feat(06-05): the 8-glyph committed maneuver set + glyphs.ts + the 18 guidance strings keys
- 8 hand-authored 32x32 SVGs per the UI-SPEC geometry table (3px stroke, square caps, orthogonal/45° only; uturn = machined staple, no arc) - glyphs.ts: GLYPH_KINDS/GLYPHS via Vite ?raw (committed files are the single source) + svgHost — the ONE sanctioned innerHTML site, a static import value - strings.ts: 18 ShellStrings keys appended in en + ms, values verbatim from the 06-UI-SPEC copywriting contract - copy-gate: COPY1 floor 40→58 + COPY8 pins all 18 guidance keys verbatim in both locales
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* glyphs.ts — the 8-glyph committed maneuver set (06-UI-SPEC "The 8-glyph set").
|
||||
* ------------------------------------------------------------------------------
|
||||
* The committed SVG files under ./glyphs/ are the SINGLE SOURCE: this module
|
||||
* imports them verbatim with Vite's `?raw` and never re-states their geometry.
|
||||
* The same files rasterize once to 256×256 PNGs for the chat turn-cards
|
||||
* (maintainer `build-glyphs.mjs`, plan 07) — one geometry, two renderings.
|
||||
* In-app the raw SVG renders inline: 32×32 on the banner's arrow plate,
|
||||
* 24×24 in the maneuver list. Strokes ride `currentColor` (signal-orange on
|
||||
* the banner plate, matte-black/outline per list row state) — the PNG build
|
||||
* injects the token literals; nothing here hardcodes a color (DSGN-01).
|
||||
*
|
||||
* svgHost is the shell's ONE sanctioned innerHTML site: the template parses
|
||||
* a STATIC import value (GLYPHS[kind], committed at build time), never a
|
||||
* name-derived or runtime string — the surface gate whitelists exactly this
|
||||
* line (guidance-surface structural case).
|
||||
*/
|
||||
import depart from "./glyphs/depart.svg?raw";
|
||||
import straight from "./glyphs/straight.svg?raw";
|
||||
import left from "./glyphs/left.svg?raw";
|
||||
import right from "./glyphs/right.svg?raw";
|
||||
import slightLeft from "./glyphs/slight-left.svg?raw";
|
||||
import slightRight from "./glyphs/slight-right.svg?raw";
|
||||
import uturn from "./glyphs/uturn.svg?raw";
|
||||
import arrive from "./glyphs/arrive.svg?raw";
|
||||
|
||||
/** The maneuver vocabulary the UI-SPEC commits (8 kinds, trip-order names —
|
||||
* RouteStep.kind maps onto these in the controller). */
|
||||
export type GlyphKind =
|
||||
| "depart"
|
||||
| "straight"
|
||||
| "left"
|
||||
| "right"
|
||||
| "slight-left"
|
||||
| "slight-right"
|
||||
| "uturn"
|
||||
| "arrive";
|
||||
|
||||
/** The 8 kinds in committed order (depart → arrive). */
|
||||
export const GLYPH_KINDS: readonly GlyphKind[] = [
|
||||
"depart",
|
||||
"straight",
|
||||
"left",
|
||||
"right",
|
||||
"slight-left",
|
||||
"slight-right",
|
||||
"uturn",
|
||||
"arrive",
|
||||
];
|
||||
|
||||
/** kind → raw SVG string of the committed file (the single source). */
|
||||
export const GLYPHS: Record<GlyphKind, string> = {
|
||||
depart,
|
||||
straight,
|
||||
left,
|
||||
right,
|
||||
"slight-left": slightLeft,
|
||||
"slight-right": slightRight,
|
||||
uturn,
|
||||
arrive,
|
||||
};
|
||||
|
||||
/** Parse a committed glyph into a live inline-SVG element. The caller sizes
|
||||
* the host (banner 32×32, list 24×24); color rides currentColor. */
|
||||
export function svgHost(kind: GlyphKind): SVGSVGElement {
|
||||
const template = document.createElement("template");
|
||||
// THE one sanctioned innerHTML site: a static import value — never a
|
||||
// name-derived or runtime string (the surface gate's exact whitelist).
|
||||
template.innerHTML = GLYPHS[kind];
|
||||
return template.content.firstElementChild as SVGSVGElement;
|
||||
}
|
||||
Reference in New Issue
Block a user