Historical Context — ve-project (v1)
This playbook describes how to pick the next migration slice for the first Vanilla Extract sub-project (
ve-project). It is preserved here for historical context.The current preferred approach is described in
docs/ve-architecture.mdand is implemented inve-project2/. Seedocs/ve-project1-docs-index.mdfor an index of all v1 historical docs.
Purpose: quickly decide the next migration slice without re-researching theme/family status.
Use this playbook when choosing the next VE runtime-contract task for non-Bootstrap themes (sketchy, cerulean, quartz, others).
ve-project/src/themes/runtime/registry.ts
- Declares implemented theme runtime contracts and
availableFamiliesper theme.
ve-project/src/themes/runtime/route-families.ts
- Declares required family sets per route.
- Runtime coverage command (no browser, no screenshots):
node scripts/capture-leaf-screenshots.mjs --ve1-runtime-missing-only --theme=<theme-list>
Policy: use only --ve1-runtime-missing-only for planning updates. Do not use --ve1-runtime-missing-leafs unless route-level detail is needed for a specific family.
- Run runtime coverage for unfinished themes.
node scripts/capture-leaf-screenshots.mjs --ve1-runtime-missing-only --theme=sketchy,cerulean,quartz- Pick the unfinished theme with the highest progress.
- Highest progress = smallest
missing N family/familiesvalue. - Tie-breaker = smallest impacted-route span (
across X/Y selected routes).
- Inside that theme, pick the next family by impact.
- Choose the missing family with the largest route count in the report:
- <family> (<n> route(s))
- If route detail is needed for implementation scoping, run:
node scripts/capture-leaf-screenshots.mjs --ve1-runtime-missing-leafs --theme=<chosen-theme>- After implementing that family, verify progress reduction:
pnpm ve:build
node scripts/capture-leaf-screenshots.mjs --ve1-runtime-missing-only --theme=<chosen-theme>Expected result: missing family count decreases (or impacted route count decreases for the selected family).
- Record the decision and result in:
docs/ve-theme-selection-changelog.md
Use this section after you choose <chosen-theme> and <chosen-family> from the runtime report.
For any non-Bootstrap theme (sketchy, cerulean, quartz, etc.), do not satisfy family conversion by re-exporting Bootstrap runtime classes or Bootstrap theme style modules.
Allowed sharing:
- Shared contract variable names and types from
ve-project/src/theme-contract/**.
Not allowed:
export const <themeX>... = bootstrap...runtime re-exports.- Importing Bootstrap theme family runtime objects as the non-Bootstrap family implementation.
Required approach:
- Implement theme-local VE classes under
ve-project/src/themes/<chosen-theme>/**using extracted CSS fromscreenshots/<chosen-theme>/**/style.css. - Export runtime classes from those theme-local files.
A family is considered converted for a theme only when all of the following are true:
- VE classes exist for that family under the theme with visual-parity intent.
- A runtime contract file exports the family runtime classes for that theme.
ve-project/src/themes/runtime/registry.tsincludes the family in both:
contractsfor the theme definitionavailableFamiliesfor the theme definition
- Runtime coverage (
--ve1-runtime-missing-only) no longer reports that family as missing for the theme.
- Baseline family implementation in Bootstrap VE theme:
ve-project/src/themes/bootstrap/**
- Route-level extracted CSS from screenshots for target theme/family:
screenshots/<chosen-theme>/<route>/<state>/style.css
- Runtime requirements:
ve-project/src/themes/runtime/route-families.ts
- Visual parity strategy (required): complete theme-specific VE classes for the full family behavior and expose them via runtime.
Important: implementation must target visual parity using theme-local files. Bootstrap family runtime/style re-exports are not permitted.
- Create or update family VE class files for
<chosen-theme>.
- Typical location pattern:
ve-project/src/themes/<chosen-theme>/ui/<family>/*.css.ts- For non-
uifamilies: ve-project/src/themes/<chosen-theme>/<family>/*.css.ts- Translate needed selectors and declarations from extracted CSS into VE class exports used by runtime.
- Create family runtime file for
<chosen-theme>.
- Typical location pattern:
ve-project/src/themes/<chosen-theme>/ui/<family>/runtime.ts- Or:
ve-project/src/themes/<chosen-theme>/<family>/runtime.ts- Export a
<theme><Family>RuntimeClassesobject matching the family contract shape.
- Register the family in runtime registry.
- Update
ve-project/src/themes/runtime/registry.ts: - Import
<theme><Family>RuntimeClasses. - Add family under
<theme>ThemeDefinition.contracts. - Add family string to
<theme>ThemeDefinition.availableFamilies.
- Keep VE architecture constraints intact.
- In
*.css.ts, do not use quoted raw custom-property keys like'--bs-*'. - Use
createVar()contract vars fromve-project/src/theme-contract/**and reference imported vars. - In route TSX, keep static classes limited to
bd-exampleandpwhook-*; move other styling into VE classes.
- Validate compile and runtime coverage.
pnpm ve:build
node scripts/capture-leaf-screenshots.mjs --ve1-runtime-missing-only --theme=<chosen-theme>- Confirm expected delta.
- Family count should decrease by at least 1, or impacted routes for the targeted family should decrease.
- Record result in changelog.
docs/ve-theme-selection-changelog.md
Use this only when you need leaf-route detail to stage implementation order:
node scripts/capture-leaf-screenshots.mjs --ve1-runtime-missing-leafs --theme=<chosen-theme>- Build passes.
- Runtime report no longer lists
<chosen-family>as missing for<chosen-theme>. - Changelog entry includes:
- chosen theme/family
- visual parity implementation summary
- verification command output summary
- remaining risk/pending work
After sketchy, cerulean, and quartz are fully converted (no missing families for selected routes), continue verification with the remaining known theme slugs:
britecosmocyborgdarklyflatlyjournalliteralumenluxmateriamintymorphpulsesandstonesimplexslatesolarspacelabsuperherounitedvaporyetizephyr
Run them as the next verification batch:
node scripts/capture-leaf-screenshots.mjs --ve1-runtime-missing-only --theme=brite,cosmo,cyborg,darkly,flatly,journal,litera,lumen,lux,materia,minty,morph,pulse,sandstone,simplex,slate,solar,spacelab,superhero,united,vapor,yeti,zephyrApply the same decision rule: pick the most-progressed unfinished theme first, then its highest-impact missing family.
At each planning checkpoint:
- Run one runtime coverage command for all unfinished themes.
- Choose the theme with the smallest missing-family count.
- Choose that theme's largest-route missing family.
- Implement, verify count reduction, update changelog.
This keeps work focused on the smallest remaining gap while maximizing route-impact reduction per family migration.