--- phase: 6 slug: turn-by-turn-guidance-live-driving status: draft shadcn_initialized: false preset: none created: 2026-10-24 --- # Phase 6 — UI Design Contract (Turn-by-Turn Guidance, Live Driving) > Visual and interaction contract for the guidance experience. Generated by gsd-ui-researcher, verified by gsd-ui-checker. > > **Source posture:** the design system is IN USE — `theme/dist/rams.css` tokens and the live shell (strip, card stack, recenter control, gantry, destination card, route card + chips) shipped in Phases 3–5 and passed their UI-SPECs + device gates. This contract specifies **extension** of that shell into the guidance cockpit: the top maneuver banner, the compacted location register, the collapsible maneuver list, the guidance card (the route card evolving), the abandon-route confirm card, trip-end messaging, the locked-follow camera, and the chat turn-card (a Telegram message, not app chrome). It invents no new token values, no new colors, no roundedness, no shadows. Binding upstream: 06-CONTEXT.md D-01..D-16 (layout, ETA deadband, haptics, PX-03/PX-01, camera, glyphs, honest copy, trip-end deletion), 05-UI-SPEC.md (the route shell this extends — ITS CONVENTIONS BIND), 03-UI-SPEC.md (strip/card/control/copy/a11y law), telemetry_rams/DESIGN.md §Navigation Heads-Up Display (the banner's component spec), DESIGN.md palette semantics (orange = navigation/primary, red = hazards/errors only). The `active_route_guidance` mockup is layout reference only; its lane matrix, incident band, speedometer deck, report/audio buttons, backdrop-blur header, and rounded puck are scrubbed residue (deferred features or existing-law violations — recorded in Fidelity Artifact). > > **Map-law restated:** the MapLibre style is never re-set; additions only (`addLayer`/`addSource`/`setData`). The route line stack from Phase 5 is guidance's route rendering — unchanged paint (orange 5px on black 9px casing). No route-line progress split this phase: the puck, the progress bar, and the camera carry progress (recorded call — less, but better). --- ## Design System | Property | Value | |----------|-------| | Tool | none — shadcn gate N/A (TypeScript + Vite, no UI framework; unchanged from Phase 3) | | Preset | not applicable | | Component library | `@araharah/theme` — `theme/dist/rams.css` (already imported via `shell.css`; nothing new to wire) | | Icon library | inline SVG — 2px uniform stroke, square linecaps, orthogonal/45° baselines (app chrome); PLUS the phase's one new committed asset: the **8-arrow maneuver glyph set** — hand-drawn 32×32 SVGs at 3px stroke (the HUD spec's weight), rendered as inline SVG in-app and rasterized once to 256×256 PNGs (maintainer `build-glyphs.mjs`, sharp) for chat turn-cards. One geometry, two renderings; the committed SVGs are the single source | | Font | self-hosted Geist + Space Grotesk via `theme.css` `@font-face` (unchanged) | | Basemap | `theme/basemap/liberty-rams.json` — Rams-constant under both Telegram themes (unchanged) | **Consumed component classes** (all pre-existing; none restyled locally): `.card`, `.card-header`, `.card-ref`, `.btn-primary`, `.btn-secondary`, `.text-headline-md`, `.text-body-md`, `.text-body-sm`, `.text-label-sm`, `.text-telemetry-num` — plus the Phase 3–5 shell classes (`.strip`, `.recenter`, `.route-stack`, `.card-stack`). New CSS for this phase (banner, list, guidance-card rows, progress bar) lives in `shell.css` and references `var(--color-*)` / `var(--spacing-*)` / `var(--type-*)` only. The machined-geometry literal list grows by exactly: banner arrow plate 48×48 + glyph 32×32, banner min-height 96px, compact strip min-height 24px, list row min-height 48px + row glyph 24×24, next-row lamp 8px, list panel max-height 480px, progress bar 4px, the 64px control-clearance composite (reused), guidance camera paddings {top 320, bottom 64, left/right 64} (map-space px) — all 4-multiples, 1px/2px rules, machined glyph geometry, and map-space paint arithmetic — the established exception classes. --- ## Shell Layout — Register Bands (guidance occupation, D-06) The Phase 3 partition is unchanged. During guidance the registers re-populate: | Band | Content during guidance | Geometry | |------|------------------------|----------| | Top register | **Maneuver banner** (new, D-06) — distance + arrow + street, matte-black chassis; the toggle for the maneuver list | Below `safe-top + space-sm`; min-height 96px; full-bleed | | Top register, compacted | **Location strip (compacted)** — same lamp + state word, telemetry cluster hidden, min-height 24px | Directly beneath the banner, separated by a 1px `chassis-subtle` rule; one continuous black chassis with the banner | | Center register | Rams basemap + position marker + Phase 5 route stack; **maneuver list panel** (only while expanded, overlays the map — no dim layer, boot-card precedent); boot/denied/pending cards unchanged when guidance is not active | Map stays the dominant surface | | Bottom register | **Guidance card** (the route card evolved — D-06); **abandon confirm card** (bottom placement — thumb-reach call, D-09); signal-lost card (existing, transient); recenter control bottom-right (returns on pan-unlock, Phase 3 semantics); attribution chip bottom-left | Card bottom offset `calc(var(--safe-bottom) + 64px)` — the Phase 5 composite, unchanged | - **Strip compaction is layout-only.** The strip's state machine, lamp colors, and word labels are byte-identical (Phase 3 table stands; `strip.ts` logic untouched). Guidance adds a `data-guidance` attribute on the shell root: padding-block drops `space-sm` → `space-xs`, min-height 32 → 24px, and the right telemetry cluster (`±M` / `FIX Ns AGO`) hides — accuracy/fix-age are not glance data at speed. The strip never hides degradation silently: staleness and denial still announce via red lamp + word, unchanged. Compacted registration is honest registration. - **No new floating controls.** The recenter control keeps its plate, notch states, and hit target exactly; during guidance its `following` state means *locked-follow* (D-10) — the notch semantics read identically to the user. - Banner placement is the strip's own band + the space above it: the chassis grows upward, the map viewport shrinks correspondingly (camera arithmetic below compensates). --- ## Spacing Scale Bound to tokens (`--spacing-*`), consumption not invention. Phase 3/5 tables stand; Phase 6 adds: | Element | Number | Token source | |---------|--------|--------------| | Banner padding | `space-sm space-md` (8/16) | tokens | | Banner min-height | 96px (register 12 + distance 32 + street 26 + 2×`space-xs` gaps + 2×`space-sm` padding ≈ 94 → 96 = 12×8) | tokens + spec geometry | | Banner arrow plate | 48×48px (32px glyph + 8px breathing per side), `surface-dark` field on the black chassis (mockup nesting precedent, token `--color-surface-dark`) | machined geometry | | Banner arrow glyph | 32×32 viewBox, 3px stroke, square linecaps | telemetry_rams HUD spec | | Compact strip min-height | 24px, padding-block `space-xs` | tokens + spec geometry | | Banner→strip separator | 1px solid `chassis-subtle` | machined rule | | List panel | card geometry: `calc(100% - 2×margin)`, max-width 320px, centered; max-height 480px (scrolls); padding `space-sm` bottom | tokens + spec geometry | | List row | min-height 48px, padding `space-sm space-md`, glyph 24×24, 1px `matte-black` row separators (dark: `inverse-on-surface`) | tokens + machined rule | | Next-row lamp | 8×8px `signal-orange` square at the row's left edge (checkbox geometry precedent) | spec geometry | | Guidance card | bottom offset 64px composite (Phase 5, reused); telemetry row + progress bar margins `space-xs`; progress bar height 4px, width = content width (inset `space-md`) | tokens + machined geometry | | Confirm card | bottom register, same 64px composite (thumb-reach — see A11y) | Phase 5 composite | | Guidance camera padding | `{ top: 320, bottom: 64, left: 64, right: 64 }` — map-space px (MapLibre padding, not CSS; 8-multiples; `T − B = 256 ≈ 0.30 × 844` reference viewport → center at 65% down-screen, D-10) | spec geometry | Exceptions: none beyond the established classes (44px hit targets via existing slop patterns; 4-multiples; map-space arithmetic). --- ## Typography The Phase 3 scale stands — zero new sizes, zero new weights. `telemetry-num` gains its second consumer (the banner distance). | Role | Token | Spec | Usage in Phase 6 | |------|-------|------|------------------| | Banner distance | `--type-telemetry-num` | 28px Space Grotesk 700 / 32px, tracking −0.03em | Distance-to-maneuver number (`250` + `M`) — the glance datum | | Banner street | `--type-headline-md` | 20px Space Grotesk 600 / 26px, tracking −0.02em | Street/designation line, uppercase (HUD spec: "Maneuver Typography: headline-md") | | Banner register | `--type-label-sm` | 10px Geist 700 / 12px, tracking +0.08em, uppercase | `GUIDE // NEXT` register line; `LIST`/`CLOSE` toggle word | | List row street | `--type-body-md` | 14px Geist 400 / 20px | Row street names | | List row distance | `--type-label-sm` | 10px Geist 700 / 12px, uppercase | Per-row remaining distance (`1.2 KM`) | | Guidance-card time | `--type-telemetry-num` | (as above) | Minutes remaining — the route card's time slot, evolved | | Guidance-card units/ETA | `--type-label-sm` | (as above) | `MIN`, `{km} KM`, `ETA 18:42` | | Card state line | `--type-body-sm` | 12px Geist 400 / 16px | Degradation copy (no-reroute), confirm-card body | | Confirm headline | `--type-headline-md` | (as above) | `Abandon route?` | | CTA labels | `--type-label-lg` (inside `.btn-*`) | 14px Space Grotesk 700 / 18px, uppercase | `END TRIP`, `YES, ABANDON`, `CONTINUE` | Unit formats are instrument constants, code-composed (Phase 3/5 precedent): distance `{n} M` under 1000 (integer), `{n.n} KM` at/over (one decimal), ETA clock 24-hour `HH:MM`, minutes `{n} MIN`. Units unchanged under `ms`. Body line-height ~1.43, heading 1.3 — token ratios verbatim. --- ## Color 60 / 30 / 10 split unchanged. **The banner's arrow joins signal-orange's reserved-for list — navigation semantics, the Phase 1 reservation's natural fulfillment.** The reserved-for list is restated and extended: | Role | Value | Usage in Phase 6 | |------|-------|------------------| | Dominant (60%) | Rams basemap grayscale + shell chrome (unchanged) | The world stays grayscale; guidance ink reads against it | | Secondary (30%) | Instrument surfaces (unchanged) | Guidance card + list panel + confirm/trip-end cards: light `soft-beige` / dark `inverse-surface` via theme slots; banner + compact strip chassis `matte-black` (Rams-constant, strip precedent) | | Accent (10%) | `signal-orange` `#EB8008` | **Reserved-for list (exact, Phase 6 — supersedes the Phase 5 list where guidance surfaces are concerned):** every Phase 5 reservation (route line, heading cone, follow notch, focus brackets, lamps, primary CTA fill, press inverts); PLUS the banner maneuver arrow (32×32, 3px stroke — HUD spec); the machine-blink gantry square in REROUTING/RESUMING states (boot-card precedent); the next-maneuver row lamp + row glyph in the list; the progress-bar fill. Orange appears at most once per band, always meaning navigation | | Destructive | `functional-red` `#ED3F1C` | **Unchanged and NOT extended:** denied/signal-lost lamps only. Abandoning a route is a deliberate user action, not an error — the confirm card renders in standard card ink; the REROUTING and no-reroute states are deferrals, never failures — no red anywhere in guidance chrome | | Operational | `olive-green` `#736B1E` | LIVE lamp only (unchanged) | **Banner ink hierarchy (chassis discipline — three inks + one accent):** register line `chassis-subtle` (≈9:1 on black), street `soft-beige` (≈11.6:1 — the HUD spec's ink), distance `pure-white` (≈17:1 — maximum glance contrast), arrow + state square `signal-orange`. The HUD spec pins the arrow orange and the street soft-beige; the distance reads white (mockup precedent: `250 M` in pure-white) so the accent stays singular per band. **Turn-card PNG colors (D-12):** stroke `signal-orange` `#EB8008` on a `matte-black` `#1A1A1A` full-bleed plate — the banner's chat sibling; hex values copied verbatim from `tokens.css` as build constants (DSGN-01 precedent; the glyph script's source SVGs carry the literals). - **Opacity 1.0 everywhere** — physical planarity law. The one sanctioned translucency remains the Phase 3 accuracy circle (data grounding). - **Past-maneuver rows** render in `outline` ink (`#897363`, an existing token) — muted history, not hidden (the list is honest about where you have been). --- ## Maneuver Banner (D-06 — the top register's guidance occupant) Full-bleed matte-black chassis under the safe inset. The whole banner is the list toggle (`