--- phase: 06-turn-by-turn-guidance-live-driving plan: 05 subsystem: web-guidance-surface tags: [guidance-cockpit, d06-maneuver-banner, d09-confirm-card, d14-trip-end, px03-close-protection, d08-haptics, committed-glyphs, token-only-css, machine-blink, tdd, copy-gates] # Dependency graph requires: - phase: 06-turn-by-turn-guidance-live-driving/02 provides: "the GuidanceState union (idle/on_route/off_route/rerouting/resuming/no_reroute) the banner's register words + calm-state swaps render, and the haptic cue vocabulary (approach/maneuver/arrive) fireHaptic dispatches" - phase: 06-turn-by-turn-guidance-live-driving/04 provides: "the engineering-A workspace the guidance card's route/telemetry model flows from (banner/card builders consume view data, never re-derive)" - phase: 05-routing-route-display/05 provides: "the builder law (route-card.ts: actions-interface-first, createElement+textContent only), the shell register classes (.card/.card-header/.card-actions/.route-telemetry/.route-stack), the 64px bottom composite, and RS5/RS9/RS10 gate shapes guidance-surface mirrors" - phase: 03-mini-app-shell-geolocation/03 provides: "the strings-module copy gate pattern (COPY1..COPY7), the machine-blink gantry precedent (cards.ts), the strip the CSS compacts under [data-guidance]" provides: - "web/src/guidance/glyphs/*.svg + web/src/guidance/glyphs.ts — the 8-glyph committed maneuver set (single source; PNGs rasterize from these exact files in plan 07) with svgHost, the shell's ONE sanctioned innerHTML site (a static import value, gated by GS6)" - "web/src/guidance/banner.ts — SEVEN builders: buildGuidanceBanner (five-slot discipline, GUIDE // NEXT|REROUTING|RESUMING|NO REROUTE, aria-expanded toggle), buildManeuverList (tap-out + NEXT/FUTURE/PAST rows), startGantryBlink/stopGantryBlink, buildGuidanceCard (progressbar + ONE btn-secondary), buildConfirmCard (the ONE btn-primary), buildTripEndCard" - "web/src/guidance/haptics.ts — fireHaptic: the three D-08 cues behind ?. chains, silent no-op without the API" - "web/src/guidance/close-protection.ts — engage/releaseCloseProtection: PX-03 layers gated BEFORE each call (isVersionAtLeast(\"7.7\") body-swipe, (\"6.2\") native-close net)" - "web/src/telegram/webapp.ts — the contract grows by OPTIONAL members only: HapticFeedback (6.1+), vertical-swipe guards (7.7+), closing-confirmation pair (6.2+), isActive (8.0+)" - "web/src/i18n/strings.ts — the 18 ShellStrings guidance keys, en + ms verbatim (COPY8 pins every value)" - "web/src/shell.css — the guidance cockpit block: banner chassis + 1px separator, CSS-only strip compaction under [data-guidance=\"active\"], list panel + row states + lamp, 4px progress bar — token vars only, zero motion/depth/radius/hex" - "web/test/guidance-surface.test.mjs — GS1..GS14: five-slot banner, list row states, gantry duty cycle, sanctioned-innerHTML + inline-copy gates, card copy + btn-primary placement, CSS token scan, capability-guard fakes" - "web/test/glyph-raw-loader.mjs — the Node-side ?raw hook (tests exercise the committed glyph strings verbatim)" affects: [06-06 guidance wiring (composes these builders with the 06-02 state machine + wires the guards), 06-07 turn-card PNGs (rasterize glyphs/*.svg), 06-08 capture legs (the guide-* classes are the capture surface)] # Tech tracking tech-stack: added: [] # zero new dependencies — Vite ?raw is a built-in import suffix; the Node loader twin is a 20-line test hook patterns: - "builder law extended to guidance: pure (locale, view, actions) => HTMLElement compositions, Node-tested through a minimal document fake (theme.test stub pattern) — no browser in the suite" - "the ONE sanctioned innerHTML site: glyphs.ts svgHost parses a STATIC committed import (GS6 pins the count: 0 in banner.ts, exactly 1 at GLYPHS[kind] in glyphs.ts)" - "registers are code-composed instrument constants: `${loc.guideRegister} // ${stateWord}` — the state words NEXT/REROUTING/RESUMING/NO REROUTE/CONFIRM/END and unit formats live in code, never the locale tables" - "distance '—' iff distanceM === null (pure view): the UI-SPEC state table decides who passes null — RESUMING legally shows projection numbers" - "capability guards: typeof wa.isVersionAtLeast === \"function\" && wa.isVersionAtLeast(\"7.7\") BEFORE the call, then ?. on the member — no-throw proven on gateless fakes and null" - "CSS-only strip compaction: [data-guidance=\"active\"] selectors touch layout only; strip.ts is source-gated to never mention data-guidance (GS11)" key-files: created: - web/src/guidance/glyphs.ts - 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/haptics.ts - web/src/guidance/close-protection.ts - web/test/guidance-surface.test.mjs - web/test/glyph-raw-loader.mjs modified: - web/src/guidance/banner.ts - web/src/i18n/strings.ts - web/src/shell.css - web/src/telegram/webapp.ts - web/test/copy-gate.test.mjs - web/test/route-surface.test.mjs - web/test/build-artifact.test.mjs key-decisions: - "Glyph geometry follows the UI-SPEC table verbatim, including the uturn machined staple with NO arrowhead and arrive as the promoted phase-5 pin (12×12 square + 3×8 tail + shaft) — the table is the binding source, not turn-glyph convention." - "The banner gantry renders ONLY in rerouting/resuming: NO REROUTE is a designed deferral, not a loading state — no blink (GS1 pins the absence)." - "Banner z-index 3 sits above the list tap-out (z 2): while the list is open the banner stays the CLOSE toggle; every other tap (map included) collapses via the full-viewport transparent layer — the UI-SPEC's tap-out law kept whole." - "Confirm + trip-end bodies are text-body-sm: the UI-SPEC typography table assigns the state-line role (degradation copy, confirm body) to body-sm; the trip-end card joins that family." - "svgHost throws nothing and parses via