# 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). - (A-F appear only in HEX mode — see below) - 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; dynamic based on mode): Normal mode (DEC/BIN/OCT): ``` 7 8 9 / MOD 4 5 6 * C 1 2 3 - AC 0 . +/- + = ``` HEX mode (A-F row appears only after Tab into HEX): ``` A B C D E F 7 8 9 / MOD 4 5 6 * C 1 2 3 - AC 0 . +/- + = ``` The BASE action (cycle display format) is available via the `Tab` key (documented in the hint row). There is no on-screen BASE button. A-F buttons appear dynamically only when the base indicator shows HEX. This keeps the button layout regular while making hex entry discoverable. 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 m:MOD BackSpace:C Del:AC" - 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.*