@motion-proto/live-tokens 0.94.2 → 0.95.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 (108) hide show
  1. package/.claude/skills/live-tokens-create-page/SKILL.md +7 -3
  2. package/CHANGELOG.md +108 -0
  3. package/README.md +6 -6
  4. package/dist-plugin/{chunk-7XSUHJUH.js → chunk-4J6JPSVS.js} +53 -2
  5. package/dist-plugin/{chunk-W5VQV32K.js → chunk-GYRULB2X.js} +1 -1
  6. package/dist-plugin/{chunk-ONYAIXCZ.js → chunk-QQASYPW7.js} +32 -9
  7. package/dist-plugin/index.cjs +598 -17
  8. package/dist-plugin/index.d.cts +9 -1
  9. package/dist-plugin/index.d.ts +9 -1
  10. package/dist-plugin/index.js +513 -6
  11. package/dist-plugin/migrateData/index.cjs +32 -9
  12. package/dist-plugin/migrateData/index.js +2 -2
  13. package/dist-plugin/setColors/index.cjs +32 -22
  14. package/dist-plugin/setColors/index.js +2 -15
  15. package/dist-plugin/setGeometry/index.cjs +32 -9
  16. package/dist-plugin/setGeometry/index.js +1 -1
  17. package/dist-plugin/tokensCssMigrations/index.cjs +53 -2
  18. package/dist-plugin/tokensCssMigrations/index.d.cts +9 -2
  19. package/dist-plugin/tokensCssMigrations/index.d.ts +9 -2
  20. package/dist-plugin/tokensCssMigrations/index.js +1 -1
  21. package/package.json +8 -3
  22. package/src/demo/ChromeSelect.svelte +111 -0
  23. package/src/demo/Demo.svelte +39 -5
  24. package/src/demo/DemoBar.svelte +33 -14
  25. package/src/demo/FloatingTokenTags.css +33 -4
  26. package/src/demo/FloatingTokenTags.svelte +81 -68
  27. package/src/demo/Section.svelte +1 -7
  28. package/src/demo/SketchSelect.svelte +36 -12
  29. package/src/demo/SourceLinks.svelte +5 -4
  30. package/src/demo/TestingLoops.svelte +128 -19
  31. package/src/demo/ThemeSelect.svelte +34 -11
  32. package/src/demo/evalResults.ts +7 -7
  33. package/src/demo/sections/SectionClaude.svelte +20 -13
  34. package/src/demo/sections/SectionFooter.svelte +4 -5
  35. package/src/demo/sections/SectionGetStarted.svelte +5 -6
  36. package/src/demo/sections/SectionHero.svelte +43 -23
  37. package/src/demo/sections/SectionKit.svelte +141 -45
  38. package/src/demo/sections/SectionLayers.svelte +3 -3
  39. package/src/demo/sections/SectionOffering.svelte +8 -23
  40. package/src/editor/bootstrap.ts +12 -6
  41. package/src/editor/component-editor/ImageEditor.svelte +1 -1
  42. package/src/editor/component-editor/ImageLightboxEditor.svelte +3 -4
  43. package/src/editor/component-editor/registration.ts +36 -0
  44. package/src/editor/component-editor/registry.ts +5 -12
  45. package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +11 -2
  46. package/src/editor/component-editor/scaffolding/StateBlock.svelte +7 -0
  47. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +1 -2
  48. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +17 -2
  49. package/src/editor/core/store/editorPersistence.ts +6 -1
  50. package/src/editor/core/store/editorRenderer.ts +1 -4
  51. package/src/editor/core/store/editorStore.ts +5 -9
  52. package/src/editor/core/store/editorTypes.ts +2 -2
  53. package/src/editor/core/themes/migrations/2026-10-15-responsive-columns.ts +40 -0
  54. package/src/editor/core/themes/migrations/index.ts +2 -0
  55. package/src/editor/core/themes/slices/columns.ts +112 -42
  56. package/src/editor/docs/Docs.svelte +25 -22
  57. package/src/editor/docs/chapters.ts +1 -0
  58. package/src/editor/docs/content/editing-tokens.md +5 -3
  59. package/src/editor/docs/content/production-css.md +116 -0
  60. package/src/editor/docs/content/themes-workflow.md +2 -0
  61. package/src/editor/docs/content.generated.ts +3 -2
  62. package/src/editor/index.ts +2 -1
  63. package/src/editor/overlay/LiveEditorOverlay.svelte +67 -19
  64. package/src/editor/overlay/LiveTokensRouter.svelte +8 -4
  65. package/src/editor/pages/Editor.svelte +15 -1
  66. package/src/editor/pages/EditorShell.svelte +312 -99
  67. package/src/editor/skill-atlas/SkillAtlas.svelte +111 -24
  68. package/src/editor/skill-atlas/TreeCanvas.svelte +14 -0
  69. package/src/editor/skill-atlas/skillSources.generated.ts +1 -1
  70. package/src/editor/skill-atlas/trees/create-page.ts +24 -24
  71. package/src/editor/skill-atlas/wireLayout.ts +62 -0
  72. package/src/editor/ui/BezierCurveEditor.svelte +3 -0
  73. package/src/editor/ui/FontStackEditor.svelte +2 -2
  74. package/src/editor/ui/PaletteEditor.svelte +64 -6
  75. package/src/editor/ui/UIPaletteSelector.svelte +2 -0
  76. package/src/editor/ui/colors/ColorsTab.svelte +5 -2
  77. package/src/editor/ui/palette/OverridesPanel.svelte +1 -0
  78. package/src/editor/ui/palette/ScaleCurveEditor.svelte +127 -18
  79. package/src/editor/ui/sections/ColumnsSection.svelte +79 -49
  80. package/src/editor/ui/sections/ShadowsSection.svelte +14 -0
  81. package/src/editor/ui/sections/WashesSection.svelte +11 -0
  82. package/src/editor/ui/sketch/SketchTab.svelte +1 -1
  83. package/src/live-tokens/data/colors-and-type/autumn.json +1 -4
  84. package/src/live-tokens/data/colors-and-type/default.json +1 -4
  85. package/src/live-tokens/data/colors-and-type/halloween.json +1 -4
  86. package/src/live-tokens/data/colors-and-type/midnight-study.json +1 -4
  87. package/src/live-tokens/data/colors-and-type/ocean.json +1 -4
  88. package/src/live-tokens/data/colors-and-type/royal-velvet.json +1 -4
  89. package/src/live-tokens/data/colors-and-type/sketchy.json +1 -4
  90. package/src/live-tokens/data/colors-and-type/spring-meadow.json +1 -4
  91. package/src/live-tokens/data/colors-and-type/sunset.json +1 -4
  92. package/src/live-tokens/data/themes/autumn.json +1 -4
  93. package/src/live-tokens/data/themes/halloween.json +1 -4
  94. package/src/live-tokens/data/themes/midnight-study.json +1 -4
  95. package/src/live-tokens/data/themes/ocean.json +1 -4
  96. package/src/live-tokens/data/themes/royal-velvet.json +1 -4
  97. package/src/live-tokens/data/themes/sketchy.json +1 -4
  98. package/src/live-tokens/data/themes/spring-meadow.json +1 -4
  99. package/src/live-tokens/data/themes/sunset.json +1 -4
  100. package/src/live-tokens/data/tokens.generated.css +1 -4
  101. package/src/system/components/SectionDivider.svelte +4 -0
  102. package/src/system/styles/CONVENTIONS.md +1 -1
  103. package/src/system/styles/tokens.css +30 -4
  104. package/template/src/main.ts +2 -2
  105. package/template/src/pages/Home.svelte +11 -8
  106. package/template/vite.config.ts +7 -3
  107. package/src/system/assets/offering.webp +0 -0
  108. /package/dist-plugin/{chunk-O6GQ6GBH.js → chunk-A4TBP4MM.js} +0 -0
@@ -38,7 +38,11 @@ The stage is the canvas, player, or strip the work is about. Stretch a section's
38
38
 
39
39
  ### Grid
40
40
 
41
- The page is the column grid: `display: grid`, `grid-template-columns: repeat(var(--columns-count), 1fr)`, `column-gap: var(--columns-gutter)`, `max-width: var(--columns-max-width)`, `margin: 0 auto`. Each section spans it with `grid-column: 1 / -1`.
41
+ The page is the column grid: `display: grid`, `grid-template-columns: repeat(var(--columns-count), 1fr)`, `column-gap: var(--columns-gutter)`, `box-sizing: content-box`, `max-width: var(--columns-max-width)`, `margin: 0 auto`, and `padding-inline: var(--columns-margin)`. Each section spans it with `grid-column: 1 / -1`. The page sets its top and bottom space with `padding-block`.
42
+
43
+ The columns span `--columns-max-width`, and the margin sits outside them, where `ColumnsOverlay` draws it. `box-sizing: content-box` keeps a project-wide `border-box` reset from narrowing the columns.
44
+
45
+ The page keeps the grid at every width. `tokens.css` narrows `--columns-gutter` and `--columns-margin` at 767px and again at 480px, and `--columns-count` holds at every width, so the page grid itself takes no `@media` rule.
42
46
 
43
47
  To place a section's children at page-column positions:
44
48
 
@@ -49,7 +53,7 @@ To place a section's children at page-column positions:
49
53
 
50
54
  A grid that follows the page columns takes `var(--columns-count)` or a `calc()` of it as its count, so it stays in step with `ColumnsOverlay`. A local grid of two or three equal columns writes its own count. A column number in `grid-column` is fixed to the count read in step 1.
51
55
 
52
- No scaffold collapses the page grid on a phone: the theme's own column gutter alone exceeds a phone's width at the full column count, so every page writes its own `@media (max-width: 767px)` rule setting `grid-template-columns: 1fr` and `column-gap: 0`, with each section's children spanning `grid-column: 1 / -1`. A section's columns then stack in reading order.
56
+ Spans count twelfths of the page at every width, so `span 6` is half the page on a desktop and on a phone. Widen the spans on a narrow screen. In a `@media (max-width: 767px)` rule, give a child that spans 4 on a desktop `span 6`, or give each child `grid-column: 1 / -1` to stack the section in reading order. A column at 390px is about 15px wide, so in a `@media (max-width: 480px)` rule each child spans 12, 6, or 4 columns.
53
57
 
54
58
  ### Separation
55
59
 
@@ -148,7 +152,7 @@ Each position takes one step of the `--space-*` scale. Space inside a group is s
148
152
  | Between containers in a section | `--columns-gutter` across, `--space-24` down |
149
153
  | Between sections | `--space-16` above a hairline |
150
154
  | Page title to first section | `--space-24`, no hairline |
151
- | Page margin | `--space-32` |
155
+ | Page margin | `--columns-margin`, as the page grid's `padding-inline` |
152
156
 
153
157
  Every section after the first opens with a hairline: `padding-top: var(--space-16)` and `border-top: var(--border-width-1) solid var(--border-neutral)`. The hairline separates, so the gap between sections is smaller than the gap between the containers inside them. A section's edge is the hairline alone.
154
158
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,113 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.95.0 — Responsive columns and production CSS
4
+
5
+ ### Changed (breaking)
6
+
7
+ - **The column gutter narrows on tablets and phones.** `--columns-gutter`
8
+ stays 32px on a desktop, becomes 24px at 767px and narrower, and becomes
9
+ 16px at 480px and narrower. `--columns-count` stays 12 at every width, so
10
+ `span 6` is half the page on a phone and on a desktop. Six tokens hold the
11
+ values: `--columns-desktop-gutter`, `--columns-tablet-gutter`,
12
+ `--columns-phone-gutter`, and the three matching `-margin` names.
13
+ `--columns-gutter` and `--columns-margin` keep their names and point at the
14
+ desktop values, and `tokens.css` re-points them in a new 767px block and in
15
+ its 480px block. Set a gutter or a margin through its viewport's name: a
16
+ theme that sets `--columns-gutter` itself outweighs the breakpoints. The
17
+ `clamp(0.5rem, 1.5vw, 1.5rem)` default gutter goes. Every shipped theme
18
+ pinned 32px over it.
19
+ - **The desktop column margin becomes 32px.** `--columns-margin` was `0`.
20
+ Each viewport's margin now equals its gutter, so it becomes 24px at 767px
21
+ and narrower and 16px at 480px and narrower. The column overlay insets its
22
+ columns by the margin, so on a desktop they now line up with a page grid
23
+ that pads with `--space-32`, as the `create` template's Home did before
24
+ this release. A theme that stored the old `0px` margin takes the new 32px.
25
+ The theme migration drops a stored `--columns-margin` of `0px` or `0`, a
26
+ `--columns-gutter` of `32px`, and a `--columns-count` of `12`, the values
27
+ every shipped theme held, and moves any other stored gutter or margin to
28
+ its desktop name.
29
+ - **A custom production theme keeps its old column values in production
30
+ until you save it.** Its file still stores `--columns-gutter` and
31
+ `--columns-margin`, and `tokens.generated.css` writes them on `:root:root`,
32
+ where they outweigh the breakpoints. The editor migrates a theme as it loads
33
+ it. Open the production theme in the editor, save it once, and Adopt it to
34
+ write the new values.
35
+ - **A `@media (max-width: 767px)` block below the 480px block overrides the
36
+ phone values.** Both blocks apply on a phone, and the later one wins. The
37
+ migration adds the tablet re-points to a 767px block your `tokens.css`
38
+ already holds, wherever it sits, and otherwise writes a new block above the
39
+ 480px block. Move a 767px block of your own above the 480px block.
40
+
41
+ ### Changed
42
+
43
+ - **The editor's Columns section edits each viewport.** The count and the
44
+ max width sit at the top and hold at every width. A Desktop, Tablet and
45
+ Phone control picks the viewport whose gutter and margin the sliders below
46
+ it set, and Reset restores that viewport's defaults. A theme stores a
47
+ viewport's value once it differs from the default.
48
+ - **The shipped pages and the `create` template keep the column grid at
49
+ every width.** Each page grid pads with `padding-inline:
50
+ var(--columns-margin)` and declares `box-sizing: content-box`, so its
51
+ columns span `--columns-max-width` and match the overlay. Spans count
52
+ twelfths at every width and widen below 768px. The create-page skill
53
+ teaches the same grid. A page of yours that sets
54
+ `grid-template-columns: 1fr` below 768px keeps working.
55
+ - **A production build keeps a CSS variable only where its value changes at
56
+ runtime.** `vite build` with `themeFileApi` removes each custom property no
57
+ rule reads, writes each one whose value never changes as its value, and
58
+ declares each one it keeps once on `:root`, so DevTools lists it once. A
59
+ scaffolded project's build drops from 821 variables on `:root` to 53, and
60
+ its CSS from 184 kB to 123 kB. Dev and your source files keep every token.
61
+ A script that reads a token under a name it assembles at runtime, such as
62
+ `` `--color-${family}-500` ``, now gets an empty string; list each such
63
+ name under `themeFileApi({ productionCss: { keep: [...] } })`.
64
+ `productionCss: { substitute: false }` removes unread properties and keeps
65
+ every other `var()`, and `productionCss: false` keeps every variable. The
66
+ guide's Production CSS chapter gives the full rule and its limits.
67
+ - **The editor stays out of production builds.** `bootLiveTokens` loads the
68
+ component registry and the editor store only in dev, `registerComponent`
69
+ queues registrations from a module of its own, and `package.json` declares
70
+ `"sideEffects": ["**/*.css"]`. A build drops every editor module and every
71
+ component the site never imports, which takes a scaffolded project from
72
+ 2,177 variables on `:root` to 821 before the step above. A production
73
+ theme's own gradients and scrim and tint washes now render; the editor
74
+ store used to write the default theme's values over them on `:root`.
75
+
76
+ ### Fixed
77
+
78
+ - **A scaffolded project's saved sketchstyles reach its build.** The `create`
79
+ template's `main.ts` passed them to `bootLiveTokens` as `sketchLooks`, an
80
+ option renamed `sketchStyles`, so a built site offered only the shipped
81
+ sketchstyles. A project scaffolded before this release keeps the old line;
82
+ rename `sketchLooks` to `sketchStyles` in its `main.ts`.
83
+
84
+ ### Migration
85
+
86
+ - Run `npx live-tokens migrate`. The `2026-10-15-responsive-columns`
87
+ tokens.css migration is breaking, so the dev plugin's `autoMigrate` skips
88
+ it, and check-page reports it as `tokens-breaking-migration` until it runs.
89
+ It adds the six viewport names, moves a gutter or margin you changed into
90
+ its desktop name, gives the shipped `clamp()` gutter and `0` margin the new
91
+ 32px, points `--columns-gutter` and `--columns-margin` at the desktop
92
+ names, and adds the 767px and 480px re-points. It leaves `--columns-count`
93
+ as it is. Until it runs, `--columns-margin` stays `0`, and the shipped
94
+ docs, demo and testing pages, which now pad with it, sit flush against the
95
+ window at every width.
96
+ - A theme migrates when the editor loads it, and the next save writes the
97
+ result. The entry on custom production themes above gives the step that
98
+ reaches production.
99
+
100
+ ## 0.94.3 — Demo bar chrome
101
+
102
+ ### Fixed
103
+
104
+ - **The demo's Theme and Sketch bar stays legible in every theme.** The bar
105
+ painted from the open theme's scrim, and its selects were themed Buttons, so
106
+ a theme or sketchstyle could leave its labels unreadable. The bar now paints
107
+ as editor chrome from the `--ui-*` tokens, like the editor overlay, and
108
+ sketch mode leaves it alone. `ThemeSelect` and `SketchSelect` take a
109
+ `chrome` prop for the bar. Elsewhere they stay themed.
110
+
3
111
  ## 0.94.2 — Palette step confirm
4
112
 
5
113
  ### Fixed
package/README.md CHANGED
@@ -6,7 +6,7 @@ A design system for styling and building Svelte + Vite microsites. Edit tokens a
6
6
  npm install @motion-proto/live-tokens
7
7
  ```
8
8
 
9
- The editor is dev-only. Production builds get plain CSS variables and the components you used.
9
+ The editor is dev-only. Production builds get the components you used, and their CSS keeps a variable only for a token whose value can change while the page runs.
10
10
 
11
11
  ## Features
12
12
 
@@ -283,7 +283,7 @@ The dev server reads the open theme and paints what it carries. A built site has
283
283
  import { seedSketchFromTheme } from '@motion-proto/live-tokens/sketch';
284
284
  import theme from './live-tokens/data/themes/sketchy.json';
285
285
 
286
- seedSketchFromTheme(theme.sketchStyle);
286
+ seedSketchFromTheme(theme.sketchSettings);
287
287
  await bootLiveTokens(App, '#app');
288
288
  ```
289
289
 
@@ -296,7 +296,7 @@ const files = import.meta.glob('./live-tokens/data/sketch-styles/*.json', {
296
296
  });
297
297
 
298
298
  await bootLiveTokens(App, '#app', {
299
- sketchLooks: Object.entries(files).map(([path, file]) => {
299
+ sketchStyles: Object.entries(files).map(([path, file]) => {
300
300
  const id = path.split('/').pop().replace('.json', '');
301
301
  return { id, label: file.name || id, settings: file.settings };
302
302
  }),
@@ -307,7 +307,7 @@ The file's slug is the look's id, so a sketchstyle picked in the editor keeps wo
307
307
 
308
308
  ### Build a picker
309
309
 
310
- `sketchLooks` is a store holding every look on offer, shipped and your own in one list. Give each row `setSketch(look.id)`, and add a None row yourself: off is a state of the effect rather than one of the looks. `themeSketchLook` carries the theme's own look as one more row, and reads null when the theme carries none.
310
+ `sketchStyles` is a store holding every sketchstyle on offer, shipped and your own, in one list. Give each row `setSketch(style.id)`. Off is a state of the effect, so add a None row yourself that calls `setSketch(null)`. `unsavedSketchStyle` adds one more row when the theme carries sketch settings that no sketchstyle file holds, and reads null otherwise.
311
311
 
312
312
  ### Draw your own elements
313
313
 
@@ -372,7 +372,7 @@ The skill runs `npx live-tokens components --json` and reads each candidate's ca
372
372
 
373
373
  Ask for a page, a route, or a screen: "build a pricing page", "add a /settings route", "put a hero at the top of Home".
374
374
 
375
- The skill composes the page from shipped components, styles every value with `var(--token-*)` (no hex, no pixel literals, so editor changes repaint the page), places content on the column grid via `--columns-count`, `--columns-gutter`, and `--columns-max-width`, adds the route as a `lazy` import with a `source` so the overlay's "Page Source" button works, and imports `site.css` from the page rather than `main.ts` so page CSS stays out of the editor routes. It writes your page files and the route entry, and never touches the data tree.
375
+ The skill composes the page from shipped components, styles every value with `var(--token-*)` (no hex, no pixel literals, so editor changes repaint the page), places content on the column grid via `--columns-count`, `--columns-gutter`, `--columns-margin`, and `--columns-max-width` at every width, adds the route as a `lazy` import with a `source` so the overlay's "Page Source" button works, and imports `site.css` from the page rather than `main.ts` so page CSS stays out of the editor routes. It writes your page files and the route entry, and never touches the data tree.
376
376
 
377
377
  ### `live-tokens-create-theme`
378
378
 
@@ -438,7 +438,7 @@ The skill runs both checkers, which apply every pending additive `tokens.css` mi
438
438
 
439
439
  1. Edit on `/live-tokens/editor`, `/live-tokens/colors`, or `/live-tokens/components`. Edits sit in the working buffer (`_working.json`). **Save** in the Theme panel captures the buffer into the open theme at `<dataDir>/themes/{name}.json`.
440
440
  2. **Adopt** the theme. It becomes the production theme, and its variables are baked into `tokens.generated.css` next to your authored `tokens.css`. Nothing else writes that file, so trying a look never changes what you ship.
441
- 3. `npm run build` bundles both as plain CSS. No editor code, no JSON lookups, no dev surfaces reach production.
441
+ 3. `npm run build` bundles both, with no editor code, JSON lookups, or dev surfaces. `themeFileApi` then rewrites the emitted CSS: it removes each token no rule reads, writes each token whose value never changes as its value, and keeps a variable for the rest. Your source files keep every token name. The user guide's Production CSS chapter covers the rule, the `keep` option, and the limits.
442
442
 
443
443
  ## File ownership
444
444
 
@@ -126,7 +126,7 @@ function setTokenValue(css, name, value, opts = {}) {
126
126
  }
127
127
  return changed ? lines.join("\n") : css;
128
128
  }
129
- function appendMediaBlock(css, query, entries) {
129
+ function appendMediaBlock(css, query, entries, opts = {}) {
130
130
  const lines = css.split("\n");
131
131
  const at = query.trim();
132
132
  const blocks = findTopLevelBlocks(lines, (line) => mediaQueryOf(line) === at);
@@ -138,6 +138,12 @@ function appendMediaBlock(css, query, entries) {
138
138
  const media = blocks.find((b) => b.end > b.start);
139
139
  if (!media) {
140
140
  const block = [`@media ${at} {`, " :root {", ...declarationLines(missing, " "), " }", "}", ""];
141
+ const before = opts.before?.trim();
142
+ const next = before === void 0 ? void 0 : findTopLevelBlocks(lines, (line) => mediaQueryOf(line) === before)[0];
143
+ if (next) {
144
+ lines.splice(next.start, 0, ...block);
145
+ return lines.join("\n");
146
+ }
141
147
  while (lines.length > 0 && lines[lines.length - 1].trim() === "") lines.pop();
142
148
  return [...lines, "", ...block].join("\n");
143
149
  }
@@ -1526,6 +1532,50 @@ var tokensCssMigration_2026_10_08_typeScales = {
1526
1532
  }
1527
1533
  };
1528
1534
 
1535
+ // vite-plugin/tokensCssMigrations/migrations/2026-10-15-responsive-columns.ts
1536
+ var DESKTOP = [
1537
+ {
1538
+ structural: "--columns-gutter",
1539
+ desktop: "--columns-desktop-gutter",
1540
+ shipped: "clamp(0.5rem, 1.5vw, 1.5rem)",
1541
+ value: "32px"
1542
+ },
1543
+ { structural: "--columns-margin", desktop: "--columns-desktop-margin", shipped: "0", value: "32px" }
1544
+ ];
1545
+ var SMALLER = [
1546
+ { name: "--columns-tablet-gutter", value: "24px" },
1547
+ { name: "--columns-tablet-margin", value: "24px" },
1548
+ { name: "--columns-phone-gutter", value: "16px" },
1549
+ { name: "--columns-phone-margin", value: "16px" }
1550
+ ];
1551
+ var repoints = (viewport) => DESKTOP.map(({ structural }) => ({
1552
+ name: structural,
1553
+ value: `var(${structural.replace("--columns-", `--columns-${viewport}-`)})`
1554
+ }));
1555
+ var tokensCssMigration_2026_10_15_responsiveColumns = {
1556
+ id: "2026-10-15-responsive-columns",
1557
+ kind: "breaking",
1558
+ description: "Give the column grid a gutter and margin per viewport, and re-point --columns-gutter and --columns-margin at them",
1559
+ apply(css) {
1560
+ const values = collectTokenValues(css);
1561
+ const pending = DESKTOP.filter(({ desktop }) => !values.has(desktop));
1562
+ let out = ensureScale(css, {
1563
+ anchorPrefixes: ["--columns-"],
1564
+ entries: [
1565
+ ...pending.map(({ structural, desktop, shipped, value }) => {
1566
+ const current = values.get(structural);
1567
+ return { name: desktop, value: current === void 0 || current === shipped ? value : current };
1568
+ }),
1569
+ ...SMALLER
1570
+ ]
1571
+ });
1572
+ for (const { structural, desktop } of pending) out = setTokenValue(out, structural, `var(${desktop})`);
1573
+ out = ensureScale(out, { anchorPrefixes: ["--columns-"], entries: repoints("desktop") });
1574
+ out = appendMediaBlock(out, "(max-width: 767px)", repoints("tablet"), { before: "(max-width: 480px)" });
1575
+ return appendMediaBlock(out, "(max-width: 480px)", repoints("phone"));
1576
+ }
1577
+ };
1578
+
1529
1579
  // vite-plugin/tokensCssMigrations/index.ts
1530
1580
  var TOKENS_CSS_MIGRATIONS = [
1531
1581
  tokensCssMigration_2026_05_29_typographyScaleAdditions,
@@ -1545,7 +1595,8 @@ var TOKENS_CSS_MIGRATIONS = [
1545
1595
  tokensCssMigration_2026_09_01_tintScale,
1546
1596
  tokensCssMigration_2026_09_20_scrimColorAndOpacity,
1547
1597
  tokensCssMigration_2026_09_21_tintColorAndOpacity,
1548
- tokensCssMigration_2026_10_08_typeScales
1598
+ tokensCssMigration_2026_10_08_typeScales,
1599
+ tokensCssMigration_2026_10_15_responsiveColumns
1549
1600
  ];
1550
1601
  function runTokensCssMigrations(css) {
1551
1602
  return foldMigrations(css, () => true);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CURRENT_COMPONENT_SCHEMA_VERSION,
3
3
  runMigrations
4
- } from "./chunk-ONYAIXCZ.js";
4
+ } from "./chunk-QQASYPW7.js";
5
5
 
6
6
  // vite-plugin/files/versionedFileResourceServer.ts
7
7
  import fs from "fs";
@@ -1258,6 +1258,28 @@ var colorsAndTypeMigration_2026_09_21_washColorAndOpacity = {
1258
1258
  }
1259
1259
  };
1260
1260
 
1261
+ // src/editor/core/themes/migrations/2026-10-15-responsive-columns.ts
1262
+ var RENAMES8 = {
1263
+ "--columns-gutter": "--columns-desktop-gutter",
1264
+ "--columns-margin": "--columns-desktop-margin"
1265
+ };
1266
+ var SHIPPED = {
1267
+ "--columns-count": ["12"],
1268
+ "--columns-gutter": ["32px"],
1269
+ "--columns-margin": ["0px", "0"]
1270
+ };
1271
+ var colorsAndTypeMigration_2026_10_15_responsiveColumns = {
1272
+ id: "2026-10-15-responsive-columns",
1273
+ fromVersion: 9,
1274
+ toVersion: 10,
1275
+ appliesTo: "colors-and-type",
1276
+ apply(rawVars) {
1277
+ return Object.fromEntries(
1278
+ Object.entries(rawVars).filter(([name, value]) => !SHIPPED[name]?.includes(value.trim())).map(([name, value]) => [RENAMES8[name] ?? name, value])
1279
+ );
1280
+ }
1281
+ };
1282
+
1261
1283
  // src/editor/core/themes/migrations/2026-09-21-scrim-surface.ts
1262
1284
  var STOPS2 = {
1263
1285
  "--scrim-opacity-low": "--scrim-low",
@@ -1296,7 +1318,7 @@ var componentMigration_2026_09_21_scrimSurface = {
1296
1318
  };
1297
1319
 
1298
1320
  // src/editor/core/themes/migrations/2026-09-13-cornerbadge-prefix.ts
1299
- var RENAMES8 = {
1321
+ var RENAMES9 = {
1300
1322
  cornerbadge: {
1301
1323
  "--corner-badge-margin": "--cornerbadge-margin",
1302
1324
  "--corner-badge-outer-radius": "--cornerbadge-outer-radius",
@@ -1346,7 +1368,7 @@ var componentMigration_2026_09_13_cornerbadgePrefix = {
1346
1368
  toVersion: 32,
1347
1369
  appliesTo: "component-config",
1348
1370
  apply(rawVars, meta) {
1349
- const renames = meta.component ? RENAMES8[meta.component] : void 0;
1371
+ const renames = meta.component ? RENAMES9[meta.component] : void 0;
1350
1372
  if (!renames) return { ...rawVars };
1351
1373
  const out = {};
1352
1374
  for (const [key, value] of Object.entries(rawVars)) {
@@ -1357,7 +1379,7 @@ var componentMigration_2026_09_13_cornerbadgePrefix = {
1357
1379
  };
1358
1380
 
1359
1381
  // src/editor/core/themes/migrations/2026-09-13-toggle-label.ts
1360
- var RENAMES9 = {
1382
+ var RENAMES10 = {
1361
1383
  toggle: {
1362
1384
  "--toggle-label-text": "--toggle-label",
1363
1385
  "--toggle-disabled-label-text": "--toggle-disabled-label"
@@ -1369,7 +1391,7 @@ var componentMigration_2026_09_13_toggleLabel = {
1369
1391
  toVersion: 33,
1370
1392
  appliesTo: "component-config",
1371
1393
  apply(rawVars, meta) {
1372
- const renames = meta.component ? RENAMES9[meta.component] : void 0;
1394
+ const renames = meta.component ? RENAMES10[meta.component] : void 0;
1373
1395
  if (!renames) return { ...rawVars };
1374
1396
  const out = {};
1375
1397
  for (const [key, value] of Object.entries(rawVars)) {
@@ -1380,7 +1402,7 @@ var componentMigration_2026_09_13_toggleLabel = {
1380
1402
  };
1381
1403
 
1382
1404
  // src/editor/core/themes/migrations/2026-09-13-collapsiblesection-open.ts
1383
- var RENAMES10 = {
1405
+ var RENAMES11 = {
1384
1406
  collapsiblesection: {
1385
1407
  "--collapsiblesection-chromeless-expanded-padding": "--collapsiblesection-chromeless-open-padding",
1386
1408
  "--collapsiblesection-hairline-expanded-padding": "--collapsiblesection-hairline-open-padding",
@@ -1394,7 +1416,7 @@ var componentMigration_2026_09_13_collapsiblesectionOpen = {
1394
1416
  toVersion: 34,
1395
1417
  appliesTo: "component-config",
1396
1418
  apply(rawVars, meta) {
1397
- const renames = meta.component ? RENAMES10[meta.component] : void 0;
1419
+ const renames = meta.component ? RENAMES11[meta.component] : void 0;
1398
1420
  if (!renames) return { ...rawVars };
1399
1421
  const out = {};
1400
1422
  for (const [key, value] of Object.entries(rawVars)) {
@@ -1421,7 +1443,7 @@ var BADGE_SUFFIXES = [
1421
1443
  "icon-size"
1422
1444
  ];
1423
1445
  var CORNERBADGE_SUFFIXES = ["surface", "border", "text"];
1424
- var RENAMES11 = {
1446
+ var RENAMES12 = {
1425
1447
  badge: Object.fromEntries(
1426
1448
  BADGE_SUFFIXES.map((s) => [`--badge-primary-${s}`, `--badge-brand-${s}`])
1427
1449
  ),
@@ -1435,7 +1457,7 @@ var componentMigration_2026_09_13_badgeBrand = {
1435
1457
  toVersion: 35,
1436
1458
  appliesTo: "component-config",
1437
1459
  apply(rawVars, meta) {
1438
- const renames = meta.component ? RENAMES11[meta.component] : void 0;
1460
+ const renames = meta.component ? RENAMES12[meta.component] : void 0;
1439
1461
  if (!renames) return { ...rawVars };
1440
1462
  const out = {};
1441
1463
  for (const [key, value] of Object.entries(rawVars)) {
@@ -1493,7 +1515,8 @@ var MIGRATIONS = [
1493
1515
  componentMigration_2026_09_20_imagelightboxScrim,
1494
1516
  componentMigration_2026_09_20_scrimColorAndOpacity,
1495
1517
  colorsAndTypeMigration_2026_09_21_washColorAndOpacity,
1496
- componentMigration_2026_09_21_scrimSurface
1518
+ componentMigration_2026_09_21_scrimSurface,
1519
+ colorsAndTypeMigration_2026_10_15_responsiveColumns
1497
1520
  ];
1498
1521
  function countFor(kind) {
1499
1522
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;