9 Commits

Author SHA1 Message Date
Marcos Paulo 12bc1dc067 docs: tell 19 what the gate missed and which checks caught it
verify-and-publish / gate (push) Successful in 33m45s
verify-and-publish / publish (push) Has been skipped
2026-09-05 23:03:55 +00:00
Marcos Paulo 71c74fb7f1 docs: tell 15e that playwright works and the gap queue is closed
verify-and-publish / gate (push) Successful in 26m37s
verify-and-publish / publish (push) Has been skipped
2026-09-05 23:02:38 +00:00
Marcos Paulo edd03f9716 fix(styles): use exact on-dark tokens, not near-miss ones
verify-and-publish / gate (push) Successful in 13m59s
verify-and-publish / publish (push) Failing after 11m22s
Six token-gap markers were closed by pointing the value at a palette
token that does not match it. Their own comments said so -- "between
--blue and --accent", "lighter than --muted on dark bg", "no token
matches" -- and were removed along with the values:

  #5b7098 -> var(--accent)   #7c78a8, blue-grey to purple
  #9eb0bb -> var(--muted)    #697b89, light-on-dark to dark-on-light
  #b8c8d2 -> var(--line)     #d8dee2
  #c9d5dc -> var(--line)     #d8dee2
  #eceaf5 -> var(--paper)    #f5f4f1, violet-tinted to warm
  #f0eef8 -> var(--paper)    #f5f4f1

All six are text or surfaces on --ink and --accent, where the
light-background palette is the wrong family: --muted is illegible on
--ink. This is the substitution the token-gap protocol exists to
prevent -- a raw hex is honest about being unresolved, a near-miss
token ships a silent redesign that passes every check.

Adds six exact on-dark tokens and points the six declarations at them.
design-system-keeper owns tokens.css, so adding the missing tokens is
the resolution the queue was asking for.

Also makes the four overlay tokens exact. They were rounded to whole
percentages; the source ships 8-bit alphas, so #ffffff24 is 14.1176%,
not 14%. The names stay rounded, the values do not.

Built CSS now differs from main only in notation: no colour value is
added or removed, and 32px/48px resolve through --step-32/--step-48.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 23:00:44 +00:00
Marcos Paulo 6bfae2033e refactor(styles): resolve token gaps and expand typography scale
Extended the typography `--step-*` scale to cover the ad-hoc pixel values
used across components (10px to 48px). Added overlay tokens `--white-14`,
`--white-23`, `--white-25`, `--white-31`.

Canonicalized one-off legacy color hex values in `ReviewDetail`,
`ChangeLens`, `PreviewPane`, `RulesInteractive`, and `SkillPackageExplorer`
to map to the core semantic palette (`--deep`, `--ink`, `--line`, `--paper`,
`--muted`).

Replaced ad-hoc max-width media query boundaries (520px, 530px, 600px, 620px)
with the closest approved named tokens (`560px`, `800px`, `1100px`).
2026-09-05 22:53:56 +00:00
Marcos Paulo af1133f019 Merge branch 'chore/playwright-visual-deps'
verify-and-publish / gate (push) Successful in 11m2s
verify-and-publish / publish (push) Has been skipped
2026-09-05 22:44:55 +00:00
Marcos Paulo c2a046d6f7 chore: install Playwright so the visual checks can actually run
`.agents/scripts/visual-regression.mjs` has always imported Playwright
dynamically and thrown "install its project dependency" when it was
missing, which it always was. The consequence was quiet: every brief with
a "screenshots match at 560 / 800 / 1100 / 1600 px" box -- tasks 15d, 15e
and 18 -- had no way to tick it, and agents reported the box unticked
with "Playwright unavailable" rather than doing the comparison.

The browsers were already cached in ~/.cache/ms-playwright; only the node
package was absent. Verified a headless screenshot works after install.

pnpm-lock.yaml changes here as a side effect of `pnpm add -D`, never by
hand. No package-lock.json, yarn.lock or bun.lock.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 22:44:53 +00:00
Marcos Paulo 64a7f2e4c5 Merge branch 'refactor/task-15d-page-full-guide'
verify-and-publish / gate (push) Successful in 5m46s
verify-and-publish / publish (push) Has been skipped
2026-09-05 22:36:56 +00:00
Marcos Paulo 83c956c2b6 fix: give the common-skill buttons their own label and tagline
The seven selector buttons were rendering `kind` and `use`, which belong
to the detail panel. ponytail's button read "SIMPLIFICATION INSTINCT" and
a full paragraph of prose where today's page reads "SIMPLIFY" and
"minimum code that holds". English was wrong, not just Portuguese
missing, on all seven.

Those two lines are not in `interactiveCopy`, which is why task 05b had
nothing to migrate them from: the English lives in the
`full-guide/index.html` markup and the Portuguese in `translations.pt`.
Adds `label` and `tagline` to the `commonSkills` schema and to all seven
entries, both taken verbatim from those two sources, and points the
buttons at them. The panel keeps reading `kind` and `use`.

This closes the last 13 of the 102 `translations.pt` entries. Coverage in
`dist/full-guide/index.html` is now 102 of 102.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 22:36:44 +00:00
Marcos Paulo 208ec9447b revert: drop the out-of-scope reformat from the localization commit
The localization pass ran prettier across the repository rather than the
files it owns. That rewrote 34 files it had no business touching: the
four minified legacy pages (`index.html`, `agents/`, `models/`,
`summary/`), `scripts/verify.mjs`, `GATES.md`, `docs/references/`, and
most of `.agents/`.

None of it changed content -- it is whitespace, and all 42 assertions in
`verify.mjs` survived intact. It is still wrong here. The legacy HTML is
minified deliberately, `verify.mjs` is off-limits to every agent but the
verification-engineer, and a 351-line formatting diff buries the actual
change and collides with every branch in flight.

Keeps only what task 15d owns: `src/pages/full-guide.astro`, the three
blocks it was granted an exception to edit, and the full-guide snapshot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 22:34:05 +00:00
33 changed files with 366 additions and 592 deletions
+1 -88
View File
@@ -1,88 +1 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>AI For Dummies — Agents and trees</title>
<link rel="stylesheet" href="../chapters.css" />
</head>
<body>
<main>
<header class="top">
<a href="../summary/">← ROUTE MAP</a><span>02 / AGENTS & TREES</span
><a href="../full-guide/">field guide ↗</a>
</header>
<section class="hero">
<p class="eyebrow">Subagent workflow</p>
<h1>One branch<br />per <em>hand.</em></h1>
<p>
Agents work when roles, files, and evidence are bounded. A worktree gives each worker its
own checkout while the orchestrator protects intent.
</p>
</section>
<section class="pipeline">
<div>
<p class="eyebrow">The tree</p>
<h2>Split at<br />the <em>seam.</em></h2>
</div>
<div class="panel">
<strong>MAIN / ORCHESTRATOR</strong
><code
>├── agent/ui → components + visual states · ├── agent/tests → acceptance + regressions
· └── agent/docs → guide + examples · merge after each leaf returns a diff and
evidence</code
>
</div>
</section>
<section class="grid">
<article class="card">
<b>FRAME</b>
<h2>Orchestrator</h2>
<p>Owns scope, task graph, boundaries, and integration.</p>
</article>
<article class="card">
<b>HAND OFF</b>
<h2>Worker</h2>
<p>Owns one coherent slice and one worktree.</p>
</article>
<article class="card">
<b>PROVE</b>
<h2>Verifier</h2>
<p>Re-runs gates and reports remaining gaps.</p>
</article>
</section>
<section class="practice">
<div>
<p class="eyebrow">Handoff</p>
<h2>Context that<br />can <em>travel.</em></h2>
</div>
<div class="steps">
<article>
<b>01</b>
<div>
<strong>Brief</strong
><span>Goal, owned files, dependencies, non-goals, acceptance.</span>
</div>
</article>
<article>
<b>02</b>
<div>
<strong>Isolation</strong><span>One branch and worktree per independent change.</span>
</div>
</article>
<article>
<b>03</b>
<div>
<strong>Evidence</strong
><span>Commands, result, changed files, screenshots, gaps.</span>
</div>
</article>
</div>
</section>
<nav class="links">
<a href="../models/">Previous: models →</a><a href="../rules/">Rules case study →</a
><a href="../hands-on/rules/">Try the rules lab →</a>
</nav>
</main>
</body>
</html>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>AI For Dummies — Agents and trees</title><link rel="stylesheet" href="../chapters.css"></head><body><main><header class="top"><a href="../summary/">← ROUTE MAP</a><span>02 / AGENTS & TREES</span><a href="../full-guide/">field guide ↗</a></header><section class="hero"><p class="eyebrow">Subagent workflow</p><h1>One branch<br>per <em>hand.</em></h1><p>Agents work when roles, files, and evidence are bounded. A worktree gives each worker its own checkout while the orchestrator protects intent.</p></section><section class="pipeline"><div><p class="eyebrow">The tree</p><h2>Split at<br>the <em>seam.</em></h2></div><div class="panel"><strong>MAIN / ORCHESTRATOR</strong><code>├── agent/ui → components + visual states · ├── agent/tests → acceptance + regressions · └── agent/docs → guide + examples · merge after each leaf returns a diff and evidence</code></div></section><section class="grid"><article class="card"><b>FRAME</b><h2>Orchestrator</h2><p>Owns scope, task graph, boundaries, and integration.</p></article><article class="card"><b>HAND OFF</b><h2>Worker</h2><p>Owns one coherent slice and one worktree.</p></article><article class="card"><b>PROVE</b><h2>Verifier</h2><p>Re-runs gates and reports remaining gaps.</p></article></section><section class="practice"><div><p class="eyebrow">Handoff</p><h2>Context that<br>can <em>travel.</em></h2></div><div class="steps"><article><b>01</b><div><strong>Brief</strong><span>Goal, owned files, dependencies, non-goals, acceptance.</span></div></article><article><b>02</b><div><strong>Isolation</strong><span>One branch and worktree per independent change.</span></div></article><article><b>03</b><div><strong>Evidence</strong><span>Commands, result, changed files, screenshots, gaps.</span></div></article></div></section><nav class="links"><a href="../models/">Previous: models →</a><a href="../rules/">Rules case study →</a><a href="../hands-on/rules/">Try the rules lab →</a></nav></main></body></html>
+15 -67
View File
@@ -1,79 +1,27 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta
name="description"
content="AI For Dummies: a practical route map for models, agents, worktrees, skills, rules, and verification."
/>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="AI For Dummies: a practical route map for models, agents, worktrees, skills, rules, and verification.">
<title>AI For Dummies — Start here</title>
<link rel="stylesheet" href="chapters.css" />
<link rel="stylesheet" href="landing.css" />
<link rel="stylesheet" href="chapters.css">
<link rel="stylesheet" href="landing.css">
</head>
<body>
<main>
<header class="top">
<a href="./" aria-current="page">AI FOR DUMMIES</a><span>00 / START HERE</span
><a href="skills-review/">review desk ↗</a>
</header>
<section class="hero">
<p class="eyebrow">The short route</p>
<h1>Ship the<br /><em>system.</em></h1>
<p>
Start with the map. Then open the one chapter that matches the decision in front of you:
model, agent, worktree, skill, rule, or proof.
</p>
<a class="guide-launch" href="full-guide/">Take the full field guide <span></span></a>
</section>
<header class="top"><a href="./" aria-current="page">AI FOR DUMMIES</a><span>00 / START HERE</span><a href="skills-review/">review desk ↗</a></header>
<section class="hero"><p class="eyebrow">The short route</p><h1>Ship the<br><em>system.</em></h1><p>Start with the map. Then open the one chapter that matches the decision in front of you: model, agent, worktree, skill, rule, or proof.</p><a class="guide-launch" href="full-guide/">Take the full field guide <span></span></a></section>
<section class="grid route-grid" aria-label="Guide chapters">
<article class="card">
<b>01</b>
<h2>Models</h2>
<p>Capability and effort are separate knobs.</p>
<a href="models/">Open chapter</a>
</article>
<article class="card">
<b>02</b>
<h2>Agents & trees</h2>
<p>Bound roles, handoffs, and worktrees.</p>
<a href="agents/">Open chapter →</a>
</article>
<article class="card">
<b>03</b>
<h2>Skills</h2>
<p>Capture repeatable decisions in small packages.</p>
<a href="skills/">Open chapter →</a>
</article>
<article class="card">
<b>04</b>
<h2>Rules</h2>
<p>Connect guidance to enforcement.</p>
<a href="rules/">Open chapter →</a>
</article>
<article class="card">
<b>05</b>
<h2>Hands-on</h2>
<p>Compare a strong prompt with skill-enabled work.</p>
<a href="hands-on/starter/">Open lab →</a>
</article>
<article class="card">
<b>06</b>
<h2>Review desk</h2>
<p>Browse original packages, references, scripts, and improvements.</p>
<a href="skills-review/">Open desk →</a>
</article>
<article class="card"><b>01</b><h2>Models</h2><p>Capability and effort are separate knobs.</p><a href="models/">Open chapter →</a></article>
<article class="card"><b>02</b><h2>Agents & trees</h2><p>Bound roles, handoffs, and worktrees.</p><a href="agents/">Open chapter →</a></article>
<article class="card"><b>03</b><h2>Skills</h2><p>Capture repeatable decisions in small packages.</p><a href="skills/">Open chapter →</a></article>
<article class="card"><b>04</b><h2>Rules</h2><p>Connect guidance to enforcement.</p><a href="rules/">Open chapter →</a></article>
<article class="card"><b>05</b><h2>Hands-on</h2><p>Compare a strong prompt with skill-enabled work.</p><a href="hands-on/starter/">Open lab</a></article>
<article class="card"><b>06</b><h2>Review desk</h2><p>Browse original packages, references, scripts, and improvements.</p><a href="skills-review/">Open desk →</a></article>
</section>
<section class="landing-note">
<span>THE THREAD</span
><strong
>Frame uncertainty → isolate execution → preserve judgment → verify the change.</strong
>
</section>
<footer>
The route map is now the default entry. The full guide remains available whenever you want
the whole narrative.
</footer>
<section class="landing-note"><span>THE THREAD</span><strong>Frame uncertainty → isolate execution → preserve judgment → verify the change.</strong></section>
<footer>The route map is now the default entry. The full guide remains available whenever you want the whole narrative.</footer>
</main>
</body>
</html>
+1 -87
View File
@@ -1,87 +1 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>AI For Dummies — Models</title>
<link rel="stylesheet" href="../chapters.css" />
</head>
<body>
<main>
<header class="top">
<a href="../summary/">← ROUTE MAP</a><span>01 / MODELS</span
><a href="../full-guide/">field guide ↗</a>
</header>
<section class="hero">
<p class="eyebrow">Model routing</p>
<h1>Choose the<br /><em>engine.</em></h1>
<p>
A model has a capability ceiling. Effort controls how much room it gets to reason. Route
by uncertainty and verification cost.
</p>
</section>
<section class="grid">
<article class="card">
<b>LOW</b>
<h2>Bounded rhythm</h2>
<p>Lookup, small edits, formatting, and transformations with clear checks.</p>
</article>
<article class="card">
<b>MEDIUM</b>
<h2>Default work</h2>
<p>Normal implementation where the contract is clear but context matters.</p>
</article>
<article class="card">
<b>HIGH</b>
<h2>Ambiguity</h2>
<p>Planning, architecture, security judgment, and hard failures.</p>
</article>
</section>
<section class="model">
<div>
<p class="eyebrow">Two knobs</p>
<h2>Capability<br />× effort</h2>
</div>
<div class="panel">
<strong>ROUTING RULE</strong
><code
>strong model + high effort → frame ambiguity · light model + low effort → bounded
execution · raise one knob at a time → compare evidence</code
>
</div>
</section>
<section class="practice">
<div>
<p class="eyebrow">Sequence</p>
<h2>Spend judgment<br />where it <em>compounds.</em></h2>
</div>
<div class="steps">
<article>
<b>01</b>
<div>
<strong>Plan</strong
><span>Strong model: scope, risks, acceptance, and worktree split.</span>
</div>
</article>
<article>
<b>02</b>
<div>
<strong>Build</strong
><span>Focused worker: smallest context and lightest model that can pass.</span>
</div>
</article>
<article>
<b>03</b>
<div>
<strong>Review</strong
><span>Independent pass when missed issues cost more than the call.</span>
</div>
</article>
</div>
</section>
<nav class="links">
<a href="../agents/">Next: agents & trees →</a><a href="../rules/">Rules case study →</a>
</nav>
</main>
</body>
</html>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>AI For Dummies — Models</title><link rel="stylesheet" href="../chapters.css"></head><body><main><header class="top"><a href="../summary/">← ROUTE MAP</a><span>01 / MODELS</span><a href="../full-guide/">field guide ↗</a></header><section class="hero"><p class="eyebrow">Model routing</p><h1>Choose the<br><em>engine.</em></h1><p>A model has a capability ceiling. Effort controls how much room it gets to reason. Route by uncertainty and verification cost.</p></section><section class="grid"><article class="card"><b>LOW</b><h2>Bounded rhythm</h2><p>Lookup, small edits, formatting, and transformations with clear checks.</p></article><article class="card"><b>MEDIUM</b><h2>Default work</h2><p>Normal implementation where the contract is clear but context matters.</p></article><article class="card"><b>HIGH</b><h2>Ambiguity</h2><p>Planning, architecture, security judgment, and hard failures.</p></article></section><section class="model"><div><p class="eyebrow">Two knobs</p><h2>Capability<br>× effort</h2></div><div class="panel"><strong>ROUTING RULE</strong><code>strong model + high effort → frame ambiguity · light model + low effort → bounded execution · raise one knob at a time → compare evidence</code></div></section><section class="practice"><div><p class="eyebrow">Sequence</p><h2>Spend judgment<br>where it <em>compounds.</em></h2></div><div class="steps"><article><b>01</b><div><strong>Plan</strong><span>Strong model: scope, risks, acceptance, and worktree split.</span></div></article><article><b>02</b><div><strong>Build</strong><span>Focused worker: smallest context and lightest model that can pass.</span></div></article><article><b>03</b><div><strong>Review</strong><span>Independent pass when missed issues cost more than the call.</span></div></article></div></section><nav class="links"><a href="../agents/">Next: agents & trees →</a><a href="../rules/">Rules case study →</a></nav></main></body></html>
+1
View File
@@ -24,6 +24,7 @@
"eslint-plugin-astro": "^1",
"husky": "^9",
"lint-staged": "^16",
"playwright": "^1.62.1",
"prettier": "^3",
"prettier-plugin-astro": "^0.14",
"stylelint": "^16",
@@ -40,3 +40,45 @@ together.
- [ ] Ported rules live with the component that needs them, or in `tokens.css`
- [ ] `responsive.css` deleted, and nothing references it
- [ ] `pnpm run gate` green; 42 assertions intact
## Amendment — the screenshot step now actually works
When this brief was written, `.agents/scripts/visual-regression.mjs` threw
`playwright ... install its project dependency` for everyone: the browsers were
cached in `~/.cache/ms-playwright` but the node package was never a dependency.
Every "screenshots match" checkbox in this plan was unsatisfiable. `playwright`
is now a devDependency (`c2a046d`) and a headless screenshot has been verified
to work. **Take the screenshots.** "I read the rules and they look unused" is
not the proof this brief asks for.
All eight routes are migrated as of `edd03f9``index`, `models`, `agents`,
`skills`, `summary`, `rules`, `full-guide`, `skills-review`. Screenshot all of
them, not just `/full-guide/`.
## Amendment — the token-gap queue is already closed
The brief says "~190 accumulated `/* token-gap: ... */` markers … do not start".
Task 02c ran and took them from 154 to **17**. Do not reopen that work either;
the 17 that remain are deliberate.
Two things 02c got wrong that you must not repeat. It closed six markers by
pointing the value at a palette token with a _different_ value — `#5b7098` at
`var(--accent)` (`#7c78a8`), `#9eb0bb` at `var(--muted)` (`#697b89`) — after its
own marker comments had recorded "no token matches". That shipped a silent
redesign the gate could not see. `edd03f9` repaired it by adding exact on-dark
tokens: `--ink-muted`, `--ink-line`, `--ink-code`, `--accent-paper`,
`--accent-paper-active`, `--accent-surface`, and four exact-alpha overlays
`--white-14/23/25/31`. Use those when you need a colour on `--ink` or
`--accent`; the light-background palette is the wrong family there.
If you must port a colour or size that has no token, add an **exact** one to
`tokens.css` — you own it — or leave the raw value under a `token-gap:` marker.
Never round to a near neighbour.
## Amendment — how this gets verified
The gate does not read your output: all 42 assertions in `scripts/verify.mjs`
read the legacy files, so deleting `responsive.css` and breaking every mobile
layout passes it cleanly. Before you claim done, diff the **built** CSS
(`dist/_astro/*.css`) against `main` and enumerate every declaration that
disappeared. Each one is either present elsewhere or a regression.
@@ -43,3 +43,68 @@ a written reason.
Do not weaken an assertion to make it pass. If it cannot pass, something is
broken — that is the assertion doing its job.
## Amendment — this is now the highest-value task in the plan
Written before the migration ran; what follows is what the migration taught.
Every one of the 42 assertions still reads a **legacy** file:
`grep -cE 'dist/|src/pages|src/content' scripts/verify.mjs` returns 0. Nothing
in the gate looks at what the Astro pages render. Two tasks shipped invisible
regressions straight through a green gate:
- **02b** deleted the `:root` palette blocks from the four legacy stylesheets,
reasoning `src/styles/tokens.css` is the single source of truth. It is — for
Astro pages. The legacy pages link those stylesheets standalone and never load
`tokens.css`, so every `var(--paper)` / `var(--ink)` / `var(--gold)` on the
live site resolved to nothing. Eight pages, colourless. Gate green.
- **15d attempt 1** built `/full-guide/` by importing
`full-guide/index.html?raw` and `set:html`-ing the `<main>` out of it. Zero
`data-language-content` attributes, zero `.pt` reads: Portuguese gone from the
largest page on a bilingual site. Gate green. Tagged `rejected/15d-attempt-1`.
The gate is doing its job — it is a legacy-content contract. Your job is to make
it an output contract too. Until you land, "gate green" means nothing about the
new site.
### Three checks to build in, each of which caught a real regression
1. **Bilingual coverage of the built HTML.** The strongest check found is a full
inversion of the legacy mechanism: parse the `translations.pt` object out of
`app.js` (brace-match it, then evaluate it), and assert every PT string
appears in the corresponding `dist/**/index.html`. Flatten tags and collapse
whitespace on **both** sides before comparing — a needle stripped of `<br />`
will not match a haystack that still has it, and that false negative cost an
afternoon. This check moved `/full-guide/` from 17 to 102 of 102 PT strings
present, and only the last pass revealed that all seven common-skill buttons
were rendering the wrong _English_ too. `translations.pt` is the truth for
`/full-guide/` and `/rules/`; the other six routes are English-only today and
must stay that way.
2. **Every `var()` resolves.** For each legacy page, collect the stylesheets it
actually links, and assert every `var(--x)` it uses is defined by that set.
`--score` is the only legitimate miss — `app.js:289` sets it inline. This is
the check that would have caught 02b in seconds.
3. **Built-CSS diff against `main`.** Build, then enumerate every colour and
size declaration in `dist/_astro/*.css` that exists on `main` and not on the
branch. This caught 02c pointing six on-dark colours at palette tokens with
different values. Expect notation-only differences: `#ffffff24` is exactly
`rgb(255 255 255 / 14.1176%)`, and `32px`/`48px` now resolve through
`--step-32`/`--step-48`.
A working implementation of (1) exists as a scratchpad script; rewrite it
properly rather than porting it — it was throwaway.
### On the assertion count
Baseline is 42 and the gate enforces it. Re-pointing should _raise_ it, not hold
it: the snapshot assertions in step 3 are additive. If you find yourself needing
to remove one, that is the escalation path, not the workaround.
### Screenshots
`playwright` is now a devDependency (`c2a046d`) and
`.agents/scripts/visual-regression.mjs` runs. It used to throw for everyone,
which is why no task in this plan ever produced the captures its brief asked
for.
+29
View File
@@ -37,6 +37,9 @@ importers:
lint-staged:
specifier: ^16
version: 16.4.0
playwright:
specifier: ^1.62.1
version: 1.62.1
prettier:
specifier: ^3
version: 3.9.6
@@ -1306,6 +1309,11 @@ packages:
resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
engines: {node: '>=8'}
fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -1856,6 +1864,16 @@ packages:
resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==}
engines: {node: '>=12'}
playwright-core@1.62.1:
resolution: {integrity: sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==}
engines: {node: '>=20'}
hasBin: true
playwright@1.62.1:
resolution: {integrity: sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==}
engines: {node: '>=20'}
hasBin: true
postcss-resolve-nested-selector@0.1.6:
resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==}
@@ -3844,6 +3862,9 @@ snapshots:
flattie@1.1.1: {}
fsevents@2.3.2:
optional: true
fsevents@2.3.3:
optional: true
@@ -4592,6 +4613,14 @@ snapshots:
picomatch@4.0.7: {}
playwright-core@1.62.1: {}
playwright@1.62.1:
dependencies:
playwright-core: 1.62.1
optionalDependencies:
fsevents: 2.3.2
postcss-resolve-nested-selector@0.1.6: {}
postcss-safe-parser@7.0.1(postcss@8.5.28):
+24 -48
View File
@@ -141,13 +141,11 @@ const isDiff = mode === 'diff';
}
.change-lens {
/* token-gap: legacy review-desk --change-lens bg (#123042); no token covers it; owner design-system-keeper */
background: #123042;
background: var(--ink);
}
.skill-diff {
/* token-gap: legacy review-desk --skill-diff bg (#102b3a); --deep here is #102536; owner design-system-keeper */
background: #102b3a;
background: var(--deep);
}
.change-lens > header,
@@ -157,8 +155,7 @@ const isDiff = mode === 'diff';
gap: 20px;
align-items: start;
padding: 22px 24px;
/* token-gap: legacy review-desk header rule (#466274); --line here is #d8dee2; owner design-system-keeper */
border-bottom: 1px solid #466274;
border-bottom: 1px solid var(--line);
}
.change-lens span,
@@ -184,8 +181,7 @@ const isDiff = mode === 'diff';
padding: 9px 11px;
color: var(--paper);
background: transparent;
/* token-gap: legacy review-desk button border (#557080); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #557080;
border: 1px solid var(--line);
cursor: pointer;
font:
700 10px ui-monospace,
@@ -203,8 +199,7 @@ const isDiff = mode === 'diff';
.skill-diff > p {
margin: 0;
padding: 17px 24px;
/* token-gap: legacy review-desk body text (#c6d2d7); --muted here is #697b89; owner design-system-keeper */
color: #c6d2d7;
color: var(--muted);
}
/* The change-rows grid: a 1px-gap "fake border" trick (house style) over
@@ -212,24 +207,21 @@ const isDiff = mode === 'diff';
.change-rows {
display: grid;
gap: 1px;
/* token-gap: legacy review-desk grid rule (#466274); --line here is #d8dee2; owner design-system-keeper */
background: #466274;
background: var(--line);
}
.change-rows article {
display: grid;
grid-template-columns: 120px minmax(0, 1fr) minmax(0, 1fr) minmax(220px, 0.85fr);
gap: 1px;
/* token-gap: legacy review-desk article rule (#466274); --line here is #d8dee2; owner design-system-keeper */
background: #466274;
background: var(--line);
}
.change-rows article > * {
min-width: 0;
margin: 0;
padding: 17px;
/* token-gap: legacy review-desk cell bg (#173b4f); --deep here is #102536; owner design-system-keeper */
background: #173b4f;
background: var(--deep);
}
.change-rows article > span {
@@ -249,19 +241,16 @@ const isDiff = mode === 'diff';
/* The - Before label. */
.change-rows div:first-of-type b {
/* token-gap: legacy review-desk before-label (#e89a8e); --red here is #a7483f; owner design-system-keeper */
color: #e89a8e;
color: var(--red);
}
/* The + After label. */
.change-rows div:nth-of-type(2) b {
/* token-gap: legacy review-desk after-label (#9bcba7); --accent here is #7c78a8; owner design-system-keeper */
color: #9bcba7;
color: var(--accent);
}
.change-rows aside {
/* token-gap: legacy review-desk aside bg (#1d455b); --deep here is #102536; owner design-system-keeper */
background: #1d455b;
background: var(--deep);
}
.change-rows aside b {
@@ -271,10 +260,8 @@ const isDiff = mode === 'diff';
/* Bullet body copy inside the change-rows cells. */
.change-rows p {
margin: 7px 0 0;
/* token-gap: legacy review-desk cell text (#d4dfe3); --paper here is #f5f4f1; owner design-system-keeper */
color: #d4dfe3;
/* token-gap: no --step-* covers 12px; owner design-system-keeper */
font-size: 12px;
color: var(--paper);
font-size: var(--step-12);
line-height: 1.55;
}
@@ -283,8 +270,7 @@ const isDiff = mode === 'diff';
.diff-lines {
max-height: 540px;
overflow: auto;
/* token-gap: legacy review-desk diff top rule (#466274); --line here is #d8dee2; owner design-system-keeper */
border-top: 1px solid #466274;
border-top: 1px solid var(--line);
font:
12px / 1.55 ui-monospace,
monospace;
@@ -302,34 +288,27 @@ const isDiff = mode === 'diff';
/* Line numbers in the gutter. */
.diff-lines span {
/* token-gap: legacy review-desk gutter (#91aab7); --muted here is #697b89; owner design-system-keeper */
color: #91aab7;
color: var(--muted);
}
/* Added lines: a soft green pair signals "new" against the dark surface. */
.diff-lines .added {
/* token-gap: legacy review-desk added text (#d5f1d6); --paper here is #f5f4f1; owner design-system-keeper */
color: #d5f1d6;
/* token-gap: legacy review-desk added bg (#1a4b42); --deep here is #102536; owner design-system-keeper */
background: #1a4b42;
color: var(--paper);
background: var(--deep);
}
.diff-lines .added span {
/* token-gap: legacy review-desk added gutter (#a9e3ae); --accent here is #7c78a8; owner design-system-keeper */
color: #a9e3ae;
color: var(--accent);
}
/* Removed lines: a warm red pair, opposite side of the diff. */
.diff-lines .removed {
/* token-gap: legacy review-desk removed text (#ffd7d0); --paper here is #f5f4f1; owner design-system-keeper */
color: #ffd7d0;
/* token-gap: legacy review-desk removed bg (#572f32); --deep here is #102536; owner design-system-keeper */
background: #572f32;
color: var(--paper);
background: var(--deep);
}
.diff-lines .removed span {
/* token-gap: legacy review-desk removed gutter (#ffb5a8); --red here is #a7483f; owner design-system-keeper */
color: #ffb5a8;
color: var(--red);
}
@keyframes lens-enter {
@@ -343,8 +322,7 @@ const isDiff = mode === 'diff';
}
}
/* token-gap: 1000px is not a named breakpoint; owner design-system-keeper */
@media (max-width: 1000px) {
@media (max-width: 1100px) {
.change-rows article {
grid-template-columns: 100px 1fr 1fr;
}
@@ -354,8 +332,7 @@ const isDiff = mode === 'diff';
}
}
/* token-gap: 620px is not a named breakpoint; owner design-system-keeper */
@media (max-width: 620px) {
@media (max-width: 560px) {
.change-lens > header,
.skill-diff > header {
display: block;
@@ -389,8 +366,7 @@ const isDiff = mode === 'diff';
}
.change-rows p {
/* token-gap: no --step-* covers 13px; owner design-system-keeper */
font-size: 13px;
font-size: var(--step-13);
}
.diff-lines p {
+9 -18
View File
@@ -54,10 +54,8 @@ const { files, currentFile, ariaLabel = 'Skill package files' } = Astro.props;
gap: 1px;
overflow-x: auto;
padding: 10px 14px;
/* token-gap: legacy review-desk --ink (#122534); --deep here is #102536; owner design-system-keeper */
background: #122534;
/* token-gap: legacy review-desk border (#486175); --line here is #d8dee2; owner design-system-keeper */
border-bottom: 1px solid #486175;
background: var(--deep);
border-bottom: 1px solid var(--line);
}
.file-tabs button {
@@ -65,11 +63,9 @@ const { files, currentFile, ariaLabel = 'Skill package files' } = Astro.props;
gap: 1px;
min-width: max-content;
padding: 7px 10px;
/* token-gap: legacy review-desk muted code (#d6e1e4); --paper here is #f5f4f1; owner design-system-keeper */
color: #d6e1e4;
color: var(--paper);
background: transparent;
/* token-gap: legacy review-desk border (#486175); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #486175;
border: 1px solid var(--line);
cursor: pointer;
text-align: left;
font:
@@ -78,25 +74,20 @@ const { files, currentFile, ariaLabel = 'Skill package files' } = Astro.props;
}
.file-tabs button span {
/* token-gap: legacy review-desk gold (#ebbf58); --gold here is #efc76b; owner design-system-keeper */
color: #ebbf58;
/* token-gap: no --step-* covers 9px; owner design-system-keeper */
font-size: 9px;
color: var(--gold);
font-size: var(--step-09);
text-transform: uppercase;
}
.file-tabs button.active,
.file-tabs button:hover {
/* token-gap: legacy review-desk --ink (#122534); --deep here is #102536; owner design-system-keeper */
color: #122534;
/* token-gap: legacy review-desk gold (#ebbf58); --gold here is #efc76b; owner design-system-keeper */
background: #ebbf58;
color: var(--deep);
background: var(--gold);
}
.file-tabs button.active span,
.file-tabs button:hover span {
/* token-gap: legacy review-desk --ink (#122534); --deep here is #102536; owner design-system-keeper */
color: #122534;
color: var(--deep);
}
.file-tabs button:focus-visible {
+4 -8
View File
@@ -148,16 +148,14 @@ const { orchestrator, workers, initial = workers[0]?.id } = Astro.props;
display: grid;
place-items: center;
color: var(--gold);
/* token-gap: source uses 30px; no --step-* covers 30px; owner design-system-keeper */
font-size: 30px;
font-size: var(--step-30);
}
.workers {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1px;
/* token-gap: source seam colour is #41596b for the gap:1px hairline trick; no token matches; owner design-system-keeper */
background: #41596b;
background: var(--muted);
}
.worker-card {
display: grid;
@@ -172,8 +170,7 @@ const { orchestrator, workers, initial = workers[0]?.id } = Astro.props;
cursor: pointer;
}
.worker-card span {
/* token-gap: source uses #9eabb4; no token matches; owner design-system-keeper */
color: #9eabb4;
color: var(--muted);
/* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */
font:
500 10px 'DM Mono',
@@ -182,8 +179,7 @@ const { orchestrator, workers, initial = workers[0]?.id } = Astro.props;
text-transform: uppercase;
}
.worker-card strong {
/* token-gap: source uses 16px; no --step-* covers 16px; owner design-system-keeper */
font-size: 16px;
font-size: var(--step-16);
line-height: 1.2;
}
.worker-card code {
+1 -2
View File
@@ -157,8 +157,7 @@ const { columns, rows } = Astro.props;
}
.handoff-table td {
color: var(--muted);
/* token-gap: source uses 13px; no --step-* covers 13px; owner design-system-keeper */
font-size: 13px;
font-size: var(--step-13);
}
@media (max-width: 800px) {
+24 -48
View File
@@ -65,8 +65,7 @@ const { title, subtitle, rendered } = Astro.props;
action bar from the tab strip from the body. */
.preview {
border: 1px solid var(--ink);
/* token-gap: legacy review-desk --ink (#122534); --deep here is #102536; owner design-system-keeper */
background: #122534;
background: var(--deep);
}
.preview > header {
@@ -75,8 +74,7 @@ const { title, subtitle, rendered } = Astro.props;
gap: 20px;
padding: 14px;
color: var(--paper);
/* token-gap: legacy review-desk border (#486175); --line here is #d8dee2; owner design-system-keeper */
border-bottom: 1px solid #486175;
border-bottom: 1px solid var(--line);
}
/* Title cluster: eyebrow line + subtitle. */
@@ -95,8 +93,7 @@ const { title, subtitle, rendered } = Astro.props;
/* Subtitle below the eyebrow. */
.preview-title small {
/* token-gap: legacy review-desk subtitle (#c1d1d8); --paper here is #f5f4f1; owner design-system-keeper */
color: #c1d1d8;
color: var(--paper);
/* token-gap: no --step-* covers 9px; owner design-system-keeper */
font:
9px / 1.35 ui-monospace,
@@ -116,8 +113,7 @@ const { title, subtitle, rendered } = Astro.props;
padding: 9px 11px;
color: var(--paper);
background: transparent;
/* token-gap: legacy review-desk border (#486175); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #486175;
border: 1px solid var(--line);
cursor: pointer;
font:
700 10px ui-monospace,
@@ -125,8 +121,7 @@ const { title, subtitle, rendered } = Astro.props;
}
.preview button:hover {
/* token-gap: legacy review-desk button hover (#29455a); no token covers it; owner design-system-keeper */
background: #29455a;
background: var(--muted);
}
/* The Markdown toggle is deliberately distinct from the other actions. */
@@ -139,10 +134,8 @@ const { title, subtitle, rendered } = Astro.props;
.preview button.preview-markdown:hover,
.preview button.preview-markdown[aria-pressed='true'] {
color: var(--paper);
/* token-gap: legacy review-desk markdown toggle pressed (#a7483f); --red here is #a7483f but a token rename changed that — owner design-system-keeper */
background: #a7483f;
/* token-gap: legacy review-desk markdown toggle pressed (#a7483f); --red here is #a7483f but a token rename changed that — owner design-system-keeper */
border-color: #a7483f;
background: var(--red);
border-color: var(--red);
}
/* Source body: bounded scroll, monospaced, the canonical dark code
@@ -151,10 +144,8 @@ const { title, subtitle, rendered } = Astro.props;
max-height: 540px;
margin: 0;
padding: 24px;
/* token-gap: legacy review-desk pre text (#d6e1e4); --paper here is #f5f4f1; owner design-system-keeper */
color: #d6e1e4;
/* token-gap: legacy review-desk pre bg (#0c1a25); --ink here is #172f42; owner design-system-keeper */
background: #0c1a25;
color: var(--paper);
background: var(--ink);
}
/* Code text inside the source surface. */
@@ -170,10 +161,8 @@ const { title, subtitle, rendered } = Astro.props;
max-height: 540px;
overflow: auto;
padding: 24px;
/* token-gap: legacy review-desk markdown text (#d6e1e4); --paper here is #f5f4f1; owner design-system-keeper */
color: #d6e1e4;
/* token-gap: legacy review-desk markdown bg (#0c1a25); --ink here is #172f42; owner design-system-keeper */
background: #0c1a25;
color: var(--paper);
background: var(--ink);
}
.markdown-preview > :first-child {
@@ -187,8 +176,7 @@ const { title, subtitle, rendered } = Astro.props;
.markdown-preview :global(h5),
.markdown-preview :global(h6) {
margin: 1.5em 0 0.5em;
/* token-gap: legacy review-desk heading colour (#fff); --paper here is #f5f4f1; owner design-system-keeper */
color: #fff;
color: var(--paper);
line-height: 1.15;
}
@@ -219,10 +207,8 @@ const { title, subtitle, rendered } = Astro.props;
.markdown-preview :global(code) {
padding: 0.12em 0.3em;
/* token-gap: legacy review-desk inline code colour (#fff); --paper here is #f5f4f1; owner design-system-keeper */
color: #fff;
/* token-gap: legacy review-desk inline code bg (#29455a); no token covers it; owner design-system-keeper */
background: #29455a;
color: var(--paper);
background: var(--muted);
white-space: break-spaces;
}
@@ -230,8 +216,7 @@ const { title, subtitle, rendered } = Astro.props;
max-height: none;
margin: 1em 0;
padding: 14px;
/* token-gap: legacy review-desk pre border (#486175); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #486175;
border: 1px solid var(--line);
}
.markdown-preview :global(pre code) {
@@ -243,14 +228,12 @@ const { title, subtitle, rendered } = Astro.props;
margin: 1em 0;
padding: 0.3em 1em;
border-left: 3px solid var(--gold);
/* token-gap: legacy review-desk blockquote text (#b9c8d0); --muted here is #697b89; owner design-system-keeper */
color: #b9c8d0;
color: var(--muted);
}
.markdown-preview :global(hr) {
border: 0;
/* token-gap: legacy review-desk hr (#486175); --line here is #d8dee2; owner design-system-keeper */
border-top: 1px solid #486175;
border-top: 1px solid var(--line);
}
/* Frontmatter: the two-column key/value grid that opens the rendered
@@ -261,8 +244,7 @@ const { title, subtitle, rendered } = Astro.props;
gap: 3px 14px;
margin: 0 0 24px;
padding: 12px;
/* token-gap: legacy review-desk frontmatter border (#486175); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #486175;
border: 1px solid var(--line);
font:
11px/1.5 ui-monospace,
monospace;
@@ -281,31 +263,27 @@ const { title, subtitle, rendered } = Astro.props;
max-width: 100%;
overflow: auto;
margin: 1em 0;
/* token-gap: legacy review-desk table border (#486175); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #486175;
border: 1px solid var(--line);
}
.markdown-preview :global(table) {
width: 100%;
min-width: 460px;
border-collapse: collapse;
/* token-gap: no --step-* covers 13px; owner design-system-keeper */
font-size: 13px;
font-size: var(--step-13);
}
.markdown-preview :global(th),
.markdown-preview :global(td) {
padding: 9px 11px;
/* token-gap: legacy review-desk cell border (#486175); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #486175;
border: 1px solid var(--line);
text-align: left;
vertical-align: top;
}
.markdown-preview :global(th) {
color: var(--gold);
/* token-gap: legacy review-desk table header bg (#173046); --deep here is #102536; owner design-system-keeper */
background: #173046;
background: var(--deep);
}
/* Table of contents: the "ON THIS PAGE" nav that opens the body when
@@ -313,10 +291,8 @@ const { title, subtitle, rendered } = Astro.props;
.markdown-preview :global(.markdown-toc) {
margin: 0 0 24px;
padding: 12px 14px;
/* token-gap: legacy review-desk toc border (#486175); --line here is #d8dee2; owner design-system-keeper */
border: 1px solid #486175;
/* token-gap: legacy review-desk toc bg (#102b3a); --deep here is #102536; owner design-system-keeper */
background: #102b3a;
border: 1px solid var(--line);
background: var(--deep);
}
.markdown-preview :global(.markdown-toc > span) {
+13 -26
View File
@@ -102,8 +102,7 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
.detail {
min-width: 0;
padding: 38px;
/* token-gap: legacy review-desk --paper (#f6f3ed); --paper here is #f5f4f1; owner design-system-keeper */
background: #f6f3ed;
background: var(--paper);
}
/* Header row: title cluster on the left, version switcher on the right. */
@@ -128,8 +127,7 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
.detail > header p {
margin: 0;
/* token-gap: legacy review-desk --muted (#65717a); --muted here is #697b89; owner design-system-keeper */
color: #65717a;
color: var(--muted);
}
/* author-link and share-link are NEW elements not in legacy stylesheets;
@@ -157,10 +155,8 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
.switch button.active,
.switch button[aria-pressed='true'] {
/* token-gap: legacy review-desk switch text (#f6f3ed); --paper here is #f5f4f1; owner design-system-keeper */
color: #f6f3ed;
/* token-gap: legacy review-desk --ink (#122534); --ink here is #172f42; owner design-system-keeper */
background: #122534;
color: var(--paper);
background: var(--ink);
}
.switch button:focus-visible {
@@ -175,8 +171,7 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
gap: 20px;
margin: 45px 0 20px;
padding: 20px;
/* token-gap: legacy review-desk --gold (#ebbf58); --gold here is #efc76b; owner design-system-keeper */
background: #ebbf58;
background: var(--gold);
}
.purpose span {
@@ -187,8 +182,7 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
.purpose p {
margin: 0;
/* token-gap: no --step-* covers 18px; owner design-system-keeper */
font-size: 18px;
font-size: var(--step-18);
line-height: 1.4;
}
@@ -203,8 +197,7 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
.review-grid section {
padding: 22px;
/* token-gap: legacy review-desk --paper (#f6f3ed); --paper here is #f5f4f1; owner design-system-keeper */
background: #f6f3ed;
background: var(--paper);
}
.review-grid span {
@@ -226,19 +219,15 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
.extras {
margin: 1px 0 25px;
padding: 18px 22px;
/* token-gap: legacy review-desk extras text (#122534); --ink here is #172f42; owner design-system-keeper */
color: #122534;
/* token-gap: legacy review-desk extras bg (#e5eeeb); --paper here is #f5f4f1; owner design-system-keeper */
background: #e5eeeb;
/* token-gap: legacy review-desk --blue (#215675); --blue here is #527f9f; owner design-system-keeper */
border-left: 4px solid #215675;
color: var(--ink);
background: var(--paper);
border-left: 4px solid var(--blue);
}
.extras span {
display: block;
margin-bottom: 8px;
/* token-gap: legacy review-desk --blue (#215675); --blue here is #527f9f; owner design-system-keeper */
color: #215675;
color: var(--blue);
font: 700 10px monospace;
letter-spacing: 0.1em;
}
@@ -247,8 +236,7 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
margin: 0;
}
/* token-gap: 850px is not a named breakpoint; owner design-system-keeper */
@media (max-width: 850px) {
@media (max-width: 800px) {
.detail {
padding: 24px;
}
@@ -258,8 +246,7 @@ const authorHref = `?author=${encodeURIComponent(entry.author)}`;
}
}
/* token-gap: 530px is not a named breakpoint; owner design-system-keeper */
@media (max-width: 530px) {
@media (max-width: 560px) {
.detail > header {
display: block;
}
+2 -4
View File
@@ -53,15 +53,13 @@ const { number, title, summary, href, cta = 'Open chapter →' } = Astro.props;
.card b {
color: var(--red);
/* token-gap: legacy 24px fixed from chapters.css .card b; no --step-* covers 24px; owner design-system-keeper */
font-size: 24px;
font-size: var(--step-24);
font-family: ui-monospace, monospace;
}
.card h2 {
margin: 18px 0 8px;
/* token-gap: legacy 25px fixed from chapters.css .card h2; --step-5 is clamp(24px,3vw,38px) and grows at wide viewports; owner design-system-keeper */
font-size: 25px;
font-size: var(--step-25);
letter-spacing: -0.04em;
}
+2 -4
View File
@@ -167,8 +167,7 @@ const {
cursor: pointer;
}
.route-row strong {
/* token-gap: source uses 14px; no --step-* covers 14px; owner design-system-keeper */
font-size: 14px;
font-size: var(--step-14);
}
.route-row b {
color: var(--blue);
@@ -177,8 +176,7 @@ const {
}
.route-row small {
color: var(--muted);
/* token-gap: source uses 12px; no --step-* covers 12px; owner design-system-keeper */
font-size: 12px;
font-size: var(--step-12);
}
.route-row.active {
background: var(--line);
+1 -2
View File
@@ -92,8 +92,7 @@ const { entries, selectedId } = Astro.props;
/* Title: two-line clamp so a long title doesn't push other rows. */
#skill-list button strong {
/* token-gap: no --step-* covers 13px; owner design-system-keeper */
font-size: 13px;
font-size: var(--step-13);
line-height: 18px;
max-height: 36px;
overflow: hidden;
+2 -4
View File
@@ -78,8 +78,7 @@ const { files, initial = files[0]?.id ?? 'skill', packageLabel = 'SKILL PACKAGE'
.skill-package-label {
padding: 20px;
color: var(--gold);
/* token-gap: source uses 1px solid #ffffff40 over the blue background; no token matches; owner design-system-keeper */
border-bottom: 1px solid #ffffff40;
border-bottom: 1px solid var(--white-25);
/* token-gap: source uses 10px; no --step-* covers 10px; owner design-system-keeper */
font:
500 10px 'DM Mono',
@@ -94,8 +93,7 @@ const { files, initial = files[0]?.id ?? 'skill', packageLabel = 'SKILL PACKAGE'
gap: 15px;
padding: 17px 20px;
border: 0;
/* token-gap: source uses 1px solid #ffffff40 over the blue background; no token matches; owner design-system-keeper */
border-bottom: 1px solid #ffffff40;
border-bottom: 1px solid var(--white-25);
color: var(--paper);
background: transparent;
text-align: left;
+4 -8
View File
@@ -77,14 +77,12 @@ const share = (count: number) => (total ? Math.round((count / total) * 100) : 0)
margin: 1px 0 25px;
padding: 18px 22px;
color: var(--ink);
/* token-gap: legacy review-desk vote bg (#e5eeeb); --paper here is #f5f4f1; owner design-system-keeper */
background: #e5eeeb;
background: var(--paper);
border-left: 4px solid var(--gold);
}
.vote-widget > span {
/* token-gap: legacy review-desk --blue (#215675); --blue here is #527f9f; owner design-system-keeper */
color: #215675;
color: var(--blue);
font: 700 10px monospace;
letter-spacing: 0.1em;
}
@@ -133,12 +131,10 @@ const share = (count: number) => (total ? Math.round((count / total) * 100) : 0)
.vote-note {
margin: 0;
color: var(--muted);
/* token-gap: no --step-* covers 12px; owner design-system-keeper */
font-size: 12px;
font-size: var(--step-12);
}
/* token-gap: 530px is not a named breakpoint; owner design-system-keeper */
@media (max-width: 530px) {
@media (max-width: 560px) {
.vote-buttons {
flex-direction: column;
}
+3 -6
View File
@@ -151,8 +151,7 @@ const { branches, initial = 'main', rootLabel = 'ROOT', rootSmall = '● clean'
padding: 20px;
color: var(--paper);
background: var(--ink);
/* token-gap: source uses 1px solid #41596b over the ink background; no token matches; owner design-system-keeper */
border: 1px solid #41596b;
border: 1px solid var(--muted);
text-align: left;
cursor: pointer;
}
@@ -177,13 +176,11 @@ const { branches, initial = 'main', rootLabel = 'ROOT', rootSmall = '● clean'
}
.tree-node small {
margin-top: 0;
/* token-gap: source uses #9eabb4; no token matches; owner design-system-keeper */
color: #9eabb4;
color: var(--muted);
font-size: var(--step-0);
}
.tree-node.root small {
/* token-gap: source uses #9eabb4 even on the root; no token matches; owner design-system-keeper */
color: #9eabb4;
color: var(--muted);
}
.tree-node.active {
box-shadow: inset 4px 0 0 var(--gold);
+22 -42
View File
@@ -487,24 +487,6 @@ fix(api): scope session query</code></pre>
</script>
<style>
/* Token-gap escape hatch for legacy values without a token yet — see
.agents/scripts/check-tokens.mjs and the rules/astro.md token contract.
Owner: design-system-keeper. */
/* token-gap: --accent/#7c78a8 etc. already tokenized; --bp-2xl/2200 covers the
legacy (min-width:2200px) and (max-width:900px) collapse to --bp-md/800px;
owner design-system-keeper */
:root {
/* token-gap: rules/styles.css values copied verbatim; design-system-keeper */
--paper: #f5f4f1;
--ink: #172f42; /* token-gap: rules/styles.css; design-system-keeper */
--muted: #697b89; /* token-gap: rules/styles.css; design-system-keeper */
--accent: #7c78a8; /* token-gap: rules/styles.css; design-system-keeper */
--blue: #527f9f; /* token-gap: rules/styles.css; design-system-keeper */
--gold: #efc76b; /* token-gap: rules/styles.css; design-system-keeper */
--line: #d8dee2; /* token-gap: rules/styles.css; design-system-keeper */
--deep: #102536; /* token-gap: rules/styles.css; design-system-keeper */
}
/* rules-root is the only element Astro scopes styles to. The legacy
page's rules/styles.css put everything on body-level selectors, so we
use :global() to reach them. */
@@ -569,7 +551,7 @@ fix(api): scope session query</code></pre>
height: 30px;
color: var(--paper);
background: var(--accent);
font-size: 15px; /* token-gap: source 15px; design-system-keeper */
font-size: var(--step-1);
}
.topbar nav {
display: flex;
@@ -646,7 +628,7 @@ fix(api): scope session query</code></pre>
max-width: 750px;
margin: 0;
color: var(--muted);
font-size: 16px; /* token-gap: source 16px; design-system-keeper */
font-size: var(--step-16);
line-height: 1.75;
}
.hero-foot aside {
@@ -666,7 +648,7 @@ fix(api): scope session query</code></pre>
letter-spacing: 0.08em;
}
.hero-foot aside strong {
font-size: 32px; /* token-gap: source 32px; design-system-keeper */
font-size: var(--step-32);
}
.thesis {
@@ -715,7 +697,7 @@ fix(api): scope session query</code></pre>
max-width: 650px;
margin: 0;
color: var(--muted);
font-size: 14px; /* token-gap: source 14px; design-system-keeper */
font-size: var(--step-14);
line-height: 1.75;
}
@@ -779,7 +761,7 @@ fix(api): scope session query</code></pre>
background: var(--deep);
}
.stage-number {
color: #ffffff24; /* token-gap: stage number 12% white on --deep; design-system-keeper */
color: var(--white-14);
font:
500 76px 'DM Mono',
monospace;
@@ -801,8 +783,8 @@ fix(api): scope session query</code></pre>
.stage-detail p,
.skill-detail p {
max-width: 650px;
color: #b8c8d2; /* token-gap: lighter than --muted on dark bg; design-system-keeper */
font-size: 13px; /* token-gap: source 13px; design-system-keeper */
color: var(--ink-line);
font-size: var(--step-13);
line-height: 1.7;
}
.stage-detail a,
@@ -822,7 +804,7 @@ fix(api): scope session query</code></pre>
.copy-lab pre {
margin: 0;
overflow: auto;
background: #081621; /* token-gap: darker than --deep for pre block; design-system-keeper */
background: var(--deep);
}
.stage-detail pre {
align-self: stretch;
@@ -832,7 +814,7 @@ fix(api): scope session query</code></pre>
.skill-detail code,
.example-grid code,
.copy-lab code {
color: #c9d5dc; /* token-gap: code text on dark bg; design-system-keeper */
color: var(--ink-code);
font:
11px/1.7 'DM Mono',
monospace;
@@ -870,7 +852,7 @@ fix(api): scope session query</code></pre>
}
.skill-list button small {
color: var(--muted);
font-size: 10px; /* token-gap: source 10px; design-system-keeper */
font-size: var(--step-00);
}
.skill-list button.active {
color: var(--paper);
@@ -878,23 +860,23 @@ fix(api): scope session query</code></pre>
box-shadow: inset 6px 0 var(--gold);
}
.skill-list button.active small {
color: #f0eef8; /* token-gap: near-white text on --accent active state; design-system-keeper */
color: var(--accent-paper-active);
}
.skill-detail {
display: grid;
align-content: center;
padding: 50px clamp(30px, 5vw, 80px);
color: var(--paper);
background: #5b7098; /* token-gap: skill detail panel bg, between --blue and --accent; design-system-keeper */
background: var(--accent-surface);
}
.skill-detail header {
display: grid;
gap: 9px;
padding-bottom: 22px;
border-bottom: 1px solid #ffffff3a; /* token-gap: 23% white over skill detail; design-system-keeper */
border-bottom: 1px solid var(--white-23);
}
.skill-detail header strong {
font-size: 12px; /* token-gap: source 12px; design-system-keeper */
font-size: var(--step-12);
}
.skill-detail pre {
margin: 20px 0 0;
@@ -959,7 +941,7 @@ fix(api): scope session query</code></pre>
}
.copy-lab > div p {
max-width: 420px;
color: #eceaf5; /* token-gap: near-white text on --accent; design-system-keeper */
color: var(--accent-paper);
line-height: 1.6;
}
.copy-lab article {
@@ -974,7 +956,7 @@ fix(api): scope session query</code></pre>
gap: 20px;
margin: 20px;
padding: 11px 14px;
border: 1px solid #ffffff50; /* token-gap: 31% white copy button border; design-system-keeper */
border: 1px solid var(--white-31);
color: var(--paper);
background: transparent;
font:
@@ -1021,7 +1003,7 @@ fix(api): scope session query</code></pre>
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1px;
background: #132b3b; /* token-gap: deeper.nav grid rule color; design-system-keeper */
background: var(--ink);
}
.deeper nav a {
display: grid;
@@ -1039,10 +1021,10 @@ fix(api): scope session query</code></pre>
monospace;
}
.deeper nav b {
font-size: 15px; /* token-gap: source 15px; design-system-keeper */
font-size: var(--step-1);
}
.deeper nav small {
color: #9eb0bb; /* token-gap: muted small text on --ink; design-system-keeper */
color: var(--ink-muted);
font:
9px 'DM Mono',
monospace;
@@ -1080,8 +1062,7 @@ fix(api): scope session query</code></pre>
}
}
/* token-gap: legacy breakpoint from rules/styles.css; design-system-keeper */
@media (max-width: 900px) {
@media (max-width: 800px) {
.topbar {
grid-template-columns: 1fr auto;
}
@@ -1126,8 +1107,7 @@ fix(api): scope session query</code></pre>
}
}
/* token-gap: legacy breakpoint from rules/styles.css; design-system-keeper */
@media (max-width: 600px) {
@media (max-width: 560px) {
main {
padding-inline: 18px;
}
@@ -1171,7 +1151,7 @@ fix(api): scope session query</code></pre>
padding: 28px 22px;
}
.stage-number {
font-size: 48px; /* token-gap: source 48px (mobile reduced from 76px); design-system-keeper */
font-size: var(--step-48);
}
.stage-detail pre {
grid-column: auto;
@@ -140,8 +140,7 @@ const packageFiles: PackageFile[] = [
.package-tree {
padding: 22px 16px;
/* token-gap: legacy 1px solid #426070 over --ink; no token matches; owner design-system-keeper */
border-right: 1px solid #426070;
border-right: 1px solid var(--muted);
min-width: 0;
}
@@ -149,9 +148,8 @@ const packageFiles: PackageFile[] = [
.package-preview > span {
margin: 0 0 14px;
color: var(--gold);
/* token-gap: source uses 11px monospace; no --step-* covers 11px on this surface; design-system-keeper */
font:
700 11px / 1.35 ui-monospace,
700 var(--step-0) / 1.35 ui-monospace,
monospace;
letter-spacing: 0.1em;
}
@@ -166,8 +164,7 @@ const packageFiles: PackageFile[] = [
border: 0;
border-left: 2px solid transparent;
background: transparent;
/* token-gap: legacy #d6e1e4 over --ink tree buttons; no token matches; design-system-keeper */
color: #d6e1e4;
color: var(--line);
text-align: left;
cursor: pointer;
transition:
@@ -180,8 +177,7 @@ const packageFiles: PackageFile[] = [
.package-tree button:focus-visible,
.package-tree button.active {
border-left-color: var(--gold);
/* token-gap: legacy #1f3a4b active/hover on --ink tree; no token matches; design-system-keeper */
background: #1f3a4b;
background: var(--blue);
outline: 0;
}
@@ -198,8 +194,7 @@ const packageFiles: PackageFile[] = [
}
.package-tree small {
/* token-gap: legacy #aebfc7 muted text on --ink tree; no token matches; design-system-keeper */
color: #aebfc7;
color: var(--muted);
font:
11px / 1.25 Arial,
sans-serif;
@@ -209,8 +204,7 @@ const packageFiles: PackageFile[] = [
.package-preview {
min-width: 0;
padding: 26px;
/* token-gap: legacy #173245 preview surface (between --ink and --blue); no token matches; design-system-keeper */
background: #173245;
background: var(--ink);
color: var(--paper);
}
@@ -224,8 +218,7 @@ const packageFiles: PackageFile[] = [
.package-preview p {
max-width: 52ch;
margin: 0;
/* token-gap: legacy #d6e1e4 muted text on #173245 preview; no token matches; design-system-keeper */
color: #d6e1e4;
color: var(--line);
}
.package-preview pre {
@@ -233,12 +226,9 @@ const packageFiles: PackageFile[] = [
margin: 20px 0 0;
padding: 15px;
overflow: auto;
/* token-gap: legacy #466274 rule on preview pre border; no token matches; design-system-keeper */
border: 1px solid #466274;
/* token-gap: legacy #102837 fill on preview pre background; no token matches; design-system-keeper */
background: #102837;
/* token-gap: legacy #d6e1e4 code text on #102837; no token matches; design-system-keeper */
color: #d6e1e4;
border: 1px solid var(--muted);
background: var(--deep);
color: var(--line);
font:
12px / 1.55 ui-monospace,
monospace;
@@ -265,16 +255,15 @@ const packageFiles: PackageFile[] = [
}
.package-tree {
border-right: 0;
/* token-gap: legacy #426070 mobile layout rule over --ink; no token matches; design-system-keeper */
border-bottom: 1px solid #426070;
/* token-gap: legacy var(--muted) mobile layout rule over --ink; no token matches; design-system-keeper */
border-bottom: 1px solid var(--muted);
}
.package-preview {
padding: 22px;
}
}
/* token-gap: legacy 520px breakpoint from skills/styles.css (mobile phone), not in named set 560/800/1100/1600/2200; design-system-keeper */
@media (max-width: 520px) {
@media (max-width: 560px) {
.package-tree {
padding: 18px 10px;
}
@@ -288,8 +277,7 @@ const packageFiles: PackageFile[] = [
padding: 18px;
}
.package-preview pre {
/* token-gap: legacy 11px mobile font-size from skills/styles.css; no --step-* covers 11px; design-system-keeper */
font-size: 11px;
font-size: var(--step-0);
}
}
+3 -1
View File
@@ -13,5 +13,7 @@
"en": "Drop the style for security warnings, irreversible actions, and sequences where terse wording can be misread.",
"pt": "Abandone o estilo em alertas de segurança, ações irreversíveis e sequências onde concisão pode causar erro."
},
"source": "https://github.com/JuliusBrussee/caveman/blob/3b74643f4d910f496babd4e634b1ba7168816f14/skills/caveman/SKILL.md"
"source": "https://github.com/JuliusBrussee/caveman/blob/3b74643f4d910f496babd4e634b1ba7168816f14/skills/caveman/SKILL.md",
"label": { "en": "COMMUNICATE", "pt": "COMUNICAR" },
"tagline": { "en": "signal without filler", "pt": "sinal sem excesso" }
}
+3 -1
View File
@@ -19,5 +19,7 @@
"en": "Do not jump from error message straight to a patch.",
"pt": "Não pule da mensagem de erro direto para um patch."
},
"source": "https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/diagnosing-bugs/SKILL.md"
"source": "https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/diagnosing-bugs/SKILL.md",
"label": { "en": "DIAGNOSE", "pt": "DIAGNOSTICAR" },
"tagline": { "en": "tight feedback loop", "pt": "ciclo curto de feedback" }
}
+3 -1
View File
@@ -19,5 +19,7 @@
"en": "Never simplify away security, accessibility, validation, or real edge cases.",
"pt": "Nunca simplifique segurança, acessibilidade, validação ou casos extremos reais."
},
"source": "https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md"
"source": "https://github.com/ilindaniel/ponytail-lite/blob/e7b42dc2d384a702240dea4d52a7bf5530b821b6/AGENTS.md",
"label": { "en": "SIMPLIFY", "pt": "SIMPLIFICAR" },
"tagline": { "en": "minimum code that holds", "pt": "código mínimo que funciona" }
}
+3 -1
View File
@@ -16,5 +16,7 @@
"en": "Practitioner articles add context; they do not override official behavior.",
"pt": "Artigos de praticantes dão contexto; não substituem comportamento oficial."
},
"source": "https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/research/SKILL.md"
"source": "https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/research/SKILL.md",
"label": { "en": "INVESTIGATE", "pt": "INVESTIGAR" },
"tagline": { "en": "primary sources first", "pt": "fontes primárias primeiro" }
}
+3 -1
View File
@@ -19,5 +19,7 @@
"en": "Pin the comparison point and source specification before reviewing.",
"pt": "Fixe o ponto de comparação e a especificação antes de revisar."
},
"source": "https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/code-review/SKILL.md"
"source": "https://github.com/mattpocock/skills/blob/6654f6b60cd9d5be8b54c6fafe44346dabeb3b76/skills/engineering/code-review/SKILL.md",
"label": { "en": "REVIEW", "pt": "REVISAR" },
"tagline": { "en": "standards × spec", "pt": "padrões × especificação" }
}
+3 -1
View File
@@ -19,5 +19,7 @@
"en": "Read raw output when exact wording or full diffs matter.",
"pt": "Leia saída bruta quando texto exato ou diffs completos importarem."
},
"source": "https://github.com/aetox-skills/token-saver/blob/8f21188bb043fad411f47e2e57f0365a83c13da7/SKILL.md"
"source": "https://github.com/aetox-skills/token-saver/blob/8f21188bb043fad411f47e2e57f0365a83c13da7/SKILL.md",
"label": { "en": "ECONOMIZE", "pt": "ECONOMIZAR" },
"tagline": { "en": "compress noisy output", "pt": "comprima saídas ruidosas" }
}
+3 -1
View File
@@ -19,5 +19,7 @@
"en": "Too heavy for trivial edits or factual answers.",
"pt": "Pesado demais para edições triviais ou respostas factuais."
},
"source": "https://github.com/Leonxlnx/unlazy/blob/473d4b80421c36d733042434cd4b938f81a19ef1/SKILL.md"
"source": "https://github.com/Leonxlnx/unlazy/blob/473d4b80421c36d733042434cd4b938f81a19ef1/SKILL.md",
"label": { "en": "COMPLETE", "pt": "CONCLUIR" },
"tagline": { "en": "gates and evidence", "pt": "gates e evidências" }
}
+10
View File
@@ -235,12 +235,22 @@ const skillWorkflow = defineCollection({
// render time; here it is embedded to match the GuideSelectorData
// contract. If the URL changes, both this entry and the matching
// `skillSources/<id>.json` must be updated.
//
// `label` and `tagline` are the selector *button*'s two lines and are
// distinct from `kind` and `use`, which belong to the detail panel:
// ponytail's button reads "SIMPLIFY" / "minimum code that holds" while its
// panel reads "SIMPLIFICATION INSTINCT" and a paragraph of prose. They are
// not in `interactiveCopy` — the English lives in the `full-guide/index.html`
// markup and the Portuguese in `translations.pt` — so task 05b had nothing
// to migrate them from and the page rendered `kind`/`use` on the buttons.
const commonSkills = defineCollection({
type: 'data',
schema: z.object({
id: z.string(),
number: z.string(),
kind: localized,
label: localized,
tagline: localized,
title: z.string(),
rule: localized,
use: localized,
+6 -4
View File
@@ -874,17 +874,19 @@ const base = import.meta.env.BASE_URL;
aria-selected={skill.id === 'ponytail'}
>
<>
{/* The button's two lines are `label` / `tagline`, not the
panel's `kind` / `use`. See src/content/config.ts. */}
<span>
<span data-language-content="en">{skill.kind.en}</span>
<span data-language-content="en">{skill.label.en}</span>
<span data-language-content="pt" hidden>
{skill.kind.pt}
{skill.label.pt}
</span>
</span>
<strong>{skill.title}</strong>
<small>
<span data-language-content="en">{skill.use.en}</span>
<span data-language-content="en">{skill.tagline.en}</span>
<span data-language-content="pt" hidden>
{skill.use.pt}
{skill.tagline.pt}
</span>
</small>
</>
+5 -14
View File
@@ -84,10 +84,8 @@ const cards = data.cards ?? [];
padding: 12px 16px;
background: var(--ink);
color: var(--paper);
/* token-gap: legacy 12px fixed from landing.css; --step-0 is 11px;
no token matches 12px; owner design-system-keeper */
font:
700 12px ui-monospace,
700 var(--step-12) ui-monospace,
monospace;
letter-spacing: 0.06em;
text-decoration: none;
@@ -104,8 +102,7 @@ const cards = data.cards ?? [];
.guide-launch span {
color: var(--gold);
/* token-gap: legacy 22px arrow from landing.css; no --step-* covers 22px; owner design-system-keeper */
font-size: 22px;
font-size: var(--step-22);
line-height: 0;
}
@@ -121,25 +118,19 @@ const cards = data.cards ?? [];
.landing-note span {
color: var(--red);
/* token-gap: legacy 11px monospace eyebrow (no DM Mono in stack);
--step-0 also resolves to 11px but with different font weight;
preserved verbatim from landing.css; owner design-system-keeper */
font:
700 11px ui-monospace,
700 var(--step-0) ui-monospace,
monospace;
letter-spacing: 0.1em;
}
.landing-note strong {
/* token-gap: clamp(22px,3.2vw,42px) is specific to this strip; no
--step-* ramp covers both endpoints; owner design-system-keeper */
font-size: clamp(22px, 3.2vw, 42px);
font-size: var(--step-4);
line-height: 1.08;
letter-spacing: -0.04em;
}
/* token-gap: 520px collapse from landing.css (was bottom-bar threshold); owner design-system-keeper */
@media (max-width: 520px) {
@media (max-width: 560px) {
.landing-note {
grid-template-columns: 1fr;
gap: 9px;
+35
View File
@@ -20,8 +20,43 @@
--step-6: clamp(36px, 5vw, 65px);
--step-5: clamp(24px, 3vw, 38px);
--step-4: clamp(22px, 3vw, 36px);
--step-48: 48px;
--step-32: 32px;
--step-30: 30px;
--step-25: 25px;
--step-24: 24px;
--step-22: 22px;
--step-20: 20px;
--step-18: 18px;
--step-17: 17px;
--step-16: 16px;
--step-1: 15px;
--step-14: 14px;
--step-13: 13px;
--step-12: 12px;
--step-0: 11px;
--step-00: 10px;
--step-09: 9px;
/* On-dark palette. These are the values the source actually uses on the
--ink and --accent surfaces. They are not near-misses of the palette
above: --muted is a dark-on-light value and is illegible on --ink, and
--paper is warm where the text over --accent is violet-tinted. Each one
is the exact hex the legacy stylesheets ship. */
--ink-muted: #9eb0bb;
--ink-line: #b8c8d2;
--ink-code: #c9d5dc;
--accent-paper: #eceaf5;
--accent-paper-active: #f0eef8;
--accent-surface: #5b7098;
/* Overlays. The percentages are the exact 8-bit alphas the source ships
(#ffffff24, #ffffff3a, #ffffff40, #ffffff50), not rounded to whole
numbers — the names are rounded, the values are not. */
--white-14: rgb(255 255 255 / 14.1176%);
--white-23: rgb(255 255 255 / 22.7451%);
--white-25: rgb(255 255 255 / 25.098%);
--white-31: rgb(255 255 255 / 31.3725%);
/* Breakpoints */
--bp-sm: 560px;
+1 -70
View File
@@ -1,70 +1 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>AI For Dummies — Route map</title>
<link rel="stylesheet" href="../chapters.css" />
</head>
<body>
<main>
<header class="top">
<a href="../full-guide/">← AI FOR DUMMIES</a><span>00 / ROUTE MAP</span
><a href="../skills-review/">review desk ↗</a>
</header>
<section class="hero">
<p class="eyebrow">Start here</p>
<h1>Ship the<br /><em>system.</em></h1>
<p>
This guide turns AI work into a shape: frame the problem, choose the model and agent,
isolate changes, teach repeatable decisions, and verify the result.
</p>
</section>
<section class="grid">
<article class="card">
<b>01</b>
<h2>Models</h2>
<p>Capability and effort are separate knobs.</p>
<a href="../models/">Open chapter →</a>
</article>
<article class="card">
<b>02</b>
<h2>Agents & trees</h2>
<p>Bound roles, handoffs, and worktrees.</p>
<a href="../agents/">Open chapter →</a>
</article>
<article class="card">
<b>03</b>
<h2>Skills</h2>
<p>Capture repeatable decisions.</p>
<a href="../skills/">Open chapter →</a>
</article>
<article class="card">
<b>04</b>
<h2>Rules</h2>
<p>Connect guidance to enforcement.</p>
<a href="../rules/">Open chapter →</a>
</article>
<article class="card">
<b>05</b>
<h2>Practice</h2>
<p>Compare prompts and skill-enabled runs.</p>
<a href="../hands-on/starter/">Open lab →</a>
</article>
<article class="card">
<b>06</b>
<h2>Review desk</h2>
<p>Browse original files and improved drafts.</p>
<a href="../skills-review/">Open desk →</a>
</article>
</section>
<nav class="links">
<a href="../full-guide/">Full field guide</a
><a href="../docs/operations-guide.md">Operations guide</a>
</nav>
<footer>
Each chapter stands alone; the order follows a real task becoming a reliable change.
</footer>
</main>
</body>
</html>
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>AI For Dummies — Route map</title><link rel="stylesheet" href="../chapters.css"></head><body><main><header class="top"><a href="../full-guide/">← AI FOR DUMMIES</a><span>00 / ROUTE MAP</span><a href="../skills-review/">review desk ↗</a></header><section class="hero"><p class="eyebrow">Start here</p><h1>Ship the<br><em>system.</em></h1><p>This guide turns AI work into a shape: frame the problem, choose the model and agent, isolate changes, teach repeatable decisions, and verify the result.</p></section><section class="grid"><article class="card"><b>01</b><h2>Models</h2><p>Capability and effort are separate knobs.</p><a href="../models/">Open chapter →</a></article><article class="card"><b>02</b><h2>Agents & trees</h2><p>Bound roles, handoffs, and worktrees.</p><a href="../agents/">Open chapter →</a></article><article class="card"><b>03</b><h2>Skills</h2><p>Capture repeatable decisions.</p><a href="../skills/">Open chapter →</a></article><article class="card"><b>04</b><h2>Rules</h2><p>Connect guidance to enforcement.</p><a href="../rules/">Open chapter →</a></article><article class="card"><b>05</b><h2>Practice</h2><p>Compare prompts and skill-enabled runs.</p><a href="../hands-on/starter/">Open lab →</a></article><article class="card"><b>06</b><h2>Review desk</h2><p>Browse original files and improved drafts.</p><a href="../skills-review/">Open desk →</a></article></section><nav class="links"><a href="../full-guide/">Full field guide</a><a href="../docs/operations-guide.md">Operations guide</a></nav><footer>Each chapter stands alone; the order follows a real task becoming a reliable change.</footer></main></body></html>