@motion-proto/live-tokens 0.73.0 → 0.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.claude/skills/live-tokens-build-page/SKILL.md +2 -2
  2. package/.claude/skills/live-tokens-check-compliance/SKILL.md +2 -2
  3. package/.claude/skills/live-tokens-create-component/SKILL.md +4 -4
  4. package/.claude/skills/live-tokens-create-theme/SKILL.md +80 -0
  5. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +94 -0
  6. package/.claude/skills/live-tokens-set-colors/SKILL.md +140 -0
  7. package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +80 -0
  8. package/.claude/skills/{live-tokens-adjust-geometry → live-tokens-set-geometry}/SKILL.md +12 -7
  9. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +61 -0
  10. package/.claude/skills/{live-tokens-pair-fonts → live-tokens-set-type}/SKILL.md +18 -15
  11. package/.claude/skills/live-tokens-set-type/references/type-anchors.md +60 -0
  12. package/CHANGELOG.md +91 -0
  13. package/README.md +24 -15
  14. package/bin/check-page.mjs +3 -3
  15. package/bin/cli.mjs +92 -55
  16. package/bin/lib/liveState.mjs +110 -0
  17. package/bin/save-theme.mjs +177 -0
  18. package/bin/set-colors.mjs +191 -0
  19. package/bin/{adjust.mjs → set-geometry.mjs} +18 -50
  20. package/bin/{set-fonts.mjs → set-type.mjs} +21 -55
  21. package/dist-plugin/{chunk-RIXO2E55.js → chunk-7VRTBGJT.js} +1 -1
  22. package/dist-plugin/{chunk-YLCOIGQC.js → chunk-V3YF6CGT.js} +56 -2
  23. package/dist-plugin/index.cjs +58 -3
  24. package/dist-plugin/index.js +11 -11
  25. package/dist-plugin/migrateData/index.cjs +56 -1
  26. package/dist-plugin/migrateData/index.js +2 -2
  27. package/dist-plugin/{generateColorsAndType → setColors}/index.cjs +1109 -1071
  28. package/dist-plugin/{generateColorsAndType → setColors}/index.d.cts +33 -24
  29. package/dist-plugin/{generateColorsAndType → setColors}/index.d.ts +33 -24
  30. package/dist-plugin/{generateColorsAndType → setColors}/index.js +45 -63
  31. package/dist-plugin/{adjust → setGeometry}/index.cjs +60 -5
  32. package/dist-plugin/{adjust → setGeometry}/index.d.cts +1 -1
  33. package/dist-plugin/{adjust → setGeometry}/index.d.ts +1 -1
  34. package/dist-plugin/{adjust → setGeometry}/index.js +1 -1
  35. package/dist-plugin/{fontPairing → setType}/index.cjs +4 -4
  36. package/dist-plugin/{fontPairing → setType}/index.d.cts +1 -1
  37. package/dist-plugin/{fontPairing → setType}/index.d.ts +1 -1
  38. package/dist-plugin/{themeTypes-DSV3Zisf.d.cts → themeTypes-BxRtuN5V.d.cts} +1 -1
  39. package/dist-plugin/{themeTypes-DSV3Zisf.d.ts → themeTypes-BxRtuN5V.d.ts} +1 -1
  40. package/package.json +2 -1
  41. package/src/editor/core/themes/{generateColorsAndType.ts → buildColors.ts} +82 -96
  42. package/src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts +62 -0
  43. package/src/editor/core/themes/migrations/index.ts +2 -0
  44. package/src/editor/docs/content/themes-workflow.md +2 -2
  45. package/src/editor/docs/content.generated.ts +1 -1
  46. package/src/editor/overlay/LiveEditorOverlay.svelte +519 -28
  47. package/src/editor/skill-atlas/SkillAtlas.svelte +2 -2
  48. package/src/editor/skill-atlas/skillSources.generated.ts +19 -15
  49. package/src/editor/skill-atlas/skillTrees.ts +785 -632
  50. package/src/live-tokens/data/colors-and-type/autumn.json +1 -37
  51. package/src/live-tokens/data/colors-and-type/default.json +1 -37
  52. package/src/live-tokens/data/colors-and-type/halloween.json +1 -37
  53. package/src/live-tokens/data/colors-and-type/midnight-study.json +1 -37
  54. package/src/live-tokens/data/colors-and-type/ocean.json +1 -37
  55. package/src/live-tokens/data/colors-and-type/royal-velvet.json +1 -37
  56. package/src/live-tokens/data/colors-and-type/sketchy.json +1 -37
  57. package/src/live-tokens/data/colors-and-type/spring-meadow.json +1 -37
  58. package/src/live-tokens/data/colors-and-type/sunset.json +1 -37
  59. package/src/live-tokens/data/themes/autumn.json +1 -37
  60. package/src/live-tokens/data/themes/halloween.json +1 -37
  61. package/src/live-tokens/data/themes/midnight-study.json +1 -37
  62. package/src/live-tokens/data/themes/ocean.json +1 -37
  63. package/src/live-tokens/data/themes/royal-velvet.json +1 -37
  64. package/src/live-tokens/data/themes/sketchy.json +1 -37
  65. package/src/live-tokens/data/themes/spring-meadow.json +1 -37
  66. package/src/live-tokens/data/themes/sunset.json +1 -37
  67. package/src/live-tokens/data/tokens.generated.css +0 -36
  68. package/.claude/skills/live-tokens-generate-theme/SKILL.md +0 -156
  69. package/.claude/skills/live-tokens-generate-theme/references/mood-vocabulary.md +0 -43
  70. package/.claude/skills/live-tokens-generate-theme/references/named-themes.md +0 -18
  71. package/.claude/skills/live-tokens-generate-theme/references/style-vocabulary.md +0 -35
  72. package/bin/generate-theme.mjs +0 -260
  73. /package/dist-plugin/{fontPairing → setType}/index.js +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: live-tokens-build-page
3
- description: Apply the @motion-proto/live-tokens project conventions when building a page: shipped components, theme tokens over hex/pixel literals, dynamic route mounting, per-page site.css. Use when the user asks to build, create, lay out, or rearrange a page, route, hero, landing page, dashboard, settings screen, pricing page, or a tool screen with a stage and controls; add a route; place an existing component on a page; assemble a screen from the catalogue; or says the layout, label sizes, or control sizes of a page are off. For component choice see live-tokens-pick-component; for a brand-new component, live-tokens-create-component; for look and feel mid-build, live-tokens-generate-theme or live-tokens-adjust-geometry.
3
+ description: Apply the @motion-proto/live-tokens project conventions when building a page: shipped components, theme tokens over hex/pixel literals, dynamic route mounting, per-page site.css. Use when the user asks to build, create, lay out, or rearrange a page, route, hero, landing page, dashboard, settings screen, pricing page, or a tool screen with a stage and controls; add a route; place an existing component on a page; assemble a screen from the catalogue; or says the layout, label sizes, or control sizes of a page are off. For component choice see live-tokens-pick-component; for a brand-new component, live-tokens-create-component; for look and feel mid-build, live-tokens-create-theme or live-tokens-set-geometry.
4
4
  ---
5
5
 
6
6
  # Building pages in a live-tokens project
@@ -8,7 +8,7 @@ description: Apply the @motion-proto/live-tokens project conventions when buildi
8
8
  Two rules above all else:
9
9
 
10
10
  1. **Use a shipped component if one fits.** Import from `@motion-proto/live-tokens/components/<Name>.svelte`. See **live-tokens-pick-component** for the catalogue and the confusing-pair decisions. Pass only the props it declares, with variant and size values from its union: `npx live-tokens components <id>` prints them (`--json` for data), and the list includes the project's own components beside the shipped ones. A prop a component does not declare is dropped silently at runtime, and the checker reports it. Author custom markup only when nothing fits, and then consider **live-tokens-create-component** so the new piece is editable too.
11
- 2. **Use theme tokens for every value.** Every color, spacing, radius, font-size, and font-family in page CSS is a `var(--token-*)`, whether it sits in the `<style>` block, an inline `style=` attribute, or a `style:` directive. No colour literals in any notation, `white` and `rgb()` included. No px or rem in spacing, stroke, radius, or shadow: that is the geometry the theme owns and `adjust` moves. Sizing is layout, not theme: a hero's height, a max content width, or a column's minimum width stays a literal. A change in `/live-tokens/editor` should repaint your page.
11
+ 2. **Use theme tokens for every value.** Every color, spacing, radius, font-size, and font-family in page CSS is a `var(--token-*)`, whether it sits in the `<style>` block, an inline `style=` attribute, or a `style:` directive. No colour literals in any notation, `white` and `rgb()` included. No px or rem in spacing, stroke, radius, or shadow: that is the geometry the theme owns and `set-geometry` moves. Sizing is layout, not theme: a hero's height, a max content width, or a column's minimum width stays a literal. A change in `/live-tokens/editor` should repaint your page.
12
12
 
13
13
  For text, reach for a whole text style rather than assembling one: `--heading-xl` through `--heading-sm`, `--body-md`, `--body-sm`, `--editorial-xl` through `--editorial-sm`, `--eyebrow`, and `--code` each carry a `-font-family`, `-font-size`, `-font-weight`, `-line-height`, and `-letter-spacing`. A heading set from `--heading-lg-*` retypes when the theme's fonts change; one set from a raw `font-size` does not.
14
14
 
@@ -27,7 +27,7 @@ The answer to "check this project" is a report. Every fact in it comes from one
27
27
  | `usage.byPage` | Which catalogue component each page renders, and how many times | A page rendering none is either chrome or hand-rolled markup that a shipped component covers. |
28
28
  | `usage.unusedShipped` | Shipped components no page renders | Information, not a finding. |
29
29
  | `usage.customUnregistered`, `usage.customUnused` | The project's own components that are unregistered or unused | Dead or half-wired work. |
30
- | `findings.pages`, `findings.components` | Both checkers' findings by rule, under the project's severities and again under `--strict` | The errors are what fails the build today; the strict count is what a fully tokenized project would fail. |
30
+ | `findings.pages`, `findings.components` | Both checkers' findings by rule, under the project's severities and again with every warning counted as an error | The errors are what fails the build today; the strict count is what a fully tokenized project would fail. |
31
31
 
32
32
  ## Mechanical or judgement
33
33
 
@@ -42,7 +42,7 @@ A translucent overlay on an app shell, or a layout size the project owns, may be
42
42
 
43
43
  1. Migrations pending, and the one command that clears them.
44
44
  2. What fails the build now: errors by rule, with the files.
45
- 3. What `--strict` would add: warnings by rule.
45
+ 3. What the strict count adds: warnings by rule.
46
46
  4. Components: unread tokens, unregistered, undescribed.
47
47
  5. Usage: what each page renders, and what is used nowhere.
48
48
  6. Recommended fixes, in the order **live-tokens-fix-findings** would take them: migrations, then the largest group of errors, then the rest, then warnings. Mark each as mechanical or judgement.
@@ -49,7 +49,7 @@ Shipped editors live in `src/editor/component-editor/` because they are library-
49
49
  ```bash
50
50
  npx live-tokens check-component <id> --strict --json
51
51
  ```
52
- `--json` gives each finding a stable `rule` id and a line number, so work one rule at a time. `--strict` fails on warnings too, the right setting for a new component: every warning is a naming or token decision that is cheaper to make now than to migrate later. Exit code 0 is the gate. With no id it checks every component under `src/system/components`; a project scaffolded by `create` runs that as `npm run check:design` before every `vite build`.
52
+ `--json` gives each finding a stable `rule` id and a line number, so work one rule at a time. `--strict` fails on warnings too, the right setting for a new component: every warning is a naming or token decision that is cheaper to make now than to migrate later. `--off=<rule>` silences a rule for one run, which a component still being authored has no use for: the finding is a decision to make. Exit code 0 is the gate. With no id it checks every component under `src/system/components`; a project scaffolded by `create` runs that as `npm run check:design` before every `vite build`.
53
53
 
54
54
  If it rejects a suffix, do not invent a new name for the role. Find a shipped component that paints the same thing and use the name it uses: every shipped component passes this same check, so the catalogue is the worked reference.
55
55
  7. **Verify** with the checklist at the bottom of this file, then place the component on a page with **live-tokens-build-page**.
@@ -90,9 +90,9 @@ state-after-property and fails.
90
90
 
91
91
  Read `references/token-naming.md` for what each one means and when two of them
92
92
  compete. A suffix outside that list fails `check-component`. The list lives in
93
- `KIND_RULES` in the editor's `aliasKinds.ts`, which the picker, the `adjust`
94
- CLI, and `check-component` all read, so a name accepted here always has a
95
- control behind it.
93
+ `KIND_RULES` in the editor's `aliasKinds.ts`, which the picker, the
94
+ `set-geometry` CLI, and `check-component` all read, so a name accepted here
95
+ always has a control behind it.
96
96
 
97
97
  ### Rules that bite
98
98
 
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: live-tokens-create-theme
3
+ description: Create a complete live-tokens theme from a natural-language request by stating one design direction and routing a color intent, a type intent, and a geometry intent to live-tokens-set-colors, live-tokens-set-type, and live-tokens-set-geometry. Use whenever the user asks for a theme, look, vibe, or brand feel by mood, style, era, season, holiday, or hue; when they name only a color and want a theme around it; or when they refine a look across more than one dimension. Not for a single token (use the editor), and not for one dimension alone: color is live-tokens-set-colors, type is live-tokens-set-type, geometry is live-tokens-set-geometry.
4
+ ---
5
+
6
+ # Creating a theme from a request
7
+
8
+ A look is three decisions: color, type, and geometry. This skill reads the
9
+ **request**, the user's own words, and states one **design direction**, a line
10
+ or two that fixes all three. From it come three **intents**, one per dimension,
11
+ each naming an outcome and never a value. Each goes to the contributing skill
12
+ that owns that dimension, and their three reports come back as one **assembled
13
+ report**, so the whole look comes from one reading.
14
+
15
+ Every contributing skill writes its dimension into the unsaved buffers the app
16
+ already renders, and those three buffers are the **look**. This skill runs one
17
+ CLI of its own, `save-theme`, which turns the look into the **theme**, the
18
+ document at `themes/<slug>.json`, and opens it. Never hand-author theme JSON and
19
+ never edit the data tree directly.
20
+
21
+ ## Workflow
22
+
23
+ 1. Read the request once and state the design direction to the user: the mood, the hue family, the scheme, and the type and geometry that mood implies. It fixes enough to derive the three intents in step 3, and it names the default where the request leaves a dimension open. Keep it to a line or two. Every step below keys off it.
24
+ 2. Read `references/design-directions.md` and name the **anchor** the request matches: a feeling, an idiom, or an occasion that reference lists, each one fixing color, type, and geometry together. An idiom sets constraints and a feeling moves dials inside them, so a request matching both reads the idiom first. A request matching none takes the design direction alone.
25
+ 3. State the three intents the design direction and the anchor imply, one line each: the color intent, the type intent, and the geometry intent. Each names an outcome. Pass the anchor's name with each one, because every contributing skill holds its own anchors for its own dimension under the same names. Never reach for an OKLCH triple, a font family, or a token on a contributing skill's behalf.
26
+ 4. Invoke **live-tokens-set-colors** with the color intent. This step never skips: a theme request names a color identity, so color is the one dimension every look fixes.
27
+ 5. Invoke **live-tokens-set-type** with the type intent. Skip only when the user asked to leave the type alone.
28
+ 6. Invoke **live-tokens-set-geometry** with the geometry intent. Skip when the geometry intent is to leave the geometry alone.
29
+ 7. Take the theme name from the design direction and run `npx live-tokens save-theme "<name>"`. It composes the three buffers into `themes/<slug>.json` and opens it, so nothing is left unsaved. `--dry-run` prints what it would write.
30
+ 8. Assemble the three reports into the assembled report: the design direction, what each contributing skill changed, the theme `save-theme` wrote, and anything one of them flagged. Tell the user to look at the running app. Offer refinements (see Refining a look).
31
+
32
+ A set of themes runs steps 4 to 7 once per theme, with `--no-activate` on every
33
+ save but the last, so each theme starts from the same live look.
34
+
35
+ ## What each contributing skill owns
36
+
37
+ Hand an outcome and the anchor's name. The mechanics stay where they are.
38
+
39
+ | Dimension | Contributing skill | It decides |
40
+ |---|---|---|
41
+ | color | live-tokens-set-colors | ten base colors, the scheme, harmony, the canvas commitment, the contrast pass |
42
+ | type | live-tokens-set-type | the two families, the form models behind them, the weights |
43
+ | geometry | live-tokens-set-geometry | radius, padding, gap, and border-width moves, global or per component |
44
+
45
+ A dimension the request leaves open still gets an intent, taken from the anchor.
46
+ A dimension the request rules out gets no invocation at all, and the assembled
47
+ report says which.
48
+
49
+ ## Refining a look
50
+
51
+ A refinement arrives against a theme that is already open, and one adjective
52
+ usually names one dimension. Route it rather than re-reading the whole look:
53
+
54
+ | The user says | Goes to |
55
+ |---|---|
56
+ | warmer, cooler, calmer, louder, lighter, darker, moodier, more contrast | live-tokens-set-colors |
57
+ | more editorial, friendlier, more technical, a serif for headings | live-tokens-set-type |
58
+ | rounder, sharper, pill buttons, tighter, airier, thicker borders | live-tokens-set-geometry |
59
+
60
+ Keep this skill for a refinement that spans dimensions ("make it feel more
61
+ serious"), or one that names no dimension at all. State a new design direction
62
+ and route all three again.
63
+
64
+ ## Files each step writes
65
+
66
+ Color, type, and geometry each write an unsaved buffer, which the page already
67
+ runs. `save-theme` composes the three into `themes/<slug>.json` and opens it,
68
+ which clears the buffers; Adopt then ships the theme. Opening a theme never
69
+ changes what the site ships. Only Adopt, in the editor, does that. Component
70
+ aliases and gradients carry forward from the live look into the theme
71
+ `save-theme` writes; user-tuned gradients survive, stock ones rebuild from the
72
+ new families.
73
+
74
+ ## Verify
75
+
76
+ - Each contributing skill reports back, and `set-colors` exits 0 with every check passing (auto-corrected is fine).
77
+ - `save-theme` exits 0 and names the theme it wrote and opened.
78
+ - The app (dev server running) shows the whole look after a reload, and the editor's Theme panel names that theme with no unsaved marker.
79
+ - The assembled report names one design direction, and the three intents trace to it.
80
+ - To return to the previous look, load the earlier theme from the Theme panel.
@@ -0,0 +1,94 @@
1
+ # Design directions: feelings, idioms, and occasions
2
+
3
+ Read this once the request names a feeling, a design idiom, an era, a genre, a
4
+ holiday, a season, or a natural scene. Each entry places the request and gives
5
+ the direction the three intents come from.
6
+
7
+ The mechanics live with the executors. Color anchors are in
8
+ live-tokens-set-colors, type anchors in live-tokens-set-type, geometry anchors
9
+ in live-tokens-set-geometry, each keyed on the same names as the tables below.
10
+ Name the anchor when you state an intent and the sibling reads its own column.
11
+
12
+ Three axes place any request, including one no entry lists:
13
+
14
+ | Axis | Reads as | Carried by |
15
+ |---|---|---|
16
+ | Valence | pleasant against unpleasant | lightness, above everything else |
17
+ | Energy | aroused against calm | chroma, and hue distance on screen |
18
+ | Dominance | assertive against yielding | surface contrast, type weight, border weight, tightness |
19
+
20
+ An idiom sets constraints and a feeling moves dials, so a request that names
21
+ both ("cozy brutalist", "clinical Swiss") reads the idiom first and lets the
22
+ feeling move the dials inside it.
23
+
24
+ ## Feelings
25
+
26
+ Valence and energy set the quadrant, and the table runs in quadrant order:
27
+ pleasant-aroused, pleasant-calm, unpleasant-aroused, unpleasant-calm. Dominance
28
+ separates confident from gentle inside one quadrant and lives almost entirely
29
+ outside color.
30
+
31
+ | Request | Placement | Direction |
32
+ |---|---|---|
33
+ | Joyful, exuberant, energetic | pleasant, high energy | warm and bright throughout, with nothing held back |
34
+ | Playful, whimsical | pleasant, high energy, low dominance | four hue families at play, soft and generous |
35
+ | Optimistic, hopeful | pleasant, moderate energy | a cool ground lit by one warm counterpoint, like sunrise |
36
+ | Confident, bold | pleasant, high energy, high dominance | wide contrast, heavy weight, held tight |
37
+ | Serene, tranquil | pleasant, low energy | cool and quiet, with nothing loud anywhere |
38
+ | Tender, gentle, romantic | pleasant, low energy, low dominance | a soft warm ground, a narrow range, light weights |
39
+ | Cozy, comforting | pleasant, low energy | warm through and through, nothing cool on screen |
40
+ | Wistful, nostalgic, vintage, faded | pleasant, low energy | chroma withheld rather than light withheld |
41
+ | Earthy, grounded, natural | pleasant, low energy, moderate dominance | warm mineral hues, nothing synthetic |
42
+ | Clinical, sterile, precise | neutral, low energy, high dominance | an untinted ground, one cool hue, tightly set |
43
+ | Contemplative, focused | neutral, low energy | one cool hue and almost nothing else |
44
+ | Urgent, alarming | unpleasant, high energy, high dominance | a neutral ground so the alarm lands, heavy and tight |
45
+ | Tense, anxious | unpleasant, high energy | an uncomfortable ground under a pair that vibrates |
46
+ | Defiant, rebellious, loud | unpleasant, high energy, highest dominance | near-black under one acid hue, blunt everywhere |
47
+ | Melancholy, moody, sad | unpleasant, low energy | dark and cool, holding one moment of color |
48
+ | Somber, grave, mournful | unpleasant, low energy, high dominance | near-neutral dark, sharp and quiet |
49
+ | Ominous, dramatic, haunted | unpleasant, low energy, high dominance | dark with one hot accent and real atmosphere |
50
+ | Austere, severe, cold | unpleasant, lowest energy, highest dominance | monochrome at one extreme of lightness |
51
+
52
+ ## Idioms, eras, and genres
53
+
54
+ The table runs modernist, digital, quiet, print, expressive.
55
+
56
+ | Request | Placement | Direction |
57
+ |---|---|---|
58
+ | Swiss, International | neutral, low energy, high dominance | one hue on a near-white ground, rational, tight |
59
+ | Bauhaus | pleasant, high energy, high dominance | primaries at full commitment on paper, geometric, square but for the circle |
60
+ | Mid-century modern | pleasant, moderate energy | warm muted mid-tones, soft and open, no borders |
61
+ | Art deco, opulent, luxurious | pleasant, low energy, high dominance | dark with one metal, high-contrast type, sharp |
62
+ | Terminal, phosphor | neutral, moderate energy, high dominance | one phosphor hue on near-black, mono, bordered |
63
+ | Cyberpunk, neon noir, futuristic | unpleasant, high energy, high dominance | dark with two neons and a glow, wide type, sharp |
64
+ | Vaporwave | pleasant, moderate energy, low dominance | light sunset pastels with a gradient, retro display, soft |
65
+ | Y2K, bubble | pleasant, high energy | a chrome ground under electric color, geometric, pills |
66
+ | Blueprint | neutral, low energy, high dominance | a drafting ground with pale rules, technical type, gridded |
67
+ | Scandinavian, hygge | pleasant, low energy, low dominance | a chalk ground and muted naturals, soft and open |
68
+ | Japandi, wabi-sabi | pleasant, lowest energy | unbleached paper, near-monochrome, generous space, no borders |
69
+ | Cottagecore, botanical | pleasant, low energy, low dominance | warm cream and garden hues, serif display, soft |
70
+ | Editorial, magazine | neutral, low energy, high dominance | paper and ink with one strong hue, carried by rules |
71
+ | Newsprint, broadsheet | neutral, low energy | grey-warm paper under near-black ink, serif throughout, tight |
72
+ | Risograph, zine | pleasant, high energy, high dominance | two flat spot inks on paper, expressive display, heavy rules |
73
+ | Corporate, professional, trustworthy | pleasant, low energy | cool near-white with navy and teal, conventional everywhere |
74
+ | Brutalist | unpleasant, high energy, highest dominance | a pure ground, one alarming hue, heavy type, thick borders |
75
+ | Memphis, postmodern | pleasant, highest energy | a pastel ground under four hue families, shapes set against each other |
76
+ | Industrial, workshop, gritty | neutral, moderate energy, high dominance | concrete and steel with safety orange, condensed type, thick borders |
77
+
78
+ ## Occasions
79
+
80
+ An occasion fixes color only, so its type and geometry intents come from the
81
+ feeling it implies or from the generic tables in the sibling skills.
82
+
83
+ Every occasion is a statement request: the named color goes on the ground
84
+ rather than only on the buttons.
85
+
86
+ | Request | Direction |
87
+ |---|---|
88
+ | Christmas | red and green with gold, one of the two owning the ground |
89
+ | Halloween | pumpkin, violet, and poison green, dark either way |
90
+ | St. Patrick's | green with gold over a pale ground |
91
+ | Ocean | blues held to one narrow band |
92
+ | Sunset | a hue sweep through red, falling in lightness |
93
+ | Autumn | parchment under rust, gold, and moss |
94
+ | Spring | pastels, greens and pinks over a mint ground |
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: live-tokens-set-colors
3
+ description: Set a live-tokens theme's color from a color intent: ten OKLCH base colors, a light or dark scheme, and an AA-gated contrast pass, written into the unsaved color buffer the app already renders. Use whenever the user asks for a palette, colors, or hues by mood, style, era, season, holiday, or hue; when they name only a color; or when they refine the color of a look: warmer, cooler, calmer, louder, lighter, darker, moodier, more contrast. Also invoked by live-tokens-create-theme, which supplies the color intent for a whole look. Changes color only, never fonts or geometry. Not for a single token (use the editor), and not for a whole look (see live-tokens-create-theme).
4
+ ---
5
+
6
+ # Setting a theme's colors
7
+
8
+ You choose ten base colors; the CLI builds every ramp from them, enforces AA
9
+ contrast on the derived text tokens, writes the result into the unsaved colors
10
+ buffer the app already renders, and prints a contrast report. Never hand-author
11
+ theme JSON and never edit the data tree directly.
12
+
13
+ The run replaces the color state in that buffer and carries everything else
14
+ forward, so it composes with type and geometry in any order. Saving the open
15
+ theme in the editor, or running `save-theme`, turns the live look into a theme.
16
+
17
+ ## Workflow
18
+
19
+ 1. Read the color intent. When it names an anchor (a feeling, an idiom, or an occasion), read `references/color-anchors.md` for that entry; it overrides the generic bands below. Say which anchor you took.
20
+ 2. Translate the intent into ten base colors using the framework below and write `scratch/<slug>-base-colors.json`. Nothing else records the base colors, so this file is the only copy; one per slug is what makes the refinement pass cheap.
21
+ 3. Run `npx live-tokens set-colors scratch/<slug>-base-colors.json`. It writes the color state into the unsaved buffer the page already runs, and prints a contrast report.
22
+ 4. Read the report. Exit 0 passes, and auto-corrected values count as passing. Exit 1 means the base colors are unworkable; each failure line names the base color to change, usually by raising its lightness or cutting its chroma. Fix the base color file and re-run.
23
+ 5. Report back in a line: the scheme, the hue families on screen, the canvas commitment level, and anything the report auto-corrected.
24
+
25
+ Flags: `--dry-run` prints the contrast report without writing.
26
+
27
+ ## The base color file
28
+
29
+ ```json
30
+ {
31
+ "scheme": "light",
32
+ "baseColors": {
33
+ "Brand": { "l": 0.62, "c": 0.17, "h": 145 },
34
+ "Accent": { "l": 0.80, "c": 0.15, "h": 95 },
35
+ "Special": { "l": 0.60, "c": 0.19, "h": 300 },
36
+ "Canvas": { "l": 0.93, "c": 0.04, "h": 120 },
37
+ "Neutral": { "l": 0.55, "c": 0.012, "h": 140 },
38
+ "Alternate": { "l": 0.58, "c": 0.009, "h": 60 },
39
+ "Info": { "l": 0.60, "c": 0.15, "h": 255 },
40
+ "Success": { "l": 0.60, "c": 0.16, "h": 150 },
41
+ "Warning": { "l": 0.75, "c": 0.15, "h": 85 },
42
+ "Danger": { "l": 0.58, "c": 0.20, "h": 25 }
43
+ }
44
+ }
45
+ ```
46
+
47
+ A base color is the one color a palette's whole ramp derives from. All 10 are required, and each may be given as a `"#rrggbb"` string instead. OKLCH: `l` is 0 to 1 lightness, `c` is chroma (0 grey, about 0.37 max), `h` is hue in degrees. The file names no theme: the slug in its own path is the theme name live-tokens-create-theme intends, or any label when this skill runs alone. `canvasGradient` is an optional boolean, see below.
48
+
49
+ Roles: **Brand** is the dominant chromatic identity; **Accent** the supporting color; **Special** the rare expressive tertiary; **Canvas** is the page background verbatim; **Neutral** drives neutral surfaces and body text; **Alternate** is the second near-grey family; the four statuses are conventional signals.
50
+
51
+ ## Chroma budget: color is inversely proportional to area
52
+
53
+ | Tier | Palettes | Chroma |
54
+ |---|---|---|
55
+ | Ground (about 60% of every screen) | Neutral, Alternate | C 0.008 to 0.02 |
56
+ | Canvas (the largest single area) | Canvas | Per the commitment levels below, C 0.02 to 0.14 |
57
+ | Dominant chromatic (about 30%) | Brand | C 0.10 to 0.20 |
58
+ | Garnish (about 10%) | Accent, Special | may exceed Brand; at most one at the gamut cap for its hue (see Gamut guardrails) |
59
+ | Conditional | Info, Success, Warning, Danger | C 0.12 to 0.19 |
60
+
61
+ A good theme reads as 3 or 4 hue families on screen, never 10. Neutral and Alternate stay near-grey but tinted toward the theme (Neutral near Brand's hue; Alternate offset 15 to 60 degrees, or a warm/cool counterpoint), never pure C = 0 unless an anchor calls for it.
62
+
63
+ ## Per-role bands
64
+
65
+ | Base color | Light scheme | Dark scheme | Hue |
66
+ |---|---|---|---|
67
+ | Canvas | L 0.92 to 0.98, C 0.02 to 0.06 | L 0.15 to 0.28, C 0.01 to 0.05 | Brand's hue or its harmony slot |
68
+ | Neutral, Alternate | L about 0.55, C 0.008 to 0.02 | same | per the chroma budget |
69
+ | Brand | L 0.45 to 0.62, C 0.12 to 0.20 | L 0.70 to 0.83, C cut by a third | the request's identity hue |
70
+ | Accent | harmony slot, or at least 0.25 L from Brand when the mode collapses hue distance | lighten and desaturate like Brand | harmony slot |
71
+ | Special | most expressive; default Brand hue +60 at about 65% of Brand's C | same transform | harmony slot |
72
+ | Info | shared status L (0.55 to 0.65 light) | lighten like Brand | H 230 to 260 |
73
+ | Success | shared status L | same | H 140 to 155 |
74
+ | Warning | L 0.75 or higher (vivid yellow must be light) | same | H 70 to 90 |
75
+ | Danger | shared status L, C 0.15 to 0.20 | same | H 20 to 30 |
76
+
77
+ **The canvas carries the theme's identity, so commit to it.** The page background is the largest area on screen and the strongest difference between themes; a timid canvas makes every theme look the same. Below C 0.015 at L 0.95 a tint is imperceptible, which makes near-white a deliberate choice for clean or minimal intents and never the default. Three levels of commitment:
78
+
79
+ 1. *Tinted paper* (most UI intents): C 0.02 to 0.06, with L down to 0.92 where the hue needs room.
80
+ 2. *Colored ground* (expressive intents): L 0.85 to 0.92 at C 0.05 to 0.10. The page is unmistakably mint, parchment, sky.
81
+ 3. *Full-color ground* (holiday and statement intents): the canvas is the theme color, like a red Christmas page with green and gold on it. Keep canvas L at or below 0.48 or at or above 0.85 so text has somewhere to go; the contrast gate enforces legibility either way.
82
+
83
+ Also:
84
+
85
+ - Blue tints cap very low at high L (H 264 at L 0.95 barely reaches C 0.03): lower L for a blue canvas rather than fighting the ceiling. Yellow, green, and cream tint generously at high L.
86
+ - When generating a set of themes, make the canvases pairwise distinct in hue or in L. Two light themes both near (0.97, 0.01) read as one theme with different buttons.
87
+ - A dark scheme transforms every base color: each chromatic one lightens to L 0.75 to 0.85 and drops about a third of its chroma, because saturated color vibrates on dark grounds.
88
+ - Equal lightness reads as equal weight: give the four statuses one shared L, and do the same for Brand and Accent when they should balance.
89
+ - Status hues never rotate with the harmony; only their L and C adapt to the mood.
90
+
91
+ ## Mood dials
92
+
93
+ Pleasantness rises with lightness (strongly) and saturation (weakly); energy rises with saturation; drama rises with dark plus saturated. Dominance, the third axis, is carried by surface contrast, type weight, and tightness rather than by color at all.
94
+
95
+ That is the whole mechanism, and one dial moves without a reference: warm is hues 20 to 110 plus pink 290 to 360, cool is 140 to 290. For an intent that names a feeling, read `references/color-anchors.md` instead of guessing the dial settings.
96
+
97
+ Avoid mid-lightness yellow-green (H 100 to 120 at L 0.5 to 0.7, C about 0.1) unless the intent asks for olive or toxic.
98
+
99
+ ## Gamut guardrails
100
+
101
+ The engine clamps to gamut regardless; these keep the intent achievable.
102
+
103
+ - Dark saturated yellow does not exist: H 90 at L 0.4 caps at C 0.08 and reads olive. Vivid yellow needs L 0.8 or more. Brown is dark low-chroma orange.
104
+ - Vivid light blue does not exist: H 264 at L 0.9 caps at C 0.05. Rich blue lives at L 0.40 to 0.55.
105
+ - Teal and sky cap at C 0.15.
106
+ - Peak chroma anchors: red H20 C 0.25 at L 0.63; orange H60 C 0.18 at L 0.76; yellow H90 C 0.18 at L 0.86; green H140 C 0.28 at L 0.88; blue H264 C 0.28 at L 0.50; magenta H320 C 0.31 at L 0.65.
107
+
108
+ ## Harmony
109
+
110
+ Hue offsets from Brand: complementary +180; split-complementary +150/+210; triadic +120/+240; tetradic +60/+180/+240; square +90 steps; compound +30/+180/+210; analogous plus or minus 30; monochromatic same hue.
111
+
112
+ - A vague or single-adjective intent takes monochromatic or analogous, with Accent separated from Brand by L and C rather than hue. The polished-UI default: Accent at Brand's hue and about 45% of its chroma, Special at +60 and about 65%.
113
+ - An intent naming two colors: measure their hue gap and pick the matching mode (green plus gold is 60 to 90 degrees, so analogous or compound).
114
+ - Drama or maximum contrast: complementary, triadic, or tetradic, and then tone one side down, since max-chroma text on a near-black ground vibrates.
115
+
116
+ ## Canvas sky and shadows
117
+
118
+ `"canvasGradient": true` renders the page background as a vertical gradient from the Canvas ramp. Default off. Turn it on only when the intent evokes atmosphere (sky, night, dusk, glow, underwater) or asks for a gradient outright; keep it off for crisp, flat, minimal, or corporate intents and whenever in doubt, because a sky on every theme stops meaning anything. It needs a committed canvas (level 2 or 3); at the ramp edge the engine skips it and says so. Say why it is on, in one line.
119
+
120
+ Shadow opacity derives from Canvas lightness and re-derives on every run, so there is nothing to choose. When shadows read heavy or muddy, raise the Canvas base color's L.
121
+
122
+ ## Refining the color of a theme that exists
123
+
124
+ "Warmer", "calmer", "more contrast" arrive against a theme that is already open, and the answer is a new base color file. Edit `scratch/<slug>-base-colors.json` when it is still there. When it is not, recover the base colors: `src/live-tokens/data/themes/<slug>.json` holds each one verbatim at `colorsAndType.editorConfigs.<Palette>.baseColor` as `{l, c, h}`, and the Canvas base color's lightness gives the scheme. Rebuild the base color file from those ten values, move the dial the user named, and re-run. A re-run replaces the buffer's whole color state, including palette edits made in the editor since the last run, so say so once when iterating; a Save or a `save-theme` run keeps the result.
125
+
126
+ One adjective moves one dial. Warmer and cooler rotate hue; calmer and louder move chroma; lighter, darker, and moodier move Canvas L and the scheme; more contrast widens the L gap between Canvas and Brand and takes chroma out of the ground rather than adding it to the garnish. Leave every base color the user did not name alone, because a refinement that re-rolls the whole palette reads as a different theme and loses the thing they liked.
127
+
128
+ ## Scope
129
+
130
+ Color only. Type and geometry are untouched: `set-colors` replaces the color
131
+ state in the unsaved buffer and carries every other value in it forward. Save
132
+ the open theme in the editor, or run `save-theme`, to keep the result; Adopt
133
+ ships it.
134
+
135
+ ## Verify
136
+
137
+ - The CLI exits 0 with every check passing (auto-corrected is fine), and the report names the layer it carried the rest of the look forward from.
138
+ - The app (dev server running) shows the new palette after a reload. The editor's Theme panel marks the open theme unsaved, unless the run was a dry one or the report says the layer under the buffer, the open theme or the package default, already holds these colors.
139
+ - The canvas is committed: on screen it reads as the theme's color rather than as generic near-white.
140
+ - To revert, re-run with the previous base color file, or load the open theme again to discard the buffer.
@@ -0,0 +1,80 @@
1
+ # Color anchors: feelings, idioms, and occasions
2
+
3
+ Read this when the color intent names one of these. Entries are starting
4
+ points: apply the chroma budget, the per-role bands, and the canvas commitment
5
+ rules from SKILL.md on top of them.
6
+
7
+ An idiom sets constraints and overrides the generic defaults in SKILL.md. The
8
+ polished-UI Accent at 45% of Brand's chroma is right for a vague intent and
9
+ wrong for Bauhaus. A feeling moves dials, and moves them inside an idiom's
10
+ constraints when the intent names both.
11
+
12
+ Energy spent on the ground tier fights the contrast gate, so keep chroma on the
13
+ garnish. A low-valence, low-energy intent taken literally reads as broken
14
+ rather than sad, which is why every dark entry below holds one moment of color.
15
+
16
+ Riso, Memphis, and brutalist break the chroma budget on purpose. Break it in
17
+ the one layer the style is about and hold the rest of the ground tier down.
18
+
19
+ ## Feelings
20
+
21
+ | Anchor | Anchors (L, C, H) |
22
+ |---|---|
23
+ | Joyful, exuberant, energetic | butter canvas (0.95, 0.05, 90), Brand (0.80, 0.17, 75), coral Accent (0.72, 0.18, 20), green Special (0.75, 0.16, 145); analogous warm. Yellow stays yellow only above L 0.80 |
24
+ | Playful, whimsical | tinted canvas (0.93, 0.05, 330), Special at full chroma; tetradic, the rare request that wants four hue families |
25
+ | Optimistic, hopeful | sky canvas (0.94, 0.03, 220), Brand (0.62, 0.14, 200), warm yellow Accent (0.85, 0.14, 90); complementary across the warm/cool line, which reads as sunrise rather than sky |
26
+ | Confident, bold | canvas (0.90, 0.07, 250), Brand C 0.18 at L 0.55, wide L range between surfaces. High dominance is the point |
27
+ | Serene, tranquil | cool canvas (0.95, 0.03, 200), nothing above C 0.08, analogous 160 to 240 |
28
+ | Tender, gentle, romantic | blush canvas (0.95, 0.03, 20), rose Brand (0.70, 0.08, 10), sage Accent (0.68, 0.06, 150); narrow L range |
29
+ | Cozy, comforting | amber-cream canvas (0.92, 0.05, 75), rust Brand (0.55, 0.12, 40), neutrals at H 60; nothing cool on screen |
30
+ | Wistful, nostalgic, vintage, faded | faded canvas (0.92, 0.03, 70), every chromatic base color capped at C 0.10, hues warm and close. The feeling is chroma withheld, not darkness |
31
+ | Earthy, grounded, natural | canvas (0.90, 0.05, 90) at commitment level 2, hues 30 to 140 at C 0.06 to 0.14, neutrals H 60 to 80; no magenta, no cyan, nothing over C 0.16 |
32
+ | Clinical, sterile, precise | near-white canvas at C 0.01, the one request an untinted ground suits; one cool Brand 200 to 260 at C 0.10; statuses carry the only other color |
33
+ | Contemplative, focused | canvas (0.94, 0.015, 250) or its dark twin (0.20, 0.02, 250), one cool Brand at C 0.10, almost no other hue |
34
+ | Urgent, alarming | ground held near-neutral so the alarm lands, red Brand (0.58, 0.22, 27) given real area, Warning and Danger on one shared L |
35
+ | Tense, anxious | an uncomfortable ground, (0.88, 0.04, 105) light or (0.22, 0.03, 280) dark, plus a near-complementary pair that vibrates with one side toned down |
36
+ | Defiant, rebellious, loud | near-black canvas (0.15, 0.01, 0), one acid hue (0.85, 0.20, 120), nothing else chromatic |
37
+ | Melancholy, moody, sad | dark; canvas (0.22, 0.03, 250), chromatic base colors C 0.06 to 0.10 at L 0.72 to 0.80, blue through violet, with Accent held at C 0.14 as the moment of color |
38
+ | Somber, grave, mournful | near-neutral dark canvas (0.18, 0.01, 260), one desaturated Brand, gradient off |
39
+ | Ominous, dramatic, haunted | dark canvas (0.15, 0.04, 300), one hot accent (0.75, 0.16, 30) used sparingly, canvasGradient on |
40
+ | Austere, severe, cold | monochrome; canvas at either L extreme at C 0.01 or below, one low-chroma Brand, muted statuses |
41
+
42
+ ## Idioms, eras, and genres
43
+
44
+ | Anchor | Anchors (L, C, H) |
45
+ |---|---|
46
+ | Swiss, International | near-white canvas (0.97, 0.01, 0), or true black for the poster reading; one red Brand (0.55, 0.22, 27) as the only hue on screen; Neutral at C 0.005, untinted on purpose; monochromatic |
47
+ | Bauhaus | paper canvas (0.95, 0.02, 85) under primaries at full commitment: red (0.58, 0.21, 27), blue (0.48, 0.20, 264), yellow (0.86, 0.17, 90); triadic |
48
+ | Mid-century modern | canvas (0.90, 0.05, 75), mustard (0.75, 0.13, 85), teal (0.55, 0.10, 195), burnt orange (0.60, 0.15, 45), walnut neutrals H 60; nothing over C 0.16; compound |
49
+ | Art deco, opulent, luxurious | near-black canvas (0.20, 0.02, 280), gold (0.78, 0.13, 88), jade (0.60, 0.10, 165); dark, one metallic accent, everything else grey |
50
+ | Terminal, phosphor | canvas (0.16, 0.01, 150), phosphor green Brand (0.80, 0.16, 145), amber Accent (0.80, 0.13, 80); monochromatic, dark, gradient off |
51
+ | Cyberpunk, neon noir, futuristic | canvas (0.18, 0.04, 300), magenta Brand (0.78, 0.18, 330), cyan Accent (0.82, 0.12, 200); complementary, dark, canvasGradient on for the glow |
52
+ | Vaporwave | sunset canvas (0.88, 0.06, 330), pink (0.72, 0.16, 350), cyan (0.80, 0.11, 205), lilac Special; light, gradient on |
53
+ | Y2K, bubble | chrome canvas (0.96, 0.015, 240), electric blue Brand (0.62, 0.18, 255), lime Accent (0.85, 0.17, 130) |
54
+ | Blueprint | canvas (0.35, 0.07, 245), pale rules (0.90, 0.02, 240), one warm accent (0.75, 0.14, 60); dark |
55
+ | Scandinavian, hygge | chalk canvas (0.96, 0.012, 70), sage Brand (0.60, 0.06, 150), clay Accent (0.70, 0.08, 40); nothing above C 0.10; analogous |
56
+ | Japandi, wabi-sabi | unbleached paper canvas (0.93, 0.025, 80), ink Brand (0.35, 0.02, 250), one earth Accent (0.62, 0.09, 45); near-monochrome |
57
+ | Cottagecore, botanical | cream canvas (0.94, 0.04, 85), moss (0.55, 0.10, 135), dusty rose (0.70, 0.09, 15), butter (0.85, 0.11, 95); warm analogous |
58
+ | Editorial, magazine | paper canvas (0.97, 0.015, 85), ink neutrals, one strong Brand (0.50, 0.18, 20) carried by rules and pull quotes |
59
+ | Newsprint, broadsheet | grey-warm canvas (0.91, 0.02, 80), near-black ink, nothing chromatic above C 0.10 |
60
+ | Risograph, zine | paper canvas (0.94, 0.03, 80) with two flat spot inks, fluoro pink (0.68, 0.22, 5) and blue (0.52, 0.18, 260); complementary, no midtones between them |
61
+ | Corporate, professional, trustworthy | canvas (0.97, 0.012, 250), navy Brand (0.48, 0.12, 255), teal Accent (0.60, 0.09, 195), conventional statuses |
62
+ | Brutalist | pure canvas, (0.98, 0, 0) or (0.15, 0, 0), with Neutral at C 0, untinted because that is the point; one alarming Brand (0.58, 0.24, 27) |
63
+ | Memphis, postmodern | pastel canvas (0.95, 0.03, 60) carrying full-chroma primaries and a hot pink Special (0.70, 0.20, 350); tetradic or square, four hue families on purpose |
64
+ | Industrial, workshop, gritty | concrete canvas (0.88, 0.008, 250), or (0.22, 0.01, 250) dark, safety orange Brand (0.68, 0.18, 50), steel neutrals |
65
+
66
+ ## Occasions
67
+
68
+ An occasion is a statement request. Default to canvas commitment level 2 or 3,
69
+ never cream, and put the named color on the ground rather than only on the
70
+ buttons.
71
+
72
+ | Anchor | Anchors (L, C, H) | Strongest form |
73
+ |---|---|---|
74
+ | Christmas | red (0.53, 0.21, 22), green (0.46, 0.11, 155), gold (0.77, 0.14, 91) | red canvas (0.42, 0.14, 25), green Brand, gold Accent, dark scheme. Softer: evergreen canvas (0.35, 0.07, 160) or deep cream (0.95, 0.04, 85). One of red or green owns the ground; never a 50/50 split. |
75
+ | Halloween | pumpkin (0.70, 0.20, 46), purple (0.51, 0.21, 313), poison green (0.73, 0.20, 137) | orange canvas (0.45, 0.13, 55) with violet and poison-green accents, or near-black violet canvas with pumpkin Brand. Dark scheme either way. |
76
+ | St. Patrick's | green (0.51, 0.13, 152) | green Brand, gold Accent, white or beige neutrals. |
77
+ | Ocean | deep blue (0.35, 0.08, 237), aqua (0.78, 0.12, 214) | hues held to 180 to 240. |
78
+ | Sunset | hues 90 to 320 through red | L falls 0.85 to 0.40 across the sweep. |
79
+ | Autumn | parchment canvas (0.87, 0.06, 80), rust Brand (0.55, 0.15, 40), gold Accent (0.75, 0.15, 85), moss Special (0.55, 0.10, 120) | warm brown neutrals H 50 to 70; deep red H 25 welcome. |
80
+ | Spring | pastels L 0.85 to 0.95, C 0.04 to 0.10 | greens 130 to 150, pinks 0 to 20, mint canvas. |
@@ -1,6 +1,6 @@
1
1
  ---
2
- name: live-tokens-adjust-geometry
3
- description: Adjust corner radius, padding, gap, and border width across live-tokens components by moving each token alias along the shipped scales. Use when the user asks for pill or capsule buttons; rounded, rounder, sharp, sharper, square, softer, or harder corners; thicker or thinner borders; or density: space it out, tighter, denser, more compact, airier, more breathing room. Also invoked by live-tokens-generate-theme for the geometry half of a whole look. Changes shape and space aliases per component, never color, fonts, or tokens.css. Not for editing a single token (use the editor) or for color (see live-tokens-generate-theme).
2
+ name: live-tokens-set-geometry
3
+ description: Adjust corner radius, padding, gap, and border width across live-tokens components by moving each token alias along the shipped scales. Use when the user asks for pill or capsule buttons; rounded, rounder, sharp, sharper, square, softer, or harder corners; thicker or thinner borders; or density: space it out, tighter, denser, more compact, airier, more breathing room. Also invoked by live-tokens-create-theme, which supplies the geometry intent for a whole look. Changes shape and space aliases per component, never color, fonts, or tokens.css. Not for editing a single token (use the editor) or for a whole look (see live-tokens-create-theme).
4
4
  ---
5
5
 
6
6
  # Adjusting geometry
@@ -9,10 +9,11 @@ You translate the request into a small ops file; the CLI resolves each matching
9
9
 
10
10
  ## Workflow
11
11
 
12
- 1. Write the ops file to `scratch/adjust-ops.json`.
13
- 2. Run `npx live-tokens adjust scratch/adjust-ops.json`. It writes `component-configs/<id>/_working.json` for every component the ops change, which is the buffer the page already runs. `--dry-run` prints the report without writing.
12
+ 1. Read the geometry intent. When it names an anchor (a feeling, an idiom, or a genre), read `references/geometry-anchors.md` for that entry; it overrides the Idioms table below. Write the ops file to `scratch/geometry-ops.json`.
13
+ 2. Run `npx live-tokens set-geometry scratch/geometry-ops.json`. It writes `component-configs/<id>/_working.json` for every component the ops change, which is the buffer the page already runs. `--dry-run` prints the report without writing.
14
14
  3. Read the report card: every changed alias old → new, plus skips (raw value, off the ladder, already at the ladder end, pill preserved). Exit 1 means the run was rejected; the message names the offending op or the missing input, so fix it and re-run. Read where the controls landed, not only that the run succeeded: a button, badge, input, or tab padding sitting at `--space-6` is on its floor, and one that also carries `--radius-full` wants a targeted lift.
15
- 4. Tell the user to reload the page before saving. The editor keeps the look in the browser and writes the buffers from that copy, so a Save in a tab that was open during the run puts the pre-run shape back and the report you just showed them becomes a lie. After the reload, offer the inverse op as the undo and say the edit is unsaved until they save the open theme.
15
+ 4. Report back in a line: every alias that moved, and any skip or clamp worth naming.
16
+ 5. Tell the user to reload the page before saving. The editor keeps the look in the browser and writes the buffers from that copy, so a Save in a tab that was open during the run puts the pre-run shape back and the report you just showed them becomes a lie. After the reload, offer the inverse op as the undo and say the edit is unsaved until they save the open theme.
16
17
 
17
18
  Each run reads the LIVE config (buffer, else the open theme, else the shipped default), so "a bit more" and "back one" compound naturally.
18
19
 
@@ -38,7 +39,9 @@ Targeted, absolute:
38
39
 
39
40
  ## Idioms
40
41
 
41
- | Request | Ops |
42
+ This table covers an intent that names no anchor. When the intent names one, `references/geometry-anchors.md` has the row and it wins.
43
+
44
+ | The intent says | Ops |
42
45
  |---|---|
43
46
  | pill, capsule | radius `set: "--radius-full"`, plus the padding the pill needs (see below) |
44
47
  | sharp, square corners | radius `set: "--radius-none"`, or `--radius-sm` for "mostly sharp" |
@@ -50,13 +53,15 @@ Targeted, absolute:
50
53
  | tighter, denser, more compact | padding and gap `shift: -1` |
51
54
  | thicker, thinner borders | border-width `shift: 1` or `-1` |
52
55
 
56
+ A whole-look intent often arrives as a direction rather than an op. Playful, friendly, or soft is rounder and a step airier, with pill buttons when the direction is warm. Luxurious, elegant, or editorial is sharper corners, airier padding, thin borders. Technical, dense, or systematic is tighter spacing, a small radius, and square corners on containers. Calm or minimal leaves geometry alone.
57
+
53
58
  Magnitude words: "slightly" or "a bit" is 1 step, unqualified is 1 to 2, "much", "way", or "really" is 2 to 3. Mood words often mean both axes: "softer" is rounder plus airier, "compact" is tighter padding plus smaller gaps.
54
59
 
55
60
  ## Controls squeeze before containers
56
61
 
57
62
  A global op spends the same number of steps everywhere, but a step costs a control far more than a container. `padding shift: -2` takes a card from a 16px inset to 10px and it is still a card. It takes a button from 8 to 4, doubled to 8px at each end, around an 18px line. The button stops reading as a button.
58
63
 
59
- So a global compaction is `shift: -1`. When the brief wants more, spend the extra steps on the containers by name (`card`, `dialog`, `panel`, `collapsiblesection`, `sidenavigation`, `table`, `codesnippet`) and leave the controls alone. Loosening is not symmetric: airier is safe globally, because nothing breaks by growing.
64
+ So a global compaction is `shift: -1`. When the request wants more, spend the extra steps on the containers by name (`card`, `dialog`, `panel`, `collapsiblesection`, `sidenavigation`, `table`, `codesnippet`) and leave the controls alone. Loosening is not symmetric: airier is safe globally, because nothing breaks by growing.
60
65
 
61
66
  A pill needs the room most. `--radius-full` bends the corner in over the first and last glyph, so a capsule wants more horizontal inset than a square-cornered control, never less. `--space-8` is the floor for a large-text pill, which is where compact Midnight Study sits; the roomier pill presets (Ocean, Sunset, Royal Velvet) run `--space-10` to `--space-12`. Pair the radius op with a padding `set` on the same target, placed after any global compaction so it wins outright:
62
67
 
@@ -0,0 +1,61 @@
1
+ # Geometry anchors: feelings, idioms, and genres
2
+
3
+ Read this when the geometry intent names one of these. An anchor overrides the
4
+ Idioms table in SKILL.md, because it is tuned to the same direction the color
5
+ came from, and a style's geometry is often targeted rather than global.
6
+
7
+ Entries are written in the ops vocabulary: "radius +2" is a radius shift of 2,
8
+ "borders +1" a border-width shift of 1, "padding +1" a padding and gap shift of
9
+ 1. A named component means a targeted op. Controls squeeze before containers,
10
+ so a compaction of more than one step still spends its extra steps on
11
+ containers by name.
12
+
13
+ An occasion (Christmas, Autumn, Ocean) fixes color only. Take its geometry from
14
+ the feeling it implies, or leave geometry alone.
15
+
16
+ ## Feelings
17
+
18
+ | Anchor | Geometry |
19
+ |---|---|
20
+ | Joyful, exuberant, energetic | radius +2, padding +1, pill buttons |
21
+ | Playful, whimsical | pill buttons, rounder cards, wide gaps |
22
+ | Optimistic, hopeful | radius +1 |
23
+ | Confident, bold | radius -1, borders +1, tight gaps |
24
+ | Serene, tranquil | soft radius, padding +1, no borders |
25
+ | Tender, gentle, romantic | rounder, hairline borders |
26
+ | Cozy, comforting | radius +1, padding +1 |
27
+ | Wistful, nostalgic, vintage, faded | unchanged, hairline rules |
28
+ | Earthy, grounded, natural | radius +1, padding +1 |
29
+ | Clinical, sterile, precise | radius sm, tight gaps, hairline borders |
30
+ | Contemplative, focused | padding +1, minimal borders |
31
+ | Urgent, alarming | radius -2, borders +2, tight padding |
32
+ | Tense, anxious | tight gaps, radius sm |
33
+ | Defiant, rebellious, loud | radius none, borders +3 |
34
+ | Melancholy, moody, sad | padding +1, hairline borders |
35
+ | Somber, grave, mournful | sharp, tight gaps, hairline rules |
36
+ | Ominous, dramatic, haunted | sharp, borders +2 |
37
+ | Austere, severe, cold | radius none, tight padding, hairline borders |
38
+
39
+ ## Idioms, eras, and genres
40
+
41
+ | Anchor | Geometry |
42
+ |---|---|
43
+ | Swiss, International | radius none, tight gaps, hairline borders |
44
+ | Bauhaus | radius none on containers, radius full on buttons alone, so the circle reads as a decision |
45
+ | Mid-century modern | radius +1 to +2, padding +1, no borders |
46
+ | Art deco, opulent, luxurious | sharp, padding +1, thin borders |
47
+ | Terminal, phosphor | radius none, tight padding, a 1px border on everything |
48
+ | Cyberpunk, neon noir, futuristic | sharp, tight gaps |
49
+ | Vaporwave | rounder, airier |
50
+ | Y2K, bubble | radius full on buttons with the padding a pill needs, generous spacing |
51
+ | Blueprint | radius none, 1px borders, tight grid |
52
+ | Scandinavian, hygge | soft radius, padding +1, hairline borders |
53
+ | Japandi, wabi-sabi | radius sm, padding +2, no borders |
54
+ | Cottagecore, botanical | rounder, airier |
55
+ | Editorial, magazine | sharp, padding +1, hairline rules |
56
+ | Newsprint, broadsheet | radius none, tight gaps, hairline rules |
57
+ | Risograph, zine | radius none, borders +2 |
58
+ | Corporate, professional, trustworthy | leave it alone |
59
+ | Brutalist | radius none, borders +2 to +3, tight padding |
60
+ | Memphis, postmodern | targeted rather than global: pill buttons against radius-none cards |
61
+ | Industrial, workshop, gritty | radius sm, thick borders, tight padding |