// Package layout provides responsive dimension calculations for the Nebara OS TUI. // All functions operate on terminal cell dimensions, not pixels. package layout // Constraints holds calculated layout values for a given terminal size. type Constraints struct { TermWidth int TermHeight int // Outer horizontal margin in cells (applied to both left and right sides). MarginH int // Outer vertical margin in cells (applied to top and bottom). MarginV int // ContentWidth is the usable width between the two horizontal margins. ContentWidth int // AppInfoLines is the number of rows reserved for appliance information // (product title + 4 metadata rows). AppInfoLines int // MessageVisible indicates whether the message row should be shown. // On very compact terminals it may be suppressed. MessageVisible bool // MenuInnerPad is the horizontal padding inside the menu border. MenuInnerPad int // FooterLines is the number of rows occupied by the footer (description + shortcuts). FooterLines int // IsMinimum flags terminals smaller than the supported minimum. IsMinimum bool } // MinWidth is the smallest terminal width the application supports gracefully. const MinWidth = 60 // MinHeight is the smallest terminal height the application supports gracefully. const MinHeight = 20 // Calculate derives layout constraints from terminal dimensions. // Reference: Figma frame 1920×1080 with 80px outer margins (4.17% of width) // and 60px vertical margins (5.56% of height). func Calculate(termW, termH int) Constraints { if termW < MinWidth || termH < MinHeight { return Constraints{ TermWidth: termW, TermHeight: termH, IsMinimum: true, } } // Horizontal margin: ~4.17% of width, min 4 cells, max 12 cells. marginH := clamp(termW*417/10000, 4, 12) // Vertical margin: ~5.56% of height, min 1 cell, max 4 cells. marginV := clamp(termH*556/10000, 1, 4) contentWidth := termW - marginH*2 // Menu inner horizontal padding (space between border char and text). menuInnerPad := 2 if termW < 100 { menuInnerPad = 1 } // Message row visibility: suppress on very compact terminals. messageVisible := termH >= 24 return Constraints{ TermWidth: termW, TermHeight: termH, MarginH: marginH, MarginV: marginV, ContentWidth: contentWidth, AppInfoLines: 6, // blank + product title + blank + 4 metadata rows MessageVisible: messageVisible, MenuInnerPad: menuInnerPad, FooterLines: 2, IsMinimum: false, } } func clamp(v, lo, hi int) int { if v < lo { return lo } if v > hi { return hi } return v }