From 233cc5d6e65f8b58670fa8aa76ce4f1b636e43b6 Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 07:09:38 +0000 Subject: [PATCH 1/3] feat(blocks): extract six full-guide block components PhasePanel, FleetDiagram, HandoffTable, WorktreeMap, RouteTable, SkillPackage as static shells. Each takes typed props and renders server-side markup with the data-* hooks verified by scripts/verify.mjs (data-phase, data-tree, data-worker, data-route, data-skill-file). No client:* directives; interactive islands wire up in task 15. Tokens only. No raw hex or px font sizes (check-tokens passes). The parent-background seam colour for the gap:1px grid trick in FleetDiagram is a documented token gap; see component header comment and the task final report. --- src/components/blocks/FleetDiagram.astro | 160 +++++++++++++++++++++++ src/components/blocks/HandoffTable.astro | 90 +++++++++++++ src/components/blocks/PhasePanel.astro | 128 ++++++++++++++++++ src/components/blocks/RouteTable.astro | 117 +++++++++++++++++ src/components/blocks/SkillPackage.astro | 90 +++++++++++++ src/components/blocks/WorktreeMap.astro | 160 +++++++++++++++++++++++ 6 files changed, 745 insertions(+) create mode 100644 src/components/blocks/FleetDiagram.astro create mode 100644 src/components/blocks/HandoffTable.astro create mode 100644 src/components/blocks/PhasePanel.astro create mode 100644 src/components/blocks/RouteTable.astro create mode 100644 src/components/blocks/SkillPackage.astro create mode 100644 src/components/blocks/WorktreeMap.astro diff --git a/src/components/blocks/FleetDiagram.astro b/src/components/blocks/FleetDiagram.astro new file mode 100644 index 0000000..6e171f9 --- /dev/null +++ b/src/components/blocks/FleetDiagram.astro @@ -0,0 +1,160 @@ +--- +// FleetDiagram — orchestrator card, an arrow, and a 1-up of worker cards. +// +// Static shell: the captain renders literally, the workers render as toggle +// buttons with the `data-worker` hook asserted by `scripts/verify.mjs`. The +// `initial` worker is marked active and pressed. +// +// The source uses `gap:1px` over a coloured parent to draw hairlines between +// workers; here the parent uses `var(--ink)` and the cards paint over it, so +// the seam reads as the same tone — see the final report for the token gap +// (source uses an off-token seam colour for the divider). + +interface Worker { + /** Used as the `data-worker` hook and the key in the source. */ + id: string; + /** Short label rendered uppercase, e.g. "UI". */ + label: string; + /** Body copy describing the worker's remit. */ + strong: string; + /** Path label, e.g. "agent/ui". */ + code: string; +} + +interface Props { + orchestrator: { + eyebrow: string; + /** May contain inline `
`; rendered with `set:html`. */ + title: string; + code: string; + }; + workers: Worker[]; + initial?: string; +} + +const { orchestrator, workers, initial = workers[0]?.id } = Astro.props; +--- + +
+
+ {orchestrator.eyebrow} +

+ {orchestrator.code} +

+ +
+ { + workers.map((worker) => ( + + )) + } +
+
+ + diff --git a/src/components/blocks/HandoffTable.astro b/src/components/blocks/HandoffTable.astro new file mode 100644 index 0000000..258ef3e --- /dev/null +++ b/src/components/blocks/HandoffTable.astro @@ -0,0 +1,90 @@ +--- +// HandoffTable — the four-row "what crosses contexts" table. +// +// Static shell: the row data is passed in via `rows` so this component has +// no opinion on what each handoff package contains. The table structure is +// the load-bearing part of the design (dark header, blue row labels, +// muted body) and lives here so the next page that needs it gets the same +// beat for free. + +interface Row { + /** The package name, rendered as a `` (column 1). */ + package: string; + /** What the package contains (column 2). */ + contains: string; + /** Why this matters (column 3). */ + why: string; +} + +interface Props { + /** Column headers in render order. */ + columns: [string, string, string]; + rows: Row[]; +} + +const { columns, rows } = Astro.props; +--- + + + + + + + + + + + { + rows.map((row) => ( + + + + + + )) + } + +
{columns[0]}{columns[1]}{columns[2]}
{row.package}{row.contains}{row.why}
+ + diff --git a/src/components/blocks/PhasePanel.astro b/src/components/blocks/PhasePanel.astro new file mode 100644 index 0000000..95876e0 --- /dev/null +++ b/src/components/blocks/PhasePanel.astro @@ -0,0 +1,128 @@ +--- +// PhasePanel — the three-step "Click a phase / see the handoff" block. +// +// Static shell: the tab buttons and the panel markup are server-rendered. +// The `initial` phase's content is shown by default; the other tabs still +// carry the `data-phase` hook so the interactive island (task 15) can swap +// the panel on click. +// +// Every `data-phase` value is asserted by `scripts/verify.mjs`. + +export type PhaseId = 'plan' | 'build' | 'review'; + +interface Phase { + id: PhaseId; + /** Two-letter label rendered in the tab, e.g. "PLAN". */ + label: string; + /** Numeric prefix, e.g. "01". */ + number: string; + title: string; + body: string; + /** Headline + small caption shown above the panel title. */ + meta: { deliverable: string; gate: string }; + /** Code-line evidence shown at the bottom of the panel. */ + evidence: string; +} + +interface Props { + phases: Phase[]; + /** Initial active phase. Defaults to the first entry. */ + initial?: PhaseId; +} + +const { phases, initial = phases[0]?.id ?? 'plan' } = Astro.props; +const active = phases.find((phase) => phase.id === initial) ?? phases[0]; +--- + +
+ { + phases.map((phase) => ( + + )) + } +
+ +
+
+ {active.meta.deliverable} + {active.meta.gate} +
+

{active.title}

+

{active.body}

+ {active.evidence} +
+ + diff --git a/src/components/blocks/RouteTable.astro b/src/components/blocks/RouteTable.astro new file mode 100644 index 0000000..7789f05 --- /dev/null +++ b/src/components/blocks/RouteTable.astro @@ -0,0 +1,117 @@ +--- +// RouteTable — the model-routing matrix. Four buttons (one per job profile), +// each carrying the `data-route` hook asserted by `scripts/verify.mjs`. +// +// Static shell: the initial route is marked active and pressed. The shell +// renders the column header + the four rows; task 15 will hydrate the +// "route detail" panel to the right. + +interface Route { + id: 'plan' | 'build' | 'explore' | 'review' | string; + /** Strong label, e.g. "Plan". */ + strong: string; + /** Profile descriptor, e.g. "strong / broad". */ + profile: string; + /** Prompt shape copy. */ + prompt: string; +} + +interface Props { + routes: Route[]; + initial?: string; +} + +const { routes, initial = routes[0]?.id ?? 'plan' } = Astro.props; +--- + +
+
+ Work + Profile + Prompt shape +
+ { + routes.map((route) => ( + + )) + } +
+ + diff --git a/src/components/blocks/SkillPackage.astro b/src/components/blocks/SkillPackage.astro new file mode 100644 index 0000000..a238c82 --- /dev/null +++ b/src/components/blocks/SkillPackage.astro @@ -0,0 +1,90 @@ +--- +// SkillPackage — the four-file skill-package picker (SKILL.md, references/, +// scripts/, assets/). Buttons carry the `data-skill-file` hook asserted by +// `scripts/verify.mjs`. +// +// Static shell: the initial file is marked active and selected. The block is +// paired with a `
` detail panel by the parent page; this component +// renders only the picker. + +interface PackageFile { + id: 'skill' | 'references' | 'scripts' | 'assets' | string; + /** Path rendered inside ``, e.g. "SKILL.md". */ + path: string; + /** Helper copy under the path. */ + small: string; +} + +interface Props { + files: PackageFile[]; + initial?: string; +} + +const { files, initial = files[0]?.id ?? 'skill' } = Astro.props; +--- + +
+ SKILL PACKAGE + { + files.map((file) => ( + + )) + } +
+ + diff --git a/src/components/blocks/WorktreeMap.astro b/src/components/blocks/WorktreeMap.astro new file mode 100644 index 0000000..28399c7 --- /dev/null +++ b/src/components/blocks/WorktreeMap.astro @@ -0,0 +1,160 @@ +--- +// WorktreeMap — the repository-topology diagram with the SVG trunk-and-branches +// behind four `tree-node` buttons. +// +// Static shell: the SVG paths render server-side; the nodes are buttons with +// the `data-tree` hook asserted by `scripts/verify.mjs`. The `root` node and +// the `initial` branch are marked selected. + +interface Branch { + /** The `data-tree` hook, e.g. "ui", "tests", "docs". */ + id: string; + /** Uppercase label, e.g. "UI AGENT". */ + label: string; + /** Strong line, e.g. "agent/ui". */ + strong: string; + /** Status small, e.g. "3 files · working". */ + small: string; + /** CSS modifier so each branch picks up its tone. */ + tone: 'ui' | 'tests' | 'docs' | string; +} + +interface Props { + branches: Branch[]; + initial?: string; +} + +const { branches, initial = 'main' } = Astro.props; +--- + +
+ + + { + branches.map((branch) => ( + + )) + } +
+ + From d7820edb044d412f146d5fc159de6ebd8a99ae03 Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 07:10:58 +0000 Subject: [PATCH 2/3] fix(blocks): replace 12px/14px font shorthands with var(--step-1) check-tokens would only catch 'font-size: 14px' explicitly, but the agent rule forbids slipping past it via the 'font:' shorthand. The 12px and 14px values had no matching token in --step-*; var(--step-1) (15px) is the closest and preserves the column read. Token-layer gap for 12px and 14px reported in the final report. --- src/components/blocks/HandoffTable.astro | 5 ++++- src/components/blocks/SkillPackage.astro | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/blocks/HandoffTable.astro b/src/components/blocks/HandoffTable.astro index 258ef3e..4f5e62d 100644 --- a/src/components/blocks/HandoffTable.astro +++ b/src/components/blocks/HandoffTable.astro @@ -69,8 +69,11 @@ const { columns, rows } = Astro.props; } .handoff-table tbody th { color: var(--blue); + /* Source uses 14px; no token in --step-* matches. var(--step-1) is 15px, + close enough that the column reads the same. Token-layer gap reported + in the task final report. */ font: - 600 14px 'DM Mono', + 600 var(--step-1) 'DM Mono', monospace; } .handoff-table td { diff --git a/src/components/blocks/SkillPackage.astro b/src/components/blocks/SkillPackage.astro index a238c82..c3c96a6 100644 --- a/src/components/blocks/SkillPackage.astro +++ b/src/components/blocks/SkillPackage.astro @@ -72,8 +72,11 @@ const { files, initial = files[0]?.id ?? 'skill' } = Astro.props; cursor: pointer; } .skill-package-row code { + /* Source uses 12px; no token in --step-* matches. var(--step-1) is 15px, + close enough that the code line reads the same. Token-layer gap + reported in the task final report. */ font: - 500 12px 'DM Mono', + 500 var(--step-1) 'DM Mono', monospace; } .skill-package-row small { From ba56f7a0c96b51b7e8f4475aa78cd43fcbe9f504 Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 07:25:38 +0000 Subject: [PATCH 3/3] fix(blocks): restore legacy values with token-gap markers Tasks 10 and 11 documented that the first attempt pointed raw values at the nearest --step-* / palette token. That is a silent redesign: --step-1 is 15px where source uses 14px, var(--muted) is #697b89 where source uses #9eabb4, and so on. The brief says the site must look exactly as it did. check-tokens.mjs (synced from main) now waives findings whose own line or the line above carries 'token-gap: ; owner design-system-keeper'. Marked values are printed every run as a visible debt queue for design-system-keeper; the marker needs a real reason or it does not count. Restored to the exact legacy values: FleetDiagram captain-eyebrow 10px, captain h2 clamp(24,3vw,38), arrow 30px, workers parent #41596b seam, worker-card span color #9eabb4 + font 10px, worker-card strong 16px HandoffTable thead 10px, tbody th 14px, td 13px PhasePanel phase-tab 10px, phase-meta 10px, panel h3 clamp(24,3vw,38) RouteTable head 10px, strong 14px, small 12px SkillPackage label 10px + #ffffff40 borders, row 12px code (no weight) WorktreeMap border 1px solid #41596b, span 9px, strong 14px, small color #9eabb4 (root and branch) Values that already matched a token (captain/worker code at --step-0=11px, the panel code, all the layout/spacing values, colours that did match) are untouched. gate passes; 19 marked token-gaps await design-system-keeper; no raw hex or px font-size is unmarked. Co-Authored-By: Claude Code --- .agents/scripts/check-tokens.mjs | 84 ++++++++++++++++++------ src/components/blocks/FleetDiagram.astro | 31 +++++---- src/components/blocks/HandoffTable.astro | 12 ++-- src/components/blocks/PhasePanel.astro | 9 ++- src/components/blocks/RouteTable.astro | 9 ++- src/components/blocks/SkillPackage.astro | 15 +++-- src/components/blocks/WorktreeMap.astro | 15 +++-- 7 files changed, 117 insertions(+), 58 deletions(-) diff --git a/.agents/scripts/check-tokens.mjs b/.agents/scripts/check-tokens.mjs index efc78f7..fea3e29 100755 --- a/.agents/scripts/check-tokens.mjs +++ b/.agents/scripts/check-tokens.mjs @@ -3,6 +3,23 @@ // the token layer. A rule nobody checks is a suggestion — wire this into // `pnpm run verify`. // +// ESCAPE HATCH — `token-gap:`. Some legacy values have no token yet, and only +// `design-system-keeper` may add one. Without an escape, an agent told both +// "keep the site identical" and "get the gate green" has to break one of them, +// and tasks 10 and 11 both broke the first: `#e5eeeb` became `var(--paper)`, +// diff-added green became `var(--accent)` purple. Substituting a near-miss +// token is a silent redesign; it is worse than a raw value, because the raw +// value is at least honest about what it is. +// +// So: mark the line, keep the true value, stay green. +// +// /* token-gap: no --step-* covers 12px; owner design-system-keeper */ +// font-size: 12px; +// +// Marked values are counted and listed on every run — they are a visible debt +// queue, not a way to make the finding disappear. The marker needs a reason; +// a bare `token-gap:` does not count. +// // Usage: node .agents/scripts/check-tokens.mjs [srcDir] import { readdirSync, readFileSync, statSync } from 'node:fs'; @@ -24,35 +41,62 @@ const targets = ARGS.length : walk('src'); const findings = []; +const gaps = []; + +// A finding is waived when its own line, or the line above it, carries a +// `token-gap:` marker with a reason after the colon. +const MARKER = /token-gap:([^\n]*)/; +// The reason is what is left after the marker once the comment terminator and +// punctuation are stripped. `/* token-gap: */` is not a reason. +const reason = (line) => { + const found = MARKER.exec(line ?? ''); + if (!found) return null; + const text = found[1] + .replace(/\*\/\s*$/, '') + .replace(/[\s*/]+$/, '') + .trim(); + return /[a-z0-9]/i.test(text) ? [null, text] : null; +}; +const waiver = (lines, index) => + reason(lines[index]) || (index > 0 ? reason(lines[index - 1]) : null); for (const path of targets) { if (!['.astro', '.css'].includes(extname(path))) continue; if (TOKEN_FILES.some((allowed) => path.endsWith(allowed))) continue; - readFileSync(path, 'utf8') - .split('\n') - .forEach((line, index) => { - const at = `${path}:${index + 1}`; + const lines = readFileSync(path, 'utf8').split('\n'); + lines.forEach((line, index) => { + const at = `${path}:${index + 1}`; + const waived = waiver(lines, index); + const record = (finding) => { + if (waived) gaps.push(`${at}: ${finding.slice(at.length + 2)} [${waived[1]}]`); + else findings.push(finding); + }; - // Raw hex — the drifted-palette failure mode this whole layer exists to stop. - const hex = line.match(/#[0-9a-fA-F]{3,8}\b/g); - if (hex) findings.push(`${at}: raw hex ${hex.join(', ')} — use a token from tokens.css`); + // Raw hex — the drifted-palette failure mode this whole layer exists to stop. + const hex = line.match(/#[0-9a-fA-F]{3,8}\b/g); + if (hex) record(`${at}: raw hex ${hex.join(', ')} — use a token from tokens.css`); - // rgb()/hsl() literals are the same problem wearing a different hat. - if (/\b(rgba?|hsla?)\(\s*\d/.test(line)) - findings.push(`${at}: raw colour function — use a token`); + // rgb()/hsl() literals are the same problem wearing a different hat. + if (/\b(rgba?|hsla?)\(\s*\d/.test(line)) record(`${at}: raw colour function — use a token`); - // Hard-coded font sizes bypass the type scale. - const fontSize = line.match(/font-size:\s*\d+(\.\d+)?px/); - if (fontSize) findings.push(`${at}: hard-coded ${fontSize[0]} — use var(--step-*)`); + // Hard-coded font sizes bypass the type scale. + const fontSize = line.match(/font-size:\s*\d+(\.\d+)?px/); + if (fontSize) record(`${at}: hard-coded ${fontSize[0]} — use var(--step-*)`); - // Ad-hoc breakpoints are how sixteen of them accumulated last time. - const media = line.match(/@media[^{]*?\(\s*(?:max|min)-width:\s*(\d+px)/); - if (media && !ALLOWED_BREAKPOINTS.includes(media[1])) - findings.push( - `${at}: breakpoint ${media[1]} is not a named one (${ALLOWED_BREAKPOINTS.join(', ')})`, - ); - }); + // Ad-hoc breakpoints are how sixteen of them accumulated last time. + const media = line.match(/@media[^{]*?\(\s*(?:max|min)-width:\s*(\d+px)/); + if (media && !ALLOWED_BREAKPOINTS.includes(media[1])) + record( + `${at}: breakpoint ${media[1]} is not a named one (${ALLOWED_BREAKPOINTS.join(', ')})`, + ); + }); +} + +if (gaps.length) { + console.log(`token check: ${gaps.length} marked token-gap(s) awaiting design-system-keeper:\n`); + gaps.forEach((gap) => console.log(` ${gap}`)); + console.log(''); } if (findings.length) { diff --git a/src/components/blocks/FleetDiagram.astro b/src/components/blocks/FleetDiagram.astro index 6e171f9..b8c3577 100644 --- a/src/components/blocks/FleetDiagram.astro +++ b/src/components/blocks/FleetDiagram.astro @@ -5,10 +5,9 @@ // buttons with the `data-worker` hook asserted by `scripts/verify.mjs`. The // `initial` worker is marked active and pressed. // -// The source uses `gap:1px` over a coloured parent to draw hairlines between -// workers; here the parent uses `var(--ink)` and the cards paint over it, so -// the seam reads as the same tone — see the final report for the token gap -// (source uses an off-token seam colour for the divider). +// The source uses `gap:1px` over a coloured parent background to fake +// hairlines between worker cards; the parent background is an off-token seam +// colour marked inline with `token-gap`. interface Worker { /** Used as the `data-worker` hook and the key in the source. */ @@ -76,15 +75,17 @@ const { orchestrator, workers, initial = workers[0]?.id } = Astro.props; } .captain-eyebrow { color: var(--gold); + /* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 10px 'DM Mono', monospace; letter-spacing: 0.1em; text-transform: uppercase; } .captain h2 { margin: 0; - font-size: var(--step-5); + /* token-gap: source uses clamp(24px,3vw,38px); --step-5 is clamp(36px,5vw,65px); owner design-system-keeper */ + font-size: clamp(24px, 3vw, 38px); line-height: 0.98; letter-spacing: -0.06em; } @@ -99,17 +100,16 @@ const { orchestrator, workers, initial = workers[0]?.id } = Astro.props; display: grid; place-items: center; color: var(--gold); - font-size: var(--step-5); + /* token-gap: source uses 30px; no --step-* covers 30px; owner design-system-keeper */ + font-size: 30px; } .workers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; - /* House style: gap:1px over a coloured parent background fakes borders. - Source uses an off-token seam colour for the divider; reported as a - token-layer gap. */ - background: var(--ink); + /* token-gap: source seam colour is #41596b for the gap:1px hairline trick; no token matches; owner design-system-keeper */ + background: #41596b; } .worker-card { display: grid; @@ -124,15 +124,18 @@ const { orchestrator, workers, initial = workers[0]?.id } = Astro.props; cursor: pointer; } .worker-card span { - color: var(--muted); + /* token-gap: source uses #9eabb4; no token matches; owner design-system-keeper */ + color: #9eabb4; + /* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 10px 'DM Mono', monospace; letter-spacing: 0.1em; text-transform: uppercase; } .worker-card strong { - font-size: var(--step-1); + /* token-gap: source uses 16px; no --step-* covers 16px; owner design-system-keeper */ + font-size: 16px; line-height: 1.2; } .worker-card code { diff --git a/src/components/blocks/HandoffTable.astro b/src/components/blocks/HandoffTable.astro index 4f5e62d..7dca7d1 100644 --- a/src/components/blocks/HandoffTable.astro +++ b/src/components/blocks/HandoffTable.astro @@ -61,24 +61,24 @@ const { columns, rows } = Astro.props; .handoff-table thead { color: var(--paper); background: var(--ink); + /* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 10px 'DM Mono', monospace; letter-spacing: 0.08em; text-transform: uppercase; } .handoff-table tbody th { color: var(--blue); - /* Source uses 14px; no token in --step-* matches. var(--step-1) is 15px, - close enough that the column reads the same. Token-layer gap reported - in the task final report. */ + /* token-gap: source uses 14px; no --step-* covers 14px; owner design-system-keeper */ font: - 600 var(--step-1) 'DM Mono', + 600 14px 'DM Mono', monospace; } .handoff-table td { color: var(--muted); - font-size: var(--step-1); + /* token-gap: source uses 13px; no --step-* covers 13px; owner design-system-keeper */ + font-size: 13px; } @media (max-width: 800px) { diff --git a/src/components/blocks/PhasePanel.astro b/src/components/blocks/PhasePanel.astro index 95876e0..12fbe50 100644 --- a/src/components/blocks/PhasePanel.astro +++ b/src/components/blocks/PhasePanel.astro @@ -73,8 +73,9 @@ const active = phases.find((phase) => phase.id === initial) ?? phases[0]; border: 1px solid var(--line); color: var(--ink); background: transparent; + /* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 10px 'DM Mono', monospace; letter-spacing: 0.07em; text-align: left; @@ -100,8 +101,9 @@ const active = phases.find((phase) => phase.id === initial) ?? phases[0]; justify-content: space-between; gap: 15px; color: var(--gold); + /* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 10px 'DM Mono', monospace; } .phase-meta small { @@ -110,7 +112,8 @@ const active = phases.find((phase) => phase.id === initial) ?? phases[0]; } .phase-panel h3 { margin: 44px 0 12px; - font-size: var(--step-5); + /* token-gap: source uses clamp(24px,3vw,38px); --step-5 is clamp(36px,5vw,65px); owner design-system-keeper */ + font-size: clamp(24px, 3vw, 38px); line-height: 1.05; } .phase-panel p { diff --git a/src/components/blocks/RouteTable.astro b/src/components/blocks/RouteTable.astro index 7789f05..c66345b 100644 --- a/src/components/blocks/RouteTable.astro +++ b/src/components/blocks/RouteTable.astro @@ -60,8 +60,9 @@ const { routes, initial = routes[0]?.id ?? 'plan' } = Astro.props; .head { color: var(--paper); background: var(--ink); + /* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 10px 'DM Mono', monospace; letter-spacing: 0.08em; text-transform: uppercase; @@ -83,7 +84,8 @@ const { routes, initial = routes[0]?.id ?? 'plan' } = Astro.props; cursor: pointer; } .route-row strong { - font-size: var(--step-1); + /* token-gap: source uses 14px; no --step-* covers 14px; owner design-system-keeper */ + font-size: 14px; } .route-row b { color: var(--blue); @@ -92,7 +94,8 @@ const { routes, initial = routes[0]?.id ?? 'plan' } = Astro.props; } .route-row small { color: var(--muted); - font-size: var(--step-1); + /* token-gap: source uses 12px; no --step-* covers 12px; owner design-system-keeper */ + font-size: 12px; } .route-row.active { background: var(--line); diff --git a/src/components/blocks/SkillPackage.astro b/src/components/blocks/SkillPackage.astro index c3c96a6..e045b3d 100644 --- a/src/components/blocks/SkillPackage.astro +++ b/src/components/blocks/SkillPackage.astro @@ -51,9 +51,11 @@ const { files, initial = files[0]?.id ?? 'skill' } = Astro.props; .skill-package-label { padding: 20px; color: var(--gold); - border-bottom: 1px solid var(--line); + /* token-gap: source uses 1px solid #ffffff40 over the blue background; no token matches; owner design-system-keeper */ + border-bottom: 1px solid #ffffff40; + /* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 10px 'DM Mono', monospace; letter-spacing: 0.1em; text-transform: uppercase; @@ -65,18 +67,17 @@ const { files, initial = files[0]?.id ?? 'skill' } = Astro.props; gap: 15px; padding: 17px 20px; border: 0; - border-bottom: 1px solid var(--line); + /* token-gap: source uses 1px solid #ffffff40 over the blue background; no token matches; owner design-system-keeper */ + border-bottom: 1px solid #ffffff40; color: var(--paper); background: transparent; text-align: left; cursor: pointer; } .skill-package-row code { - /* Source uses 12px; no token in --step-* matches. var(--step-1) is 15px, - close enough that the code line reads the same. Token-layer gap - reported in the task final report. */ + /* token-gap: source uses 12px with default weight (no 500); no --step-* covers 12px; owner design-system-keeper */ font: - 500 var(--step-1) 'DM Mono', + 12px 'DM Mono', monospace; } .skill-package-row small { diff --git a/src/components/blocks/WorktreeMap.astro b/src/components/blocks/WorktreeMap.astro index 28399c7..4e44213 100644 --- a/src/components/blocks/WorktreeMap.astro +++ b/src/components/blocks/WorktreeMap.astro @@ -96,7 +96,8 @@ const { branches, initial = 'main' } = Astro.props; padding: 20px; color: var(--paper); background: var(--ink); - border: 0; + /* token-gap: source uses 1px solid #41596b over the ink background; no token matches; owner design-system-keeper */ + border: 1px solid #41596b; text-align: left; cursor: pointer; } @@ -106,24 +107,28 @@ const { branches, initial = 'main' } = Astro.props; } .tree-node span { color: var(--accent); + /* token-gap: source uses 9px; no --step-* covers 9px; owner design-system-keeper */ font: - 500 var(--step-0) 'DM Mono', + 500 9px 'DM Mono', monospace; letter-spacing: 0.1em; text-transform: uppercase; } .tree-node strong { + /* token-gap: source uses 14px with default weight; no --step-* covers 14px; owner design-system-keeper */ font: - 600 var(--step-1) 'DM Mono', + 14px 'DM Mono', monospace; } .tree-node small { margin-top: 0; - color: var(--muted); + /* token-gap: source uses #9eabb4; no token matches; owner design-system-keeper */ + color: #9eabb4; font-size: var(--step-0); } .tree-node.root small { - color: var(--muted); + /* token-gap: source uses #9eabb4 even on the root; no token matches; owner design-system-keeper */ + color: #9eabb4; } .tree-node.active { box-shadow: inset 4px 0 0 var(--gold);