gralculator/docs/UI_DESIGN.md
Grok 4f58ee9f2d ui: integrate base indicator into main wide display row + full width span
- Refactored View() display to a single wide row inside the LCD panel:
  - Leading base indicator on the left: [BIN], [HEX], etc. (flashes on successful cycle)
  - Number (or CERR) right-aligned in the remaining maximal width (spans full available inside the card)
  - LCD container uses full dispW (based on terminal width) + vertical padding for visual weight
  - CERR still flashes the number slot (base label remains visible on left)
- Keypad grid and hint now also respect the wide dispW and are centered under the display
- Updated docs/UI_DESIGN.md and ARCHITECTURE.md with the new integrated layout (replaced old separate two-row description and ASCII)
- Matches user request: main display spans full maximal width; base begins the main display row (e.g. [ [BIN] [              3465... ] ] inside the panel)

This is iterative polish on the phase 3 spike. Paper trail updated.
2026-06-06 14:43:08 +01:00

73 lines
4.8 KiB
Markdown

# 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
Sparse for MVP (no memory, no %, no bitwise, no scientific, no A-F yet).
Uses the same button-cell rendering idiom as gostations `renderPlayback` / `makeButton`:
- `lipgloss.NewStyle().Width(5).Align(lipgloss.Center).Padding(0,1).Render(label)`
- Active/pressed state uses green accent or the flashStyle (white on 63 bg, bold).
- Flash on every key action using `tea.Tick` + clearFlashMsg (140ms), exactly as tuned in gostations player.
Layout sketch (subject to refinement during spike; 4-5 columns typical):
```
7 8 9 / MOD
4 5 6 * C
1 2 3 - AC
0 . +/- + =
BASE
```
(Or tighter grouping. 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.
## 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.*