# Gralculator UI Design ## Display (Integrated Base + Wide Number Row) The main display now uses a single wide row inside the bordered LCD panel (dark background ~235, green/high-visibility foreground ~46 for the number, subtle inner NormalBorder color 238). This addresses the request for the main display area to span the full maximal possible width, with the base indicator beginning the row rather than a separate row below. - **Main display row** (spans full width of the panel): Begins with the base indicator in brackets on the left (e.g. `[BIN]`), followed by generous spacing and then the number right-aligned in the remaining wide space. The number area uses the LCD green styling and takes as much width as available inside the card (maximal possible). Vertical padding on the container gives the row "large" visual weight without needing a separate tall block. - The base uses a dim style normally; successful BASE cycles flash the base badge using the color-63 style. On CERR (non-integer), the number slot flashes "CERR" (the base label stays visible on the left). Example (ASCII approximation of rendered view, showing the integrated row): ``` +------------------------------------------------------------------+ | [BIN] [ 34654563566564356636565 ] | +------------------------------------------------------------------+ ``` (The outer +-- represent the LCD panel border + padding. The number fills the maximal remaining width and is right-aligned.) When a non-integer conversion is attempted (e.g. 3.833... + BASE / Tab), the number portion of the row temporarily renders "CERR" (with the 140ms + color 63 flash/blink style used for volume/skip/stop feedback in gostations, held longer ~600ms for the error case). After the flash, it reverts to the previous value in the unchanged base. The base label on the left does not change on error. This layout keeps the galculator spirit (base visible at a glance next to the big number) while being practical in a TUI and reducing vertical space. The entire row is one logical "large display". ## Keypad Grid (Tactile Decoration) Sparse for MVP (no memory, no %, no bitwise, no scientific, no A-F yet). The keypad is decorated to evoke a physical, tactile calculator using only the keys themselves (no enclosing background panel or outer border around the grid): - Each key is a bordered mini-panel (NormalBorder color 238) with its own background and foreground. - Base key style: dark bg 236, light fg 250, subtle border — gives a "raised key" appearance. - Specialized variants: - Number keys (0-9 .): neutral. - Operators (+ - * / =): accent color 63 for quick recognition. - Clears (C, AC): red-tinted bg 52 + fg 203 (warning/danger). - MOD: highlighted (214 orange). - BASE: prominent border color 63 + bold (stands out as the special display function). - Pressed state: the key inverts to the bright flashStyle (white fg on 63 bg, bold) for ~140ms on every action. This provides immediate "tactile click" visual feedback (modeled directly on gostations volume/skip/stop flashes). - Keys use Height(2) for chunkier, more button-like presence. - Spacing (" " gaps) between keys. The keys sit directly on the main card background (no faceplate container). Layout sketch (subject to refinement; 4-5 columns): ``` 7 8 9 / MOD 4 5 6 * C 1 2 3 - AC 0 . +/- + = BASE ``` BASE is prominent because it is the distinctive "programmer display" feature. All important actions have direct keys (digits, operators, =/Enter, Backspace, Tab for BASE, c/C, etc.). The on-screen buttons are primarily visual + mouse targets. This decoration keeps the UI lightweight while making the keypad feel far more "real" than plain text on background. Further polish (icons, better color themes, mouse hover if desired) can be added later. ## Overall Card & Polish - The entire calculator is wrapped in a **content-sized centered card**: - Outer rounded border (color 63, matching gostations label/border). - `lipgloss.Place(width, height, lipgloss.Center, lipgloss.Center, card)` - No stretching to full terminal width (important lesson from gostations player polish). - Subtle inner borders on panels where depth helps. - Minimal non-wrapping hint row at bottom of window (lipgloss bar with key badges in 63 bg, like final gostations player): e.g. "Tab:BASE q:quit etc." - Resize handling: card recenters; display and grid adapt gracefully (minimum sensible width enforced with a message if too narrow). - Consistent dark theme, green LCD accents, flash feedback. ## Rendering & State - UI owns transient state: current flashes, window size, focus hints. - Engine (`internal/calc`) is queried for `FormatForDisplay()`, `CurrentBase()`, and mutated via `CycleBase()`, digit entry, operators, etc. - View is mostly custom (JoinVertical/JoinHorizontal + lipgloss styles). Minimal use of bubbles components for MVP (possible list or table later if keypad grows). - Update dispatches keys → engine calls + flash triggers. Tab always cycles (global, like q/quit). ## Mouse (Bonus) Bubble Tea mouse support will be wired so clicking a rendered button cell triggers the same action as its key. Not required for first working spike. ## References & Constraints - Must feel like the top half of the provided galculator screenshot (large number + small mode indicator) while staying practical in 80-120 col terminals. - Reuse every hard-won gostations pattern: lipgloss.Place centering, inner 238 borders, makeButton cells, 140ms color-63 flashes, hint bar, content-sized card, tea.Tick clear messages. - Keep the TUI responsive and fun even in the minimal keypad state. See `spec.md` (root) for full scope and `ARCHITECTURE.md` for package and decision rationale. --- *Created during phase 1 skeleton, 2026.*