@motion-proto/live-tokens 0.56.1 → 0.58.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.
- package/.claude/skills/live-tokens-create-component/SKILL.md +13 -2
- package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +202 -0
- package/.claude/skills/live-tokens-pair-fonts/SKILL.md +2 -2
- package/.claude/skills/live-tokens-pick-component/SKILL.md +1 -1
- package/CHANGELOG.md +192 -0
- package/README.md +1 -1
- package/bin/cli.mjs +2 -1
- package/dist-plugin/adjust/index.cjs +1 -0
- package/dist-plugin/adjust/index.d.cts +2 -2
- package/dist-plugin/adjust/index.d.ts +2 -2
- package/dist-plugin/adjust/index.js +1 -1
- package/dist-plugin/{chunk-TKZBVIW5.js → chunk-E5QYON4L.js} +59 -2
- package/dist-plugin/{chunk-PB2JTK2H.js → chunk-LW4SR7AZ.js} +39 -6
- package/dist-plugin/{chunk-YR6GPXW2.js → chunk-XWXIMTWZ.js} +0 -5
- package/dist-plugin/{chunk-D3ZVKOR4.js → chunk-Y5CNFSSV.js} +1 -0
- package/dist-plugin/{dataPaths-DBN0RPuT.d.cts → dataPaths-CRfD1LdA.d.cts} +3 -0
- package/dist-plugin/{dataPaths-DBN0RPuT.d.ts → dataPaths-CRfD1LdA.d.ts} +3 -0
- package/dist-plugin/fontPairing/index.cjs +4 -2
- package/dist-plugin/fontPairing/index.d.cts +3 -3
- package/dist-plugin/fontPairing/index.d.ts +3 -3
- package/dist-plugin/fontPairing/index.js +4 -3
- package/dist-plugin/generateColorsAndType/index.cjs +22 -9
- package/dist-plugin/generateColorsAndType/index.d.cts +2 -2
- package/dist-plugin/generateColorsAndType/index.d.ts +2 -2
- package/dist-plugin/generateColorsAndType/index.js +8 -5
- package/dist-plugin/index.cjs +158 -9
- package/dist-plugin/index.d.cts +1 -1
- package/dist-plugin/index.d.ts +1 -1
- package/dist-plugin/index.js +71 -4
- package/dist-plugin/migrateData/index.cjs +1 -0
- package/dist-plugin/migrateData/index.d.cts +1 -1
- package/dist-plugin/migrateData/index.d.ts +1 -1
- package/dist-plugin/migrateData/index.js +1 -1
- package/dist-plugin/{themeTypes-BAqtv4XO.d.cts → themeTypes-DSV3Zisf.d.cts} +12 -1
- package/dist-plugin/{themeTypes-BAqtv4XO.d.ts → themeTypes-DSV3Zisf.d.ts} +12 -1
- package/dist-plugin/tokensCssMigrations/index.cjs +58 -1
- package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
- package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
- package/dist-plugin/tokensCssMigrations/index.js +3 -3
- package/package.json +3 -1
- package/src/editor/core/fonts/applyFontPairing.ts +3 -2
- package/src/editor/core/fonts/fontLoader.ts +1 -0
- package/src/editor/core/fonts/fontMigration.ts +31 -1
- package/src/editor/core/palettes/paletteDerivation.ts +9 -2
- package/src/editor/core/sketch/maskField.ts +385 -0
- package/src/editor/core/sketch/sketchLayer.ts +1106 -0
- package/src/editor/core/sketch/sketchPresetService.ts +65 -0
- package/src/editor/core/sketch/sketchPresets.ts +345 -0
- package/src/editor/core/sketch/sketchStore.ts +190 -0
- package/src/editor/core/store/editorPersistence.ts +28 -12
- package/src/editor/core/store/editorTypes.ts +4 -1
- package/src/editor/core/store/editorViewStore.ts +2 -2
- package/src/editor/core/store/gradientSource.ts +15 -1
- package/src/editor/core/themes/parsers/gradient.ts +62 -4
- package/src/editor/core/themes/slices/gradients.ts +75 -14
- package/src/editor/core/themes/themeTypes.ts +6 -1
- package/src/editor/docs/Docs.svelte +4 -3
- package/src/editor/docs/chapters.ts +1 -0
- package/src/editor/docs/content/01-overview.md +2 -1
- package/src/editor/docs/content/editing-tokens.md +5 -1
- package/src/editor/docs/content/sketch-mode.md +183 -0
- package/src/editor/docs/content.generated.ts +3 -2
- package/src/editor/overlay/LiveEditorOverlay.svelte +15 -0
- package/src/editor/pages/EditorShell.svelte +43 -0
- package/src/editor/ui/EditorViewSwitcher.svelte +30 -17
- package/src/editor/ui/FontStackEditor.svelte +3 -0
- package/src/editor/ui/GradientEditor.svelte +38 -1
- package/src/editor/ui/UIReveal.svelte +7 -1
- package/src/editor/ui/UISegmentedControl.svelte +4 -8
- package/src/editor/ui/sections/GradientsSection.svelte +47 -1
- package/src/editor/ui/sketch/SketchDial.svelte +124 -0
- package/src/editor/ui/sketch/SketchPreview.svelte +119 -0
- package/src/editor/ui/sketch/SketchRange.svelte +185 -0
- package/src/editor/ui/sketch/SketchTab.svelte +1264 -0
- package/src/live-tokens/data/colors-and-type/autumn.json +17 -0
- package/src/live-tokens/data/colors-and-type/default.json +17 -0
- package/src/live-tokens/data/colors-and-type/halloween.json +17 -0
- package/src/live-tokens/data/colors-and-type/midnight-study.json +17 -0
- package/src/live-tokens/data/colors-and-type/ocean.json +17 -0
- package/src/live-tokens/data/colors-and-type/royal-velvet.json +17 -0
- package/src/live-tokens/data/colors-and-type/sketchy.json +2520 -0
- package/src/live-tokens/data/colors-and-type/spring-meadow.json +17 -0
- package/src/live-tokens/data/colors-and-type/sunset.json +17 -0
- package/src/live-tokens/data/themes/autumn.json +17 -0
- package/src/live-tokens/data/themes/halloween.json +17 -0
- package/src/live-tokens/data/themes/midnight-study.json +17 -0
- package/src/live-tokens/data/themes/ocean.json +17 -0
- package/src/live-tokens/data/themes/royal-velvet.json +17 -0
- package/src/live-tokens/data/themes/sketchy.json +3984 -0
- package/src/live-tokens/data/themes/spring-meadow.json +17 -0
- package/src/live-tokens/data/themes/sunset.json +17 -0
- package/src/live-tokens/data/tokens.generated.css +1 -0
- package/src/system/components/Card.svelte +12 -1
- package/src/system/components/SectionDivider.svelte +4 -0
- package/src/system/styles/tokens.css +15 -2
|
@@ -44,7 +44,15 @@ For pattern reference, read any shipped component's source directly from the con
|
|
|
44
44
|
```
|
|
45
45
|
The schema side-effect happens inside `registerComponent` (which `bootLiveTokens` calls for you), so you don't call `registerComponentSchema` separately. **Do not place a standalone `registerComponent(...)` *before* `bootLiveTokens`** — that registers before the editor's init hooks run, which is the wrong window and can leave editor changes disconnected from the live page. Only call `registerComponent` directly if your app mounts manually (no `bootLiveTokens`), in which case call it before `mount(App, ...)`.
|
|
46
46
|
4. **Tell the picker** — open `.claude/skills/live-tokens-pick-component/SKILL.md` and add your new component to the **Catalogue** line under the family it belongs to (Action / Input / Selection / Containers / Messaging / Display). If it's confusable with an existing component (a second selection control, a competing container), add a row to that family's decision table explaining the use-case it owns. Without this step, the component exists but [[live-tokens-pick-component]] can't recommend it when a user asks "which component should I use?" — the same rule applies whether the component is first-party (update the picker shipped in this package) or consumer-authored (update the local copy at `.claude/skills/live-tokens-pick-component/SKILL.md` that `setup-claude` placed in your project).
|
|
47
|
-
5. **
|
|
47
|
+
5. **Join the sketch layer** — the effect draws a fixed set of parts, so a new
|
|
48
|
+
component stays crisp while the page around it goes hand-drawn until it opts
|
|
49
|
+
in. A consumer component carries one of four reserved classes on its root and
|
|
50
|
+
names the five `--sketch-*` colours it is drawn with; a first-party component
|
|
51
|
+
adds a `PartSpec` row instead. The layer also takes `background`,
|
|
52
|
+
`border-color`, `box-shadow`, `overflow`, `position` and both pseudo-elements
|
|
53
|
+
away from the element it draws, which constrains where the class can go. Read
|
|
54
|
+
`references/sketch-mode.md`.
|
|
55
|
+
6. **Verify** with the checklist at the bottom of this file.
|
|
48
56
|
|
|
49
57
|
## Token discipline
|
|
50
58
|
|
|
@@ -123,6 +131,7 @@ The authoritative recognised list lives in `bin/check-component.mjs` (`KNOWN_SUF
|
|
|
123
131
|
|
|
124
132
|
The helper strips the `--<component>-` prefix and those segments, keeping the rest: `--mywidget-header-default-text` → `header-text`, `--mywidget-header-default-text-font-family` → `header-text-font-family`. Two parts ending in the same word stay distinct; one slot across variants collapses to one key. To override a single derived key, set `colorGroupKey` on that type-group config — it wins and is never recomputed, so your fix survives. There is no name-based fallback: a bare `buildTypeGroupColorTokens` call emits un-grouped (solo) colors rather than guessing, and a bare *font* helper across multiple slots is a `check-component` warning (its default `font-family`/… keys would merge the slots' fonts).
|
|
125
133
|
|
|
134
|
+
|
|
126
135
|
## State model
|
|
127
136
|
|
|
128
137
|
Components *can* have two state axes. Many don't: container and messaging components (Card, Badge, Callout, CollapsibleSection) have only variants, no hover/disabled. Skip the rest of this section for those.
|
|
@@ -194,10 +203,11 @@ For your own component, copy the pattern and substitute your id. Registering aga
|
|
|
194
203
|
|
|
195
204
|
## Extensions
|
|
196
205
|
|
|
197
|
-
Read the
|
|
206
|
+
Read the sketch reference for every component; the other two only when they apply.
|
|
198
207
|
|
|
199
208
|
- `references/linked-siblings.md`: variants that share base properties and should move together (Badge, Card, SegmentedControl).
|
|
200
209
|
- `references/intrinsics.md`: structural or display choices that are not token values (an alignment, an element's visibility), where the runtime default and the editor's read-back must agree.
|
|
210
|
+
- `references/sketch-mode.md`: joining the sketch layer. **Every component needs this.** One class on the root, the five `--sketch-*` values the layer draws with, and the list of what it takes over from the element. Skip it and the component stays crisp while the page around it goes hand-drawn.
|
|
201
211
|
|
|
202
212
|
## Verification checklist
|
|
203
213
|
|
|
@@ -230,3 +240,4 @@ Finally navigate to `/live-tokens/components` and confirm the runtime behaviours
|
|
|
230
240
|
- [ ] `component-configs/<id>/default.json` is derived from the `:global(:root)` block at boot. Save writes `_working.json`, the unsaved buffer the open theme captures; Save As also writes a named preset.
|
|
231
241
|
- [ ] Reset returns each variable to its `:global(:root)` default.
|
|
232
242
|
- [ ] Boot validation is clean (no warnings about the component being missing from the server scan, or about disk-vs-registry drift).
|
|
243
|
+
- [ ] Switch Sketch mode on in the editor and walk the checklist at the end of `references/sketch-mode.md`. The component is drawn in every variant and on hover, in its own colours, not crisp and not wearing another part's palette. Switch it off again and the component is unchanged.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Joining the sketch layer
|
|
2
|
+
|
|
3
|
+
Sketch mode blanks each part's real background and border and repaints them onto
|
|
4
|
+
`::before`/`::after` through a shared noise field. It draws a fixed set of
|
|
5
|
+
selectors: the shipped components, plus four classes reserved for everyone else.
|
|
6
|
+
Your component is skipped until it opts in, so it stays crisp while the page
|
|
7
|
+
around it goes hand-drawn.
|
|
8
|
+
|
|
9
|
+
The whole contract is CSS. There is nothing to import and no function to call:
|
|
10
|
+
the layer exports no runtime API, and a component joins it by carrying a class
|
|
11
|
+
and naming five custom properties.
|
|
12
|
+
|
|
13
|
+
## What the layer takes over
|
|
14
|
+
|
|
15
|
+
An opted-in element is no longer painting itself. On every drawn part the layer
|
|
16
|
+
forces:
|
|
17
|
+
|
|
18
|
+
| It forces | So you must |
|
|
19
|
+
|----------------------------------------------|----------------------------------------------------------|
|
|
20
|
+
| `background: transparent !important` | Name the fill again as `--sketch-fill` |
|
|
21
|
+
| `border-color: transparent !important` | Name the outline again as `--sketch-stroke` |
|
|
22
|
+
| `box-shadow: none !important` | Name the shadow again as `--sketch-shadow` |
|
|
23
|
+
| `overflow: visible !important` | Never put the class on a box whose clip carries meaning |
|
|
24
|
+
| `position: relative` | Never put the class on an absolutely-positioned root |
|
|
25
|
+
| `z-index: 0` | Expect a new stacking context on that element |
|
|
26
|
+
| `::before` (the fill), `::after` (the stroke) | Never own either pseudo-element on that element |
|
|
27
|
+
|
|
28
|
+
`::after` survives on `sketch-rule` alone, which draws no outline. `::before` is
|
|
29
|
+
claimed on all four.
|
|
30
|
+
|
|
31
|
+
## Opting in
|
|
32
|
+
|
|
33
|
+
Put one class on the runtime component's root, chosen by **size, not by kind**.
|
|
34
|
+
A card and a modal are both containers; a badge and a pill are both chips.
|
|
35
|
+
|
|
36
|
+
| Class | For |
|
|
37
|
+
|---------------------|-------------------------------------------------------------|
|
|
38
|
+
| `sketch-surface` | A box. The default treatment. |
|
|
39
|
+
| `sketch-container` | A large box. Tilts less, so the type inside stays readable. |
|
|
40
|
+
| `sketch-chip` | A small box. Finer fill mask, more rotation, less travel. |
|
|
41
|
+
| `sketch-rule` | A line rather than a box. No rotation, no rounded ends. |
|
|
42
|
+
|
|
43
|
+
The class opts you in and nothing more. It names no colour, so the layer emits
|
|
44
|
+
no rule for it and whatever your component declares survives.
|
|
45
|
+
|
|
46
|
+
```svelte
|
|
47
|
+
<div class="mywidget sketch-container {variant}">…</div>
|
|
48
|
+
|
|
49
|
+
<style>
|
|
50
|
+
.mywidget {
|
|
51
|
+
background: var(--mywidget-surface);
|
|
52
|
+
border: var(--mywidget-border-width) solid var(--mywidget-border);
|
|
53
|
+
border-radius: var(--mywidget-radius);
|
|
54
|
+
box-shadow: var(--mywidget-shadow);
|
|
55
|
+
|
|
56
|
+
/* The layer hides all four above. These are what it draws instead. */
|
|
57
|
+
--sketch-fill: var(--mywidget-surface);
|
|
58
|
+
--sketch-stroke: var(--mywidget-border);
|
|
59
|
+
--sketch-hatch-color: var(--mywidget-border);
|
|
60
|
+
--sketch-radius: var(--mywidget-radius);
|
|
61
|
+
--sketch-shadow: var(--mywidget-shadow);
|
|
62
|
+
}
|
|
63
|
+
</style>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
State all five. `--sketch-radius` is registered as an inheriting `<length>`, and
|
|
67
|
+
the other four inherit as ordinary custom properties, so a part that states
|
|
68
|
+
nothing is drawn with its **ancestor's** value: a badge inside a hatched card
|
|
69
|
+
stripes itself in the card's ink, and a square header inside a rounded card
|
|
70
|
+
picks up the card's corners.
|
|
71
|
+
|
|
72
|
+
## Variants, states and inner parts
|
|
73
|
+
|
|
74
|
+
Nothing competes with you for these values, so every case is one more
|
|
75
|
+
declaration at the specificity you already use.
|
|
76
|
+
|
|
77
|
+
```css
|
|
78
|
+
.mywidget.danger { --sketch-fill: var(--mywidget-danger-surface); }
|
|
79
|
+
.mywidget:hover,
|
|
80
|
+
.mywidget.force-hover { --sketch-stroke: var(--mywidget-hover-border); }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Pair every `:hover` with `.force-hover`, as elsewhere: that is the editor's
|
|
84
|
+
preview of the hover state, and a hover the sketch layer cannot paint reads as
|
|
85
|
+
no hover at all once the real background is transparent.
|
|
86
|
+
|
|
87
|
+
An inner part that carries its own surface (a header strip, a footer) takes its
|
|
88
|
+
own class and its own five values. Where such a part draws no outline, bind the
|
|
89
|
+
hatch ink to the ink its **parent** is outlined in, so the component reads as one
|
|
90
|
+
drawing rather than a shaded panel dropped into a box:
|
|
91
|
+
|
|
92
|
+
```css
|
|
93
|
+
.mywidget-header {
|
|
94
|
+
--sketch-fill: var(--mywidget-header-surface);
|
|
95
|
+
--sketch-stroke: transparent;
|
|
96
|
+
--sketch-hatch-color: var(--mywidget-border);
|
|
97
|
+
--sketch-radius: 0px;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
A part with a visible stroke needs no `--sketch-hatch-color`; it falls back to
|
|
102
|
+
the stroke and follows it into hover. A part with no fill wants none, because
|
|
103
|
+
there is no surface there to shade.
|
|
104
|
+
|
|
105
|
+
A gradient is a valid fill. The `background` shorthand's last layer takes a
|
|
106
|
+
colour or an image, so `--sketch-fill` accepts either.
|
|
107
|
+
|
|
108
|
+
## Where the class does not go
|
|
109
|
+
|
|
110
|
+
- **A positioned root.** The layer forces `position: relative` on parts that sit
|
|
111
|
+
in flow, which drops an absolutely or fixed-positioned element back to its
|
|
112
|
+
flow position. Put the class on an inner box instead.
|
|
113
|
+
- **A box that clips something real.** `overflow` is forced visible so the ink
|
|
114
|
+
can travel past the border box, and there is no consumer opt-out. A scroller,
|
|
115
|
+
a fill bar held to its track, or a picture held to its frame keeps its clip by
|
|
116
|
+
keeping the class off that element and carrying it on a wrapper.
|
|
117
|
+
- **An element that owns `::before` or `::after`.** The layer claims both. A
|
|
118
|
+
shimmer, a caret or a decorative arrow on the opted-in element is gone.
|
|
119
|
+
- **A shipped part's selector** (`.card`, `.panel`). Borrowing one to get drawn
|
|
120
|
+
works, but it hands your component that part's colours and its damping, and it
|
|
121
|
+
is package-internal. The reserved classes are the contract.
|
|
122
|
+
|
|
123
|
+
## Rules, which are not boxes
|
|
124
|
+
|
|
125
|
+
A `border` cannot be displaced: the effect moves boxes, and a border is not one.
|
|
126
|
+
Make the rule an element, give it `sketch-rule`, and name its ink as the fill.
|
|
127
|
+
|
|
128
|
+
```svelte
|
|
129
|
+
<span class="mywidget-rule sketch-rule" aria-hidden="true"></span>
|
|
130
|
+
```
|
|
131
|
+
```css
|
|
132
|
+
.mywidget-rule {
|
|
133
|
+
height: var(--border-width-2);
|
|
134
|
+
background: var(--mywidget-divider);
|
|
135
|
+
--sketch-fill: var(--mywidget-divider);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Media inside your component
|
|
140
|
+
|
|
141
|
+
A drawn part's `overflow` is visible so the fill and outline can travel past the
|
|
142
|
+
box. A background that bleeds is the effect working. An image that bleeds is
|
|
143
|
+
not, since it keeps square corners while the part around it turns. Media running
|
|
144
|
+
to your component's edge has to carry the corners itself:
|
|
145
|
+
|
|
146
|
+
```css
|
|
147
|
+
.mywidget-cover {
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
border-top-left-radius: var(--sketch-radius, var(--mywidget-radius));
|
|
150
|
+
border-top-right-radius: var(--sketch-radius, var(--mywidget-radius));
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`--sketch-radius` is the radius the layer drew and it inherits, so the fallback
|
|
155
|
+
covers the effect being off. Corner spread is per-corner and per-instance, so at
|
|
156
|
+
high spread the crop is the mean rather than an exact trace of the drawn edge.
|
|
157
|
+
|
|
158
|
+
## Icons and SVG
|
|
159
|
+
|
|
160
|
+
Icons and inline SVG take the wobble directly, since a glyph has no box to
|
|
161
|
+
redraw. Body type is left alone deliberately: an icon is a shape and survives a
|
|
162
|
+
wobble, a paragraph is not. You opt into none of this; it applies to every
|
|
163
|
+
`[class*="fa-"]` and every `svg` under the scope.
|
|
164
|
+
|
|
165
|
+
`--sketch-icon-off` names what a subtree's glyphs are drawn with instead. It
|
|
166
|
+
inherits, so one declaration covers everything under it:
|
|
167
|
+
|
|
168
|
+
```css
|
|
169
|
+
/* Crisp. Chrome, a logo, anything that has to stay exact. */
|
|
170
|
+
.mywidget-toolbar { --sketch-icon-off: none; }
|
|
171
|
+
|
|
172
|
+
/* Drawn back rather than off, at a third of the travel. Small artwork, and
|
|
173
|
+
type set as an SVG, which the layer reads as one large glyph. */
|
|
174
|
+
.mywidget-mark { --sketch-icon-off: var(--sketch-icon-soft); }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Travel is stated in px against a glyph whose size the layer cannot know, so the
|
|
178
|
+
dial that suits a card's worth of artwork tears a 16px icon apart. Reach for the
|
|
179
|
+
soft bank before reaching for `none`. The shipped `SectionDivider` is the worked
|
|
180
|
+
example.
|
|
181
|
+
|
|
182
|
+
## First-party components
|
|
183
|
+
|
|
184
|
+
A component authored inside the package does not use the reserved classes. Add a
|
|
185
|
+
`PartSpec` row to `PART_SPECS` in `src/editor/core/sketch/sketchLayer.ts`
|
|
186
|
+
instead, which is keyed to the component's own token stem and gets the shipped
|
|
187
|
+
damping. `sketchPartTokens.test.ts` then holds you to it: every colour the layer
|
|
188
|
+
paints must be one the component itself assigns to that same element, checked
|
|
189
|
+
against the compiled `<style>` block.
|
|
190
|
+
|
|
191
|
+
## Verify
|
|
192
|
+
|
|
193
|
+
Switch Sketch mode on from the editor's **Sketch Style** view, then check the
|
|
194
|
+
component in place:
|
|
195
|
+
|
|
196
|
+
- [ ] Drawn, not crisp, in every variant.
|
|
197
|
+
- [ ] Wearing its own colours, not its parent's, including inner parts.
|
|
198
|
+
- [ ] Hover repaints. The wobble holds still while it does.
|
|
199
|
+
- [ ] Hatched fill uses ink that belongs to the component.
|
|
200
|
+
- [ ] Media at the component's edge turns with the drawn corners.
|
|
201
|
+
- [ ] Nothing that has to stay exact is torn: icons, clipped content, overlays.
|
|
202
|
+
- [ ] Switch it off. Every trace is gone and the component is unchanged.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: live-tokens-pair-fonts
|
|
3
|
-
description: Choose and apply a Google Fonts pairing for a live-tokens theme by binding families to the --font-display, --font-sans, --font-serif and --font-
|
|
3
|
+
description: Choose and apply a Google Fonts pairing for a live-tokens theme by binding families to the --font-display, --font-sans, --font-serif, --font-mono and --font-editorial stacks. Use whenever the user asks to pair fonts, pick a typeface, change or set the fonts, or describes type by voice: give me a font pairing, what font should the headings use, make the type more editorial, friendlier, more technical, more elegant, a serif for headings, a display font for this theme, less generic type, match the fonts to the theme. Also invoked by live-tokens-generate-theme for the type half of a whole look. Changes type only, never color. Not for a single token (use the editor) or for color (see live-tokens-generate-theme).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Pairing fonts for a theme
|
|
@@ -24,7 +24,7 @@ Flags: `--dry-run` reports without writing. `--no-verify` skips the network and
|
|
|
24
24
|
{ "display": "Fraunces", "body": "Nunito Sans" }
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Every slot is optional and an omitted slot is left exactly as it is. `display` is `--font-display`, `body` is `--font-sans`; `serif` and `
|
|
27
|
+
Every slot is optional and an omitted slot is left exactly as it is. `display` is `--font-display`, `body` is `--font-sans`; `serif`, `mono` and `editorial` exist when a theme needs them. `editorial` is `--font-editorial`, the long-reading face behind the `--editorial-*` text style: it tracks the body face until a theme repoints it, so set it only when essays and articles should not carry the body face. A slot may be `{ "name": "...", "url": "..." }` to pin an exact URL. Spell families as Google does; the CLI reports the canonical spelling back.
|
|
28
28
|
|
|
29
29
|
## Choose the body face first
|
|
30
30
|
|
|
@@ -49,7 +49,7 @@ All four pick one option from a set. The right one depends on **option count**,
|
|
|
49
49
|
| `Dialog` | Modal, blocks page | Confirmations, focused tasks the page can't continue around |
|
|
50
50
|
| `Panel` | Inline, fixed stage | A demo or preview surface whose height must not reflow |
|
|
51
51
|
|
|
52
|
-
- Default to `Card`. It's the workhorse.
|
|
52
|
+
- Default to `Card`. It's the workhorse. For full-bleed media — cover art, a poster, a chart that reaches its own border — pass `flush` (with `prose={false}`) rather than zeroing its padding tokens from the page.
|
|
53
53
|
- Reach for `CollapsibleSection` only when the content is *legitimately secondary* (advanced users open it; most skip). Don't use collapse as a styling choice when the content matters.
|
|
54
54
|
- `Panel` is a stage, not a content container. It pins its own height so what it shows can resize without moving the page, which is what a component preview or a live example needs and what article content does not. Content goes in `Card`.
|
|
55
55
|
- **Don't use `Dialog` for routine forms.** Reach for it only when the page cannot meaningfully continue until the user decides (destructive confirmations, payment, sign-in). Routine forms go inline in a `Card`.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,197 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.58.0 — The sketch layer states its contract
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`flush` on `Card`.** A card holding full-bleed media has to reach its own
|
|
8
|
+
border, but the body's inset stood in the way and the only way around it was
|
|
9
|
+
for the page to zero the five `--card-default-body-padding*` tokens at its own
|
|
10
|
+
scope — reaching around the component to undo something the component did, and
|
|
11
|
+
repeating it at every such card. `flush` drops the inset from the body alone,
|
|
12
|
+
outweighs `size="compact"` so it holds at either size, and pairs with
|
|
13
|
+
`prose={false}`: a flush body is a frame, not a column of text.
|
|
14
|
+
- **`sketch-container` and `sketch-chip`, beside the existing `sketch-surface`
|
|
15
|
+
and `sketch-rule`.** The sketch layer draws a fixed set of selectors, so a
|
|
16
|
+
consumer-authored component stayed crisp while the page around it went
|
|
17
|
+
hand-drawn. The four reserved classes are now a size ladder — a container
|
|
18
|
+
tilts less than the type inside it can tolerate, a chip is smaller than one
|
|
19
|
+
blob of the fill mask — and a consumer picks the band its part belongs to
|
|
20
|
+
instead of inheriting the middle treatment or borrowing a shipped part's
|
|
21
|
+
selector to get drawn at all. The classes name no colours, so the element's
|
|
22
|
+
own `--sketch-fill` / `--sketch-stroke` survive untouched.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **The `Sketches` preset theme is now `Sketchy`.** The old name read as a
|
|
27
|
+
collection of sketches rather than as the look itself, which is the one thing
|
|
28
|
+
a preset name has to do. The theme's files move to
|
|
29
|
+
`themes/sketchy.json` and `colors-and-type/sketchy.json`. Presets are served
|
|
30
|
+
read-through from the package, so a consumer who never opened it sees only the
|
|
31
|
+
new name; one whose active or production pointer names `sketches` has to
|
|
32
|
+
repoint it at `sketchy`.
|
|
33
|
+
- **The editor's `Sketch` and `Colors` views are now `Sketch Style` and
|
|
34
|
+
`Color Wheel`,** and the condensed rail cycles Tokens, Components, Sketch
|
|
35
|
+
Style, Color Wheel. `Sketch` named the mode and the view identically while
|
|
36
|
+
`Colors` said less than the view does; the flow order now runs from the
|
|
37
|
+
narrowest edit to the widest.
|
|
38
|
+
- **The sketch layer's contract is now documented from both sides.** The guide
|
|
39
|
+
and the component-authoring skill each described what an element has to
|
|
40
|
+
declare to be drawn, and neither said what the layer takes away from it: the
|
|
41
|
+
element's `background`, `border-color` and `box-shadow` are forced off, its
|
|
42
|
+
`overflow` is forced visible, it is given a stacking context, and both its
|
|
43
|
+
pseudo-elements are claimed. That is what decides where the opt-in class can
|
|
44
|
+
go, so a component that owned a `::before`, clipped its content or positioned
|
|
45
|
+
its root failed in a way neither document accounted for. The skill reference
|
|
46
|
+
now carries the full contract, including the icon controls, the hatch-ink
|
|
47
|
+
fallback for a part with no outline, and the `PART_SPECS` path a first-party
|
|
48
|
+
component takes instead of the reserved classes. The guide gains a short
|
|
49
|
+
section on where the dials live, since nothing said they are held in the
|
|
50
|
+
browser rather than in the theme.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **Sketch mode's "Drawing your own elements" section showed the custom
|
|
55
|
+
properties without the class that opts an element in**, so the example it gave
|
|
56
|
+
drew nothing. It now documents all four reserved classes, how to pick one, and
|
|
57
|
+
that variants, states and gradients are all just further declarations of
|
|
58
|
+
`--sketch-fill` / `--sketch-stroke`.
|
|
59
|
+
- **Nothing said how to keep an image inside a drawn part from bleeding.** A
|
|
60
|
+
part's `overflow` is forced visible so the fill and outline can travel past
|
|
61
|
+
the box, which is right for a background and wrong for a photo: it kept square
|
|
62
|
+
corners while the card around it turned. `--sketch-radius` was already the
|
|
63
|
+
radius the layer drew and already inherited, so the fix was a documentation
|
|
64
|
+
one. Both the Sketch mode chapter and the component-authoring reference now
|
|
65
|
+
show media reading it, with a fallback for the effect being off.
|
|
66
|
+
- **`live-tokens-create-component` never mentioned sketch mode.** Joining the
|
|
67
|
+
layer is now step 5 of the recipe, with `references/sketch-mode.md` behind it
|
|
68
|
+
and a line on the verification checklist. A component authored to the old
|
|
69
|
+
recipe was invisible to the effect and nothing said so.
|
|
70
|
+
|
|
71
|
+
## 0.57.0 — A theme can be drawn by hand
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
|
|
75
|
+
- **Sketch mode: a fourth editor view, beside Tokens, Colors and Components.**
|
|
76
|
+
It is an effect layer over the active theme, not a set of theme values. It
|
|
77
|
+
reads nothing from the theme and writes nothing back. Each component's fill
|
|
78
|
+
and outline are repainted onto `::before`/`::after` from the tokens that
|
|
79
|
+
component already owns (`--<component>-<variant>-surface`, `-border`,
|
|
80
|
+
`-radius`), the real background and border are hidden behind them, and both
|
|
81
|
+
are pushed around one shared noise field. Turning it off removes every trace.
|
|
82
|
+
While it is on it applies to the page behind the editor as well as to the
|
|
83
|
+
preview, because the layer is injected into every document `cssVarSync`
|
|
84
|
+
tracks. Scope is the `data-sketch` attribute, so it switches on for a whole
|
|
85
|
+
document root or for one preview container.
|
|
86
|
+
- **Seven shipped looks, and every dial behind them.** Pencil, Marker,
|
|
87
|
+
Whiteboard, Hatched, Dashed, Napkin and Dry marker, each a complete set of
|
|
88
|
+
settings with a blurb naming what it is. The dials sit under five headings:
|
|
89
|
+
**Border** (travel, wavelength, width, ink, pressure, pooling, dashes, a
|
|
90
|
+
second pass that either copies the first line or runs it through the pen again
|
|
91
|
+
on its own seed), **Fill** (solid or hatched, travel, per-instance offset,
|
|
92
|
+
rotation and scale), **Shape** (corner spread, and a corner travel that leans
|
|
93
|
+
the drawn box into a quadrilateral with no two sides parallel), **Icons and
|
|
94
|
+
SVG** (glyph travel and wavelength on their own scale, because a glyph is all
|
|
95
|
+
curves and needs more travel than a card's long straight edge), and **Noise**
|
|
96
|
+
(the shared displacement field's wavelength, roughness and waveform).
|
|
97
|
+
- **Ink coverage as a generated field.** The mask that thins a fill is a tiling
|
|
98
|
+
Perlin field rasterised to a greyscale PNG and applied with `mask-mode:
|
|
99
|
+
luminance`, rather than an `feTurbulence` primitive. Turbulence lands in a
|
|
100
|
+
narrow band around its own midpoint, so a dial walking a cut across 0 to 1
|
|
101
|
+
spends most of its travel outside the field and the rest reads as flat grey.
|
|
102
|
+
Generated, the tile is stretched onto its own measured range first, so Min and
|
|
103
|
+
Max always mean levels at every grain and octave count. The panel previews the
|
|
104
|
+
field at each stage: noise, output, blur.
|
|
105
|
+
- **Saved sketch presets.** Any set of dials saves under a name and reloads
|
|
106
|
+
later, as files under `<dataDir>/sketch-presets/` served by a new
|
|
107
|
+
`/api/sketch-presets` route on the dev plugin. A sketch look is a draft
|
|
108
|
+
effect, never part of a theme: it has no active/production pointer, it is not
|
|
109
|
+
adopted, and it never reaches `tokens.generated.css`. The shipped seven stay
|
|
110
|
+
in code, so the directory holds nothing but your own files.
|
|
111
|
+
- **A page can hand the layer its own elements.** The effect displaces boxes, so
|
|
112
|
+
a rule drawn as a `border` is not one of them. `--sketch-fill`,
|
|
113
|
+
`--sketch-stroke`, `--sketch-hatch-color` and `--sketch-radius` name what an
|
|
114
|
+
element should be drawn with, and `--sketch-icon-off: none` opts a subtree
|
|
115
|
+
out. The demo app's kit section draws its rules this way; the editor's own
|
|
116
|
+
overlay bar opts out, because the effect is for the page being designed and
|
|
117
|
+
not for the tool looking at it.
|
|
118
|
+
- **A Sketch mode chapter in the user guide.** It sits after Editing tokens and
|
|
119
|
+
covers the presets, the dials, and the `--sketch-*` properties a page uses to
|
|
120
|
+
hand the layer its own elements. Editing tokens itself now names all four
|
|
121
|
+
views; it had been describing two since the Colors view landed.
|
|
122
|
+
- **Sketches ships as an eighth preset theme.** A whole look built on the
|
|
123
|
+
effect: Cabin Sketch over Shantell Sans, square corners, and component
|
|
124
|
+
aliases tuned for a page that is drawn rather than rendered. Load it from the
|
|
125
|
+
Theme panel like any other preset. It stands on its own with Sketch mode off,
|
|
126
|
+
and the effect is what it was designed under.
|
|
127
|
+
- **The gradient library is open-ended.** `--gradient-N` was a fixed four-slot
|
|
128
|
+
scale; the Gradients section now has Add and Remove, and any number of
|
|
129
|
+
numbered slots loads from a theme file. A new slot seeds from the last one, so
|
|
130
|
+
it lands as a gradient you edit rather than an invisible transparent one.
|
|
131
|
+
- **A gradient can point at a corner.** Alongside degrees, a linear gradient
|
|
132
|
+
takes CSS's `to top right` and its seven neighbours. A keyword angles the
|
|
133
|
+
gradient line off the box's own diagonal, so it tracks the element's aspect
|
|
134
|
+
where a fixed angle cannot: `to bottom right` reads as about 95deg across a
|
|
135
|
+
wide heading and about 111deg once that heading wraps. The degrees underneath
|
|
136
|
+
are kept, so clearing the keyword lands on the nearest angle rather than
|
|
137
|
+
snapping to 0deg.
|
|
138
|
+
- **`--gradient-N-stops`.** Each slot now also emits its stop list on its own,
|
|
139
|
+
so a consumer can keep the theme's colours and supply their own geometry:
|
|
140
|
+
`linear-gradient(to top, var(--gradient-5-stops))`. One set of stops then
|
|
141
|
+
serves every direction a design needs, instead of a token per angle.
|
|
142
|
+
- **The editorial type role.** A fifth font stack (`--font-editorial`) and a
|
|
143
|
+
ninth text-style bundle (`--editorial-*`), for the long-reading surfaces that
|
|
144
|
+
should not carry the body face under an expressive display face. Both default
|
|
145
|
+
to indirections rather than literals: the stack resolves to `var(--font-sans)`
|
|
146
|
+
and the bundle mirrors `--body-md-*`, so a project that never mentions
|
|
147
|
+
editorial renders byte-identically. `live-tokens set-fonts` gained a matching
|
|
148
|
+
`editorial` slot, and the stack is editable in the editor beside the other
|
|
149
|
+
four.
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
|
|
153
|
+
- **Derived palette values serialize unclamped.** A palette's basis is OKLCH,
|
|
154
|
+
and clamping every derived step into sRGB on the way out threw away chroma a
|
|
155
|
+
wide-gamut display can show. Values already inside sRGB serialize identically,
|
|
156
|
+
so nothing moves in an existing theme; intent authored beyond sRGB now
|
|
157
|
+
survives to the browser, which does its own gamut mapping at paint. The hex
|
|
158
|
+
readouts still show the clamped projection, which is what a hex readout is
|
|
159
|
+
for.
|
|
160
|
+
- **The product is spelled LiveTokens.** One word, in the README, the docs and
|
|
161
|
+
the demo app. The package name is unchanged.
|
|
162
|
+
- **A test fails on any engine load at module top.** `bin/engineLoadsLazily.test.ts`
|
|
163
|
+
follows every `.mjs` module a test suite can reach, transitively, and rejects
|
|
164
|
+
a top-level import of the compiled engine. CI runs the suite before it builds
|
|
165
|
+
the plugin, so such a load is a publish failure rather than a test failure.
|
|
166
|
+
This is the bug that took down 0.56.0.
|
|
167
|
+
|
|
168
|
+
### Fixed
|
|
169
|
+
|
|
170
|
+
- **A session persisted before the OKLCH palette basis no longer throws on
|
|
171
|
+
hydrate.** Such a session holds hex strings where every palette color is now
|
|
172
|
+
`{ l, c, h }`. `loadFromFile` migrated those on the way in and `hydrate` did
|
|
173
|
+
not, so the session reached the renderer with an undefined hue and threw on
|
|
174
|
+
the first serialization.
|
|
175
|
+
- **The overlay panel's chrome keeps its own font.** `tokens.css` sets the theme
|
|
176
|
+
font on `:where(*)`, and a matching rule beats inheritance, so the panel's
|
|
177
|
+
font-family never reached its children. The editor page already restored
|
|
178
|
+
inheritance for its chrome; the overlay now does the same.
|
|
179
|
+
|
|
180
|
+
### Migration
|
|
181
|
+
|
|
182
|
+
- Two **tokens.css migrations** ship here, both additive: `--font-editorial`
|
|
183
|
+
with the `--editorial-*` bundle, and a `--gradient-N-stops` companion per
|
|
184
|
+
gradient slot. Each companion is read out of the slot it belongs to rather
|
|
185
|
+
than hardcoded, so a retuned gradient does not get a stop list contradicting
|
|
186
|
+
it. Run `npx live-tokens migrate` to apply them to a vendored `tokens.css`, or
|
|
187
|
+
set the plugin's `autoMigrate` option and let it apply additive migrations on
|
|
188
|
+
boot. Until then the dev plugin warns on the gap and the new names simply
|
|
189
|
+
resolve to nothing.
|
|
190
|
+
- The **editorial font stack** is added to a theme file on load, cloned from
|
|
191
|
+
that theme's `--font-sans`. It is presence-based and idempotent, so there is
|
|
192
|
+
no schema step and a theme that never touches editorial keeps rendering as it
|
|
193
|
+
did.
|
|
194
|
+
|
|
3
195
|
## 0.56.1 — Release fix
|
|
4
196
|
|
|
5
197
|
### Fixed
|
package/README.md
CHANGED
package/bin/cli.mjs
CHANGED
|
@@ -56,7 +56,8 @@ Commands:
|
|
|
56
56
|
the report without writing.
|
|
57
57
|
set-fonts <brief.json> [--dry-run] [--no-verify]
|
|
58
58
|
Bind Google Fonts families to --font-display,
|
|
59
|
-
--font-sans, --font-serif
|
|
59
|
+
--font-sans, --font-serif, --font-mono and
|
|
60
|
+
--font-editorial (see
|
|
60
61
|
the live-tokens-pair-fonts skill). Each family is
|
|
61
62
|
verified against the Google Fonts API and the URL
|
|
62
63
|
is negotiated from the weights it actually has.
|
|
@@ -270,6 +270,7 @@ function resolveDataDirs(opts = {}) {
|
|
|
270
270
|
colorsAndTypeDir: opts.colorsAndTypeDir ? import_path.default.resolve(opts.colorsAndTypeDir) : fileConfig.colorsAndTypeDir ? import_path.default.resolve(fileConfig.colorsAndTypeDir) : sub("colors-and-type"),
|
|
271
271
|
componentConfigsDir: opts.componentConfigsDir ? import_path.default.resolve(opts.componentConfigsDir) : fileConfig.componentConfigsDir ? import_path.default.resolve(fileConfig.componentConfigsDir) : sub("component-configs"),
|
|
272
272
|
themesDir: opts.themesDir ? import_path.default.resolve(opts.themesDir) : fileConfig.themesDir ? import_path.default.resolve(fileConfig.themesDir) : sub("themes"),
|
|
273
|
+
sketchPresetsDir: sub("sketch-presets"),
|
|
273
274
|
legacyManifestsDir: fileConfig.manifestsDir ? import_path.default.resolve(fileConfig.manifestsDir) : void 0
|
|
274
275
|
};
|
|
275
276
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-
|
|
2
|
-
export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-
|
|
1
|
+
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-DSV3Zisf.cjs';
|
|
2
|
+
export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-CRfD1LdA.cjs';
|
|
3
3
|
export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.cjs';
|
|
4
4
|
|
|
5
5
|
type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-
|
|
2
|
-
export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-
|
|
1
|
+
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-DSV3Zisf.js';
|
|
2
|
+
export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-CRfD1LdA.js';
|
|
3
3
|
export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.js';
|
|
4
4
|
|
|
5
5
|
type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hexToOklch,
|
|
3
3
|
oklchToCss
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XWXIMTWZ.js";
|
|
5
5
|
|
|
6
6
|
// src/editor/core/themes/parsers/globalRootBlock.ts
|
|
7
7
|
function extractGlobalRootBody(source) {
|
|
@@ -375,6 +375,61 @@ var tokensCssMigration_2026_08_19_oklchColorValues = {
|
|
|
375
375
|
}
|
|
376
376
|
};
|
|
377
377
|
|
|
378
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-08-25-editorial-type-role.ts
|
|
379
|
+
var STACK = [{ name: "--font-editorial", value: "var(--font-sans)" }];
|
|
380
|
+
var BUNDLE2 = [
|
|
381
|
+
{ name: "--editorial-font-family", value: "var(--font-editorial)" },
|
|
382
|
+
{ name: "--editorial-font-size", value: "var(--font-size-md)" },
|
|
383
|
+
{ name: "--editorial-font-weight", value: "var(--font-weight-normal)" },
|
|
384
|
+
{ name: "--editorial-line-height", value: "var(--line-height-normal)" },
|
|
385
|
+
{ name: "--editorial-letter-spacing", value: "var(--letter-spacing-normal)" }
|
|
386
|
+
];
|
|
387
|
+
var tokensCssMigration_2026_08_25_editorialTypeRole = {
|
|
388
|
+
id: "2026-08-25-editorial-type-role",
|
|
389
|
+
kind: "additive",
|
|
390
|
+
description: "Add the editorial type role (--font-editorial and the --editorial-* bundle)",
|
|
391
|
+
apply(css) {
|
|
392
|
+
const withStack = ensureScale(css, {
|
|
393
|
+
anchorPrefixes: ["--font-mono", "--font-serif", "--font-sans", "--font-display"],
|
|
394
|
+
entries: STACK
|
|
395
|
+
});
|
|
396
|
+
return ensureScale(withStack, {
|
|
397
|
+
sectionComment: "Editorial \u2014 the long-reading role, body face until repointed",
|
|
398
|
+
anchorPrefixes: [
|
|
399
|
+
"--eyebrow-",
|
|
400
|
+
"--code-",
|
|
401
|
+
"--body-",
|
|
402
|
+
"--heading-",
|
|
403
|
+
"--letter-spacing-",
|
|
404
|
+
"--line-height-",
|
|
405
|
+
"--font-weight-",
|
|
406
|
+
"--font-size-",
|
|
407
|
+
"--font-"
|
|
408
|
+
],
|
|
409
|
+
entries: BUNDLE2
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-08-26-gradient-stops.ts
|
|
415
|
+
var STOPS_RE = /^(?:linear|radial)-gradient\(\s*[^,]+,\s*(.+)\)$/i;
|
|
416
|
+
var tokensCssMigration_2026_08_26_gradientStops = {
|
|
417
|
+
id: "2026-08-26-gradient-stops",
|
|
418
|
+
kind: "additive",
|
|
419
|
+
description: "Add --gradient-N-stops companions to the gradient slots",
|
|
420
|
+
apply(css) {
|
|
421
|
+
const values = collectTokenValues(css);
|
|
422
|
+
const entries = [];
|
|
423
|
+
for (const [name, value] of values) {
|
|
424
|
+
if (!/^--gradient-\d+$/.test(name)) continue;
|
|
425
|
+
const stops = value.match(STOPS_RE);
|
|
426
|
+
if (stops) entries.push({ name: `${name}-stops`, value: stops[1].trim() });
|
|
427
|
+
}
|
|
428
|
+
if (entries.length === 0) return css;
|
|
429
|
+
return ensureScale(css, { anchorPrefixes: ["--gradient-"], entries });
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
378
433
|
// vite-plugin/tokensCssMigrations/index.ts
|
|
379
434
|
var TOKENS_CSS_MIGRATIONS = [
|
|
380
435
|
tokensCssMigration_2026_05_29_typographyScaleAdditions,
|
|
@@ -384,7 +439,9 @@ var TOKENS_CSS_MIGRATIONS = [
|
|
|
384
439
|
tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions,
|
|
385
440
|
tokensCssMigration_2026_07_20_lineHeightRename,
|
|
386
441
|
tokensCssMigration_2026_07_20_semanticTextStyles,
|
|
387
|
-
tokensCssMigration_2026_08_19_oklchColorValues
|
|
442
|
+
tokensCssMigration_2026_08_19_oklchColorValues,
|
|
443
|
+
tokensCssMigration_2026_08_25_editorialTypeRole,
|
|
444
|
+
tokensCssMigration_2026_08_26_gradientStops
|
|
388
445
|
];
|
|
389
446
|
function runTokensCssMigrations(css) {
|
|
390
447
|
return foldMigrations(css, () => true);
|