// SPDX-License-Identifier: Apache-2.0 // Canonical layout breakpoints for Chanora. // // Aligned with Material 3 adaptive layout guidance: // compact < 600dp — phone, narrow tablet // medium 600–1023 — tablet portrait, small desktop window // expanded ≥ 1024dp — desktop, tablet landscape // // 1024dp was chosen as the expanded threshold based on production app // research: Discord (member list at 1024px), Mattermost (RHS docked at // ≥ 1024px), and Rocket.Chat (contextual bar persistent at lg/1024px). /// Canonical breakpoint thresholds in logical pixels. /// /// Use these instead of hardcoded pixel values in layout decisions. /// Migrate existing `_wideBreakpoint` / `_chatMobileBreakpoint` references /// to these named constants. class ChanoraBreakpoints { ChanoraBreakpoints._(); /// Width at which the layout switches from compact to medium. /// Below this: single-column mobile layout. /// At/above: two-panel side-by-side layout. static const double medium = 600; /// Width at which the layout switches from medium to expanded. /// Below this: chat opens as a pushed route. /// At/above: three-panel layout with inline chat panel. static const double expanded = 1024; // Panel sizing constants. /// Fixed width of the left voice/control panel. static const double voicePanelWidth = 320; /// Fixed width of the right chat panel (expanded layout only). static const double chatPanelWidth = 380; /// Horizontal gap between panels. static const double panelGap = 12; /// Desktop snackbar width cap (used when width ≥ [medium]). static const double snackBarDesktopCap = 560; /// Connect form action buttons switch from row to column below this width. static const double connectActionsStackMaxWidth = 400; /// Modal bottom sheet max height as fraction of screen height. static const double modalSheetHeightFraction = 0.72; } /// Semantic layout class derived from viewport width. enum LayoutClass { /// < 600dp — single-column mobile layout. compact, /// 600–1023dp — two-panel side-by-side layout. medium, /// ≥ 1024dp — three-panel layout with inline chat. expanded, } /// Computes the current [LayoutClass] from viewport [width]. LayoutClass layoutClassFromWidth(double width) { if (width >= ChanoraBreakpoints.expanded) return LayoutClass.expanded; if (width >= ChanoraBreakpoints.medium) return LayoutClass.medium; return LayoutClass.compact; }