--- phase: 06-turn-by-turn-guidance-live-driving plan: 05 type: execute wave: 2 depends_on: [06-02] files_modified: - web/src/guidance/glyphs/depart.svg - web/src/guidance/glyphs/straight.svg - web/src/guidance/glyphs/left.svg - web/src/guidance/glyphs/right.svg - web/src/guidance/glyphs/slight-left.svg - web/src/guidance/glyphs/slight-right.svg - web/src/guidance/glyphs/uturn.svg - web/src/guidance/glyphs/arrive.svg - web/src/guidance/glyphs.ts - web/src/guidance/banner.ts - web/src/guidance/haptics.ts - web/src/guidance/close-protection.ts - web/src/telegram/webapp.ts - web/src/i18n/strings.ts - web/src/shell.css - web/test/guidance-surface.test.mjs - web/test/route-surface.test.mjs - web/test/build-artifact.test.mjs - web/test/copy-gate.test.mjs autonomous: true requirements: [GUID-01, GUID-04, PX-03] must_haves: truths: - "The maneuver banner renders distance + arrow + street per the UI-SPEC anatomy, with REROUTING/RESUMING/NO REROUTE calm states and the machine-blink gantry (GUID-01, D-04/D-06)" - "The maneuver list collapses/expands over the map with NEXT/FUTURE/PAST row states and tap-out collapse (GUID-01)" - "The guidance card shows ETA + remaining + progress bar + END TRIP — the route card evolved (D-06)" - "The abandon-route confirm card guards every guidance exit with the exact en/ms copy (D-09/PX-03)" - "Haptics fire through capability-guarded calls and no-op cleanly on old clients (GUID-04/D-08)" - "Close protection engages on guidance start and releases at trip end (disableVerticalSwipes 7.7+, closing confirmation 6.2+) (PX-03)" - "All guidance copy lives in the strings module in en + ms — never inline (the copy gates)" artifacts: - path: "web/src/guidance/glyphs.ts" provides: "the 8-glyph committed set as raw SVG (single source; PNGs rasterize from these files in plan 07)" - path: "web/src/guidance/banner.ts" provides: "banner + maneuver list + guidance card + confirm card + trip-end card builders (createElement + textContent)" - path: "web/src/guidance/haptics.ts" provides: "capability-guarded haptic dispatch (approach/maneuver/arrive)" exports: ["fireHaptic"] - path: "web/src/guidance/close-protection.ts" provides: "engage/release close protection (version-gated)" exports: ["engageCloseProtection", "releaseCloseProtection"] - path: "web/src/i18n/strings.ts" provides: "the 18 new ShellStrings keys, en + ms, exact UI-SPEC copy" key_links: - from: "web/src/guidance/banner.ts" to: "web/src/i18n/strings.ts" via: "every label via strings[locale] — zero inline copy" pattern: "strings\\[locale\\]" - from: "web/src/guidance/banner.ts" to: "web/src/guidance/glyphs.ts" via: "inline SVG from the committed glyph sources" pattern: "GLYPHS" - from: "web/src/guidance/close-protection.ts" to: "web/src/telegram/webapp.ts" via: "optional members + isVersionAtLeast guards" pattern: "isVersionAtLeast" --- The guidance cockpit surface per 06-UI-SPEC: the 8-glyph committed set, the maneuver banner + collapsible list + guidance card + abandon-confirm + trip-end builders, the close-protection and haptics capability guards, and all copy in the strings module — every element token-only, radius-0, no shadows, machine-instant state swaps. Purpose: GUID-01/PX-03's visible behavior and GUID-04's haptic channel. Builders are pure DOM composition (Node-testable, the route-card law); plan 06 wires them to the state machine. Output: glyphs + 5 builders + 2 guard modules + webapp contract members + strings keys + shell.css guidance rules + the guidance-surface suite + RS10/BA9/copy-gate bumps. @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md @$HOME/.config/opencode/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/phases/06-turn-by-turn-guidance-live-driving/06-UI-SPEC.md @.planning/phases/06-turn-by-turn-guidance-live-driving/06-CONTEXT.md @.planning/phases/06-turn-by-turn-guidance-live-driving/06-PATTERNS.md task 1: The 8-glyph committed set + glyphs.ts + strings keys web/src/guidance/glyphs/*.svg, web/src/guidance/glyphs.ts, web/src/i18n/strings.ts, web/test/copy-gate.test.mjs - .planning/phases/06-turn-by-turn-guidance-live-driving/06-UI-SPEC.md "The 8-glyph set" table (the EXACT geometry per glyph) + "Maneuver Banner" ink hierarchy - web/src/i18n/strings.ts (the ShellStrings interface + en/ms records — append, never reorder) - web/test/copy-gate.test.mjs (what it enumerates — extend in the same change) - theme/src/tokens.css (verify --color-signal-orange #EB8008 — SVGs use currentColor; PNG rasterization in plan 07 injects the literals) - glyphs.ts exports GLYPHS: Record for exactly ["depart","straight","left","right","slight-left","slight-right","uturn","arrive"], each value the raw SVG string of the committed file (?raw import — the committed SVGs are the single source) - every SVG: viewBox "0 0 32 32", stroke currentColor, stroke-width 3, square linecaps, orthogonal/45° segments only (the geometry table verbatim: depart = 4×4 filled square + vertical shaft; uturn = machined staple, no arc; arrive = shaft ending on a 12×12 filled square) - every new ShellStrings key exists in BOTH en and ms with the exact UI-SPEC values (the interface gains the 18 keys with doc comments) 1. Create the 8 SVG files in `web/src/guidance/glyphs/` per the UI-SPEC geometry table — hand-authored, 32×32 grid, `fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="square" stroke-linejoin="miter"`, filled squares as ``. Keep every segment orthogonal or 45° (the orthogonal law — the uturn staple is the proof case). 2. `web/src/guidance/glyphs.ts`: `import depart from "./glyphs/depart.svg?raw"; …` (Vite ?raw), `export type GlyphKind = "depart" | "straight" | "left" | "right" | "slight-left" | "slight-right" | "uturn" | "arrive";`, `export const GLYPH_KINDS: readonly GlyphKind[]` (the 8 in order), `export const GLYPHS: Record`, and `export function svgHost(kind: GlyphKind): SVGSVGElement` — a `