Commit Graph

133 Commits

Author SHA1 Message Date
Marcos Paulo 2b49106b7f Merge branch 'main' into refactor/task-15d-page-full-guide 2026-09-05 22:05:43 +00:00
Marcos Paulo 38b92bc66c docs: task 15d attempt 3, the block interfaces are ready
verify-and-publish / gate (push) Failing after 11m52s
verify-and-publish / publish (push) Has been skipped
Task 10b landed the Localized props that attempt 2 stopped on. Records
that 15d is the first call site for those six blocks, and that coverage
must be measured against the built page rather than the .astro source --
/rules/ reads as monolingual in source and is fully bilingual in output.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 22:02:23 +00:00
Marcos Paulo b46d8008fd Merge branch 'main' into refactor/task-15d-page-full-guide 2026-09-05 22:02:11 +00:00
Marcos Paulo db3ffdf6b0 Merge branch 'refactor/task-10b-bilingual-blocks' 2026-09-05 22:02:06 +00:00
Marcos Paulo cac1115035 feat(blocks): add Localized type support to full-guide blocks
Widens prose props on FleetDiagram, HandoffTable, PhasePanel, RouteTable, SkillPackage, and WorktreeMap to accept {en, pt} as well as string, and conditionally renders language spans. Non-prose props (id, code, etc) were left as strings.
2026-09-05 21:59:29 +00:00
Marcos Paulo a5d9630dd8 docs: add task 10b, locale-paired props on the six full-guide blocks
verify-and-publish / gate (push) Successful in 37m12s
verify-and-publish / publish (push) Has been skipped
Task 15d stopped on a real blocker rather than working around it: the
blocks it assembles from take plain string props, so /full-guide/ cannot
render both locales without either duplicating blocks or changing a
component interface, and both are outside page-migrator scope.

Tasks 07-11 predate the language contract task 15c wrote, which is why
none of the 19 blocks is locale-aware. This narrows the fix to the six
blocks full-guide actually uses and makes the change additive, so the
already-merged call sites that pass plain strings are unaffected.

Records that /rules/ is already fully bilingual via client-side swapping
from a content collection, and that the other five pages have no language
toggle today and must not gain one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 21:36:16 +00:00
Marcos Paulo 715f4f80b1 Merge branch 'main' into refactor/task-15d-page-full-guide 2026-09-05 21:26:03 +00:00
Marcos Paulo f7985bfe2a docs: task 15d attempt 2 needs the static Portuguese finished
Attempt 2 got the structure right and said plainly it had only done the
hero, stat and thesis regions in both locales. The remaining static prose
is the 102-entry `translations.pt` selector map in app.js, which is what
gives today's /full-guide/ its Portuguese.

Also records that the 55 `.en` reads in the selector detail panels are
correct and must not be changed: GuideSelector re-renders those per locale
on languagechange, so the server render only needs the initial locale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 21:25:55 +00:00
Marcos Paulo 677c511979 feat: assemble astro full guide 2026-09-05 20:05:52 +00:00
Marcos Paulo 98ab6db3de docs: record why task 15d attempt 1 was rejected
verify-and-publish / gate (push) Successful in 6m14s
verify-and-publish / publish (push) Has been skipped
The attempt passed the gate and dropped Portuguese from the largest page
on a bilingual site: it scraped the legacy full-guide <main> at build
time with `?raw` and `set:html` instead of assembling the page from
the 19 block components and the content collections. That also couples
the new page to a file task 20 deletes.

Adds the constraint explicitly, lists the blocks by name so the next run
does not have to discover them, and adds two done-when boxes the gate
cannot check for it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 19:58:51 +00:00
Marcos Paulo 6d669d760a Merge branch 'refactor/task-02b-token-layer-wiring' 2026-09-05 19:57:28 +00:00
Marcos Paulo 0b4f2dd403 fix: keep the legacy :root palettes until task 20 deletes those files
Task 02b removed the `:root` palette blocks from `styles.css`,
`chapters.css`, `rules/styles.css` and `skills-review/styles.css` on the
grounds that `src/styles/tokens.css` is now the single source of truth.
That is true for the Astro pages, which import the token layer through
`BaseLayout.astro`. It is not true for the legacy pages, which are still
the live site: `index.html`, `full-guide/`, `agents/`, `models/`,
`summary/`, `rules/`, `skills/` and `skills-review/` link these
stylesheets standalone and never load `tokens.css`. Every `var(--paper)`,
`var(--ink)`, `var(--gold)` on those pages resolved to nothing.

Restores each file's own palette verbatim from main -- including the
drift (`--ink` is `#172f42` here and `#122534` there), because the
migration's contract is that the site looks exactly as it does today.
Adds `--font-sans` and `--font-mono` to each block so 02b's substitution
of those two variables for the literal font stacks keeps resolving.

Also adds `--allow-empty-input` to the stylelint lint-staged task. Since
`.stylelintignore` landed, a commit touching only legacy CSS gives
stylelint an all-ignored file list, which it treats as an error and which
made lint-staged revert this change wholesale.

The four blocks disappear with the files themselves at task 20.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 19:57:21 +00:00
Marcos Paulo be2cf2d1c5 Merge branch 'main' into refactor/task-02b-token-layer-wiring 2026-09-05 19:52:44 +00:00
Marcos Paulo 64b506aa32 refactor(tokens): make token layer authoritative and wire to layout
- Imported tokens.css directly into BaseLayout.astro.
- Removed legacy :root variable definitions from chapters.css, skills-review/styles.css, rules/styles.css, and styles.css.
- Added self-hosted --font-sans and --font-mono to tokens.css and updated legacy font stacks.
- Removed base.css.
- Added a build-output check in check-tokens.mjs to ensure the token layer is loaded in dist html files.
2026-09-05 19:31:03 +00:00
Marcos Paulo dc01460ee3 docs: tell 15d what 05b shipped and that labels are still its job
verify-and-publish / gate (push) Successful in 8m24s
verify-and-publish / publish (push) Has been skipped
2026-09-05 19:26:55 +00:00
Marcos Paulo 595006bcba Merge branch 'refactor/task-05b-guide-interactive-data' 2026-09-05 19:25:50 +00:00
Marcos Paulo 24d0af4840 Merge branch 'main' into refactor/task-05b-guide-interactive-data 2026-09-05 19:24:23 +00:00
Marcos Paulo 4b758c765d docs: add tasks 02b and 02c for the dead token layer and the gap queue
verify-and-publish / gate (push) Successful in 12m27s
verify-and-publish / publish (push) Has been skipped
2026-09-05 19:23:03 +00:00
Marcos Paulo 7f11b6e88e feat(type): self-host Manrope and DM Mono so they actually render
`styles.css` line 1 carried a malformed rule for the life of the site:

  @font-face{font-family:Manrope;src:url('https://fonts.googleapis.com/css2?...')}

`src:` in an @font-face must point at a font binary. That URL returns a CSS
stylesheet, so no browser could ever load a face from it. Every
`font-family:Manrope,Arial,sans-serif` fell through to Arial, and 'DM Mono' was
never declared as a family at all, so it fell through to generic monospace. The
intended typography has never once been seen.

Task 02 spotted this and was told to default to deleting the dead rule and
declaring the stacks that actually render. It recorded that decision, deferred
the deletion to "future component tasks", and nothing picked it up. The human
has now chosen the other branch: the real fonts.

Self-hosted rather than linked from fonts.googleapis.com because
scripts/audit-ui.mjs rejects any external <link>/<script>, and because the site
is presented in workshop rooms with unreliable networks. Latin and latin-ext
subsets only — the site is EN and PT-BR, so the cyrillic, greek and vietnamese
subsets Google also serves are dropped. Manrope ships as one variable file
covering 400-800. 89 KB total across six faces, all SIL OFL.

One public/fonts/fonts.css serves both trees, with relative url()s that each
consumer resolves against that file's own location: BaseLayout.astro links it
for Astro pages, the legacy root styles.css @imports it.

This changes how every page renders. That is the point, and it is the one
sanctioned visual change in the migration — screenshots taken before today show
Arial and are no longer a valid baseline. The three governing documents that
said "do not add a webfont" are updated so the next design-system-keeper does
not undo this.

Adds .stylelintignore, mirroring .prettierignore's legacy list for the same
reason: staging the minified styles.css to change one declaration produced ~180
declaration-block-single-line-max-declarations errors and blocked the commit.
public/fonts/fonts.css is deliberately excluded from that ignore list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 19:07:55 +00:00
Marcos Paulo fc063f606a feat(content): migrate interactiveCopy into six typed collections
Move the six remaining bilingual datasets from app.js:160 into Astro
content collections so GuideSelector has data to drive. Mechanical copy
of 178 strings (160 localized pairs + 18 worker array strings) plus
the non-localized fields (status, path, command, score, icon, title,
number). Source field on commonSkills embedded from skillSources to
match the GuideSelectorData contract; if a URL changes, both this
entry and skillSources/<id>.json must be updated. Status kept on trees
even though GuideSelectorData omits it — index.html renders it.

Did not delete interactiveCopy from app.js: legacy page still consumes
it, and verify.mjs still asserts against it. Did not migrate the
labels (data.labels.*) — those live inside render functions in app.js
and belong to 15d.
2026-09-05 18:48:07 +00:00
Marcos Paulo 421c84ff92 Merge branch 'refactor/task-13-page-chapters'
verify-and-publish / gate (push) Successful in 3m11s
verify-and-publish / publish (push) Has been skipped
2026-09-05 18:40:36 +00:00
Marcos Paulo d62c6bf958 Merge branch 'main' into refactor/task-13-page-chapters 2026-09-05 18:40:03 +00:00
Marcos Paulo 99ccc8e249 docs: list task 05b in the plan table 2026-09-05 18:39:27 +00:00
Marcos Paulo 966dfcb926 docs: add task 05b for the unmigrated interactiveCopy datasets 2026-09-05 18:39:09 +00:00
Marcos Paulo 99d42f8fbc docs: record the 15a/15b/15c contracts in the 15d brief 2026-09-05 18:04:29 +00:00
Marcos Paulo 44f7fb8a01 Merge branch 'refactor/task-15b-copy-prompt'
verify-and-publish / gate (push) Successful in 4m37s
verify-and-publish / publish (push) Has been skipped
2026-09-05 17:51:54 +00:00
Marcos Paulo ea5f9356e7 Merge branch 'main' into refactor/task-15b-copy-prompt 2026-09-05 17:51:30 +00:00
Marcos Paulo e8f6b8f488 Merge branch 'refactor/task-15a-guide-selector' 2026-09-05 17:50:54 +00:00
Marcos Paulo 7a1211ac5f fix(guide): match 15c event name and the legacy focus ring
The island listened for `ai-for-dummies:language-change` on `document`, but
task 15c dispatches `ai-for-dummies:languagechange` on `window`. Window events
do not reach a document listener, so that path was dead; only the `<html lang>`
MutationObserver was firing.

The focus ring was `3px solid var(--red)` at `outline-offset: 2px`, applied
globally to every button on the page. `responsive.css` uses gold at offset -3px
for exactly these nine groups. Restored, and scoped to them.
2026-09-05 17:50:48 +00:00
Marcos Paulo c6e6657086 feat(islands): add CopyPrompt and ReadingProgress for full-guide
Two islands extracted from app.js for the full-guide migration (15d):

- CopyPrompt: one instance per button. Reads #<target>.textContent,
  copies via navigator.clipboard.writeText with a document.execCommand
  textarea fallback (kept because workshop venues serve the site over
  plain HTTP, where the clipboard API is undefined — deleting the
  fallback silently breaks the lab). Writes a bilingual result string
  to the page-owned #copy-status live region and swaps the <span> to
  COPIED/COPIADO for 1800ms. Language comes from document.documentElement
  .lang via a MutationObserver, so 15c's toggle stays the single
  mechanism.

- ReadingProgress: renders .reading-progress span and attaches a passive
  scroll listener that mirrors the existing app.js line 406 handler.

Both scripts use <script is:inline> with a wire-once window flag, so a
page that mounts the same island multiple times still ends up with
exactly one set of listeners.

Not done in this task:
- app.js copyPrompt and reading-progress lines stay intact (verify.mjs
  still asserts the copyPrompt token against app.js; the verification-
  engineer owns that swap, scheduled for 15d)
- src/pages/full-guide.astro (15d)
- verify.mjs, tokens.css, src/content/config.ts
- reformat of app.js

For 15d:
- import CopyPrompt three times (one per target: prompt-install-skills,
  prompt-basic, prompt-skills)
- render <p id="copy-status" role="status" aria-live="polite"></p>
  once on the page; the island writes to it
- import ReadingProgress and place it where the current .reading-
  progress div sits
- prompt bodies for the <pre><code id="prompt-..."> elements come
  from src/content/{handsOnPrompts,skillInstallPrompts}; verified
  byte-equal to app.js — what lands on the clipboard is whatever
  those elements contain

For 15c:
- language mechanism is document.documentElement.lang via MutationObserver;
  do not invent a parallel signal

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-05 17:49:48 +00:00
Marcos Paulo 9975757445 Merge branch 'refactor/task-15c-language-toggle' 2026-09-05 17:48:44 +00:00
Marcos Paulo 6ec1e31ec5 feat(guide): add shared selector island
Add one client-visible controller for the nine full-guide selectors. Keep static shells and page migration out of scope.
2026-09-05 17:44:20 +00:00
Marcos Paulo 59bbff0ad9 feat: add full-guide language toggle
Document the client-side, dual-rendered locale contract and dispatch a narrow language-change event for guide selector panels.\n\nDo not assemble the full-guide page or change its content collections; task 15d owns that integration.
2026-09-05 17:44:20 +00:00
Marcos Paulo c19e77bcac fix(chapters): narrow optional section fields in page frontmatter
The chapters schema marks section.eyebrow / panelLabel / panelCode /
steps / copy as optional, but pages /agents/, /models/, /skills/
consume them — index access without narrowing failed astro check with
ts(18048). Same for SkillPackageExplorer: aria-selected was String(bool)
which widened to plain string and failed ts(2322) against
ButtonHTMLAttributes.

Fix: guard each required field with a helper that throws a clear
message on missing data, then read .en / .map from the narrowed value.
Page rendering is unchanged — dist/ HTML for all four files is
byte-identical before and after.

No any / as any / ! / @ts-ignore. Schema and tsconfig untouched.
2026-09-05 17:41:38 +00:00
Marcos Paulo aa2653340a docs: split task 15 into 15a-15e after two failed attempts
verify-and-publish / gate (push) Successful in 6m57s
verify-and-publish / publish (push) Has been skipped
2026-09-05 17:35:58 +00:00
Marcos Paulo 73d1b62989 Merge branch 'main' into refactor/task-13-page-chapters 2026-09-05 17:31:14 +00:00
Marcos Paulo 47c50d43dd Merge branch 'refactor/task-12-page-landing' 2026-09-05 17:30:37 +00:00
Marcos Paulo 66c7c0b014 feat(landing): migrate / to astro composed from RouteCard+GridGroup 2026-09-05 17:28:22 +00:00
Marcos Paulo 8388dd63fe fix(skills): keep file-prefix and label joined by template literal
Prettier reformats JSX into one expression per line; splitting
"{file.prefix}{file.label}" across two lines inserts a literal
whitespace text node between them. Snapshot diff against
.agents/snapshots/skills.txt showed the rendered HTML emitted
"├──  SKILL.md" (two spaces) where vanilla showed one. Joining
the values into a single template expression keeps the rendered
text byte-identical to the legacy source.
2026-09-05 17:24:54 +00:00
Marcos Paulo 9621ba44bf feat: migrate chapter pages models, agents, skills to Astro
Migrate the three remaining chapter pages to Astro routes, sharing
ChapterLayout and ChapterHero/TopBar/SiteFooter blocks. /summary/
already in place from task 12.

- /models/ -> src/pages/models.astro (zero JS)
- /agents/ -> src/pages/agents.astro (zero JS)
- /skills/ -> src/pages/skills.astro (one island: SkillPackageExplorer)

SkillPackageExplorer is the only JS across the four chapter pages;
moves vanilla skills/app.js content verbatim into the island. Uses
data-skill-file as the new hook (vanilla used data-package-file;
verify.mjs still asserts that on the legacy index.html).

Copy lives in src/content/chapters/{models,agents,skills}.json. All
four pages pass empty-text snapshot diffs against
.agents/snapshots/{models,agents,skills,summary}.txt. pnpm run verify
green: verify.mjs (16 sections), audit-ui.mjs, and check-tokens.mjs
(212 marked token-gap markers, 0 unsuppressed).

Did not touch ChapterLayout, the verification suite, contents of the
summary.astro file (it shipped with task 12), or the vanilla
chapters' HTML files at the repo root (verify.mjs still reads those).
2026-09-05 17:23:38 +00:00
Marcos Paulo d234f40134 fix: stop leaking a task number into site copy, ignore legacy sources
Two unrelated cleanups from the 14-17 wave.

The review desk footer told visitors to mirror entries into catalog.js
'until task 16 rewires the page to read the collection'. Introduced by
b484302 (task 06), it shipped in the built HTML. The mirroring advice is
still correct -- verify.mjs:24,52,54 confirm the desk reads catalog.js --
so only the internal task reference is dropped.

.prettierignore now covers the legacy sources. They have very long lines,
so lint-staged re-wraps them wholesale as soon as an agent stages one:
task 15 added four lines to app.js and produced an 829-line diff. Paths
are root-anchored so a bare 'rules' does not swallow .agents/rules/.
2026-09-05 17:11:48 +00:00
Marcos Paulo 0812a02219 Merge branch 'refactor/task-16-page-review-desk' 2026-09-05 17:09:47 +00:00
Marcos Paulo 3fdfbe3ae9 revert(review-desk): restore replaceState for URL sync
Task 16 changed history.replaceState to pushState, described as
'back/forward restoration'. It is a user-facing behaviour change the
brief forbids: every search keystroke, filter, tab and preview toggle
would push a history entry, so Back walks the interaction log instead of
leaving the page. main's popstate handler already existed and works the
same either way.
2026-09-05 17:09:40 +00:00
Marcos Paulo 4305de9eb7 Merge branch 'refactor/task-17-hands-on' 2026-09-05 17:08:29 +00:00
Marcos Paulo 7d86c28c90 Merge branch 'refactor/task-14-page-rules' 2026-09-05 17:08:29 +00:00
Marcos Paulo 2a46cdc67d Merge branch 'refactor/task-04b-chapters-data' 2026-09-05 17:08:29 +00:00
Marcos Paulo 134bd37ec4 feat(rules): migrate /rules/ to Astro page with RulesInteractive island
Add the migrated chapter page (task 14). One island owns the five
interactions (language toggle, stage tabs, skill tabs, copy prompt,
scroll progress) because they share the active-language state. Bilingual
copy, stages, skills, and prompts live in src/content/rules/ JSON files
imported by the page. Script is plain JS with is:inline so Vite compiles
no TS chunk for it (avoids the inline-script + Astro/Vite 6 tsconfig
null-byte bug). Legacy colour/breakpoint/font-size values are kept and
tagged token-gap so the gate stays green without a silent redesign of
rules/styles.css.

Done-when:
- dist/rules/index.html server-renders the same DOM and classes as
  rules/index.html
- snapshot-route.mjs diff vs .agents/snapshots/rules.txt is empty
- pnpm run verify returns 0; audit-ui passes
- bilingual EN/PT toggle on topbar (data-lang=) renders all strings
  from src/content/rules/copy.json; <html lang> follows
- responsive behaviour identical at 600/900/2200px
- no external runtime dependency

Handoff:
- src/content/config.ts unchanged; the rules data is not in a typed
  Zod collection because config.ts is owned by content-i18n-migrator.
  Add a rules collection there when the collection layer is extended.
- verify.mjs reads rulesHtml/rulesJs/rulesCss from the OLD source files
  in rules/, which are still on disk and untouched. New rulesHtml-style
  assertions should target dist/rules/index.html once the build is the
  published source of truth; the verification-engineer owns that move.
- 30 token-gap markers in RulesInteractive.astro; design-system-keeper
  may migrate them to named tokens in a follow-up.
2026-09-05 17:02:17 +00:00
Marcos Paulo 71e4775573 feat: migrate skills review desk to astro 2026-09-05 16:55:40 +00:00
Marcos Paulo 6119abfa32 feat(content): add chapters entries for landing + four chapter pages
Fill the chapters collection that task 04 defined and tasks 05/06 left
empty. Five entries (landing, summary, models, agents, skills), each
with both en and pt locales on every localized field.

Landing and summary carry the six-card route map with non-uniform CTAs
(four "Open chapter →", one "Open lab →", one "Open desk →"); the
CTA text travels as cards[].cta and the destination as cards[].href,
both added in the schema change that landed first.

Models / agents / skills carry their hero + cards + sections + steps,
including the highlighted rule panels (ROUTING RULE / MAIN /
ORCHESTRATOR / package-anatomy hint) as section-level panelLabel /
panelCode / panelHint.

Strings copied verbatim from the existing HTML files (index.html and
the four chapter pages). Tasks 12 and 13 own the page migration;
this commit is data only.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-05 16:48:30 +00:00
Marcos Paulo 2bd96d1f8c fix(tools): ignore hands-on fixtures in prettier
.preprettierignore already excluded public/hands-on but not the root
hands-on/ that verify.mjs reads from. Both are lab fixtures that must
ship byte-identical and must not be reformatted by a future `pnpm
format`. ESLint and Stylelint already ignored both paths; align
Prettier.

Refs task 17.
2026-09-05 16:47:04 +00:00