@getvitops/generator 0.6.0 → 0.8.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/CHANGELOG.md ADDED
@@ -0,0 +1,148 @@
1
+ # @getvitops/generator
2
+
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **New: `<wc-theme-editor>`, a live theme editor you can ship with your site.**
8
+
9
+ Tune the whole design system in the browser — palette, semantic roles, type roles, spacing, layout,
10
+ pattern geometry, radii, shadows — with no rebuild. Edits are layered as `:root` custom-property
11
+ overrides, persist to localStorage, and export as CSS or as a `design-system.json` patch. It follows
12
+ your site's colour scheme and drives the same `data-theme` + storage key as `<color-scheme-toggle>`,
13
+ so the two no longer fight.
14
+
15
+ It ships as a **separate, opt-in bundle** (`@getvitops/core/editor`, ~13 kB, no Lit) and is never
16
+ registered in `elements.js`: a page that doesn't ask for it pays nothing.
17
+
18
+ ```js
19
+ // astro.config.mjs
20
+ getvitops({
21
+ css: { input: 'design-system.json', format: 'css', out: 'src/styles' },
22
+ editor: true,
23
+ });
24
+ ```
25
+
26
+ ```html
27
+ <!-- anywhere in your layout -->
28
+ <wc-theme-editor></wc-theme-editor>
29
+ ```
30
+
31
+ `editor: true` copies `editor.js` into `public/vitops/`, loads it from `<Head />`, and mirrors
32
+ `design-manifest.json` to `/vitops/design-manifest.json` (override with the `manifest` attribute).
33
+ Outside Astro, load the bundle yourself and point `manifest` at the file.
34
+
35
+ **Save straight back to your config, in dev.** `@getvitops/vite` now serves a dev-only
36
+ `/__vitops/design-system` endpoint: the editor POSTs its patch, the plugin deep-merges it into your
37
+ `design-system.json`, validates the _merged_ result, writes it back preserving the file's formatting,
38
+ then regenerates and reloads. The endpoint exists only under `vite dev` — on a static deploy the
39
+ editor detects its absence and hides the button, while everything else still works.
40
+
41
+ **Added:** `colors.roleTokens` in `design-manifest.json` — the functional token set (bg / border /
42
+ solid / on-solid / text / emphasis stops) precomputed per hue, in `default` and `surface` variants for
43
+ both appearances. Re-pointing a role at another hue needs these: `solid` is chosen by scanning the hue
44
+ and `on-solid` is a computed contrast value, so neither is derivable by a browser client.
45
+
46
+ **Removed:** the dead `interaction` block from `design-manifest.json` — a hardcoded
47
+ `{duration, easing}` literal with no schema key, no reverse-index entry, and no corresponding CSS
48
+ variable. Nothing could have consumed it meaningfully. The real animation knobs are
49
+ `--animation-duration-*` / `--custom-ease-*`.
50
+
51
+ **Fixed:** a `[popover]` reset in `popover.css` was stripping the background, padding and border from
52
+ any pattern used as a popover. It is imported after `drawer.css`, so at equal specificity it beat
53
+ `.drawer` — and `dialog` (0-0-1) too — leaving a `.drawer[popover]` transparent and unpadded despite
54
+ drawer.css documenting popover as supported. The reset now sits in `:where()` at zero specificity, so
55
+ it still overrides the UA stylesheet but any pattern class takes its surface back. Open/closed
56
+ behaviour is unchanged.
57
+
58
+ **Added:** `input[type="range"]` and `input[type="color"]` now have baseline styling in `forms.css`
59
+ (accent colour from `--ui-primary-solid`; the colour swatch picks up the control border and radius).
60
+
61
+ ### Patch Changes
62
+
63
+ - @getvitops/utils@0.8.0
64
+
65
+ ## 0.7.0
66
+
67
+ ### Patch Changes
68
+
69
+ - @getvitops/utils@0.7.0
70
+
71
+ ## 0.6.0
72
+
73
+ ### Minor Changes
74
+
75
+ - 2cc847d: Package-resident agent skill + `vitops docs`:
76
+ - `@getvitops/cli` now ships the `vitops-design-system` agent skill inside the package
77
+ (`skill/SKILL.md`). `vitops agents` no longer emits a generated skill into the repo — it
78
+ symlinks `.agents/skills/` and `.claude/skills/` entries to the installed package (logical
79
+ `node_modules/@getvitops/cli/skill` target, surviving version bumps) and writes the
80
+ AGENTS.md pointer block. Old generated-skill directories are migrated automatically;
81
+ `--docs-dir` keeps the emit-files layout.
82
+ - New `vitops docs [topic]` command prints reference docs to stdout, rendered live from the
83
+ project's `design-system.json` (topics: classes, authoring, formats, color, scales,
84
+ patterns, elements; `--all` concatenates).
85
+ - `renderSkill()` removed from `@getvitops/generator` (superseded by the packaged skill).
86
+
87
+ ### Patch Changes
88
+
89
+ - @getvitops/utils@0.6.0
90
+
91
+ ## 0.5.0
92
+
93
+ ### Minor Changes
94
+
95
+ - Ship design-system context to downstream agents:
96
+ - JSON Schema descriptions: every `design-system.json` and site-config field now carries a
97
+ `description` (authored in the zod schemas via `desc()`), emitted into `schema.json` /
98
+ `site.schema.json` for editor hovers and agent consumption.
99
+ - New generated OKF docs: `authoring.md` (field reference walked from the JSON Schema),
100
+ `formats.md` (tailwind vs css vs bricks, including the TW_CLASH utilities Tailwind
101
+ provides natively), and `concepts/{color,scales,patterns}.md` (seeded OKLCH colour
102
+ system, fluid modular scales, pattern token cascade + override hooks).
103
+ - `vitops agents` now emits a generated `vitops-design-system` agent skill into
104
+ `.agents/skills/vitops-design-system/` (SKILL.md + the docs bundle as `references/`,
105
+ with an idempotent `.claude/skills/` symlink) and writes a compact pointer block into
106
+ `AGENTS.md`. Pass `--docs-dir` for the legacy docs-only layout.
107
+ - `TW_CLASH` and `BASE_HOOK` are exported from `@getvitops/generator`.
108
+
109
+ ### Patch Changes
110
+
111
+ - @getvitops/utils@0.5.0
112
+
113
+ ## 0.4.0
114
+
115
+ ### Patch Changes
116
+
117
+ - Updated dependencies [d7e6491]
118
+ - @getvitops/utils@0.4.0
119
+
120
+ ## 0.3.0
121
+
122
+ ### Patch Changes
123
+
124
+ - Updated dependencies
125
+ - @getvitops/utils@0.3.0
126
+
127
+ ## 0.2.1
128
+
129
+ ### Patch Changes
130
+
131
+ - d28aae7: Fix Tailwind output: the `.centered > *` default (`grid-column: measure`) was emitted unlayered,
132
+ which in Tailwind v4 outranks every layer — so track utilities (`.spotlight`/`.breakout`/
133
+ `.fullbleed`) never overrode it and all `.centered` children fell back to `measure`. Emit the
134
+ structural rules (and the animation engine + patterns) in `@layer components` so the track/spacing
135
+ `@utility` classes (utilities layer) win.
136
+ - @getvitops/utils@0.2.1
137
+
138
+ ## 0.2.0
139
+
140
+ ### Minor Changes
141
+
142
+ - Redesign the colour system: seeded OKLCH tonal scales plus functional semantic tokens
143
+ (`bg`/`text`/`solid`/`on-solid`, `muted`/`bold`), with named-alias back-compat. Updates the
144
+ framework CSS, the schema, and the generated docs to the new token model.
145
+
146
+ ### Patch Changes
147
+
148
+ - @getvitops/utils@0.2.0
package/README.md CHANGED
@@ -33,3 +33,9 @@ await generate({
33
33
  | `bricks` | `styles.min.css`, `bricks-colors-*.json`, `bricks-variables.json`, `tokens.json`, JS, `bricks/`, `docs/` |
34
34
 
35
35
  See the [`design-system.json` schema](./schema.json) for the config shape.
36
+
37
+ ## Changelog
38
+
39
+ This package's history: [`CHANGELOG.md`](./CHANGELOG.md) (shipped in the npm tarball, so it
40
+ also reads from `node_modules/@getvitops/generator/CHANGELOG.md`). `@getvitops/core`, `generator`,
41
+ `utils`, `cli`, `vite` and `astro` share one version and are released together.
@@ -8,6 +8,16 @@
8
8
  font-size: 100% !important;
9
9
  }
10
10
 
11
+ /* Drop the UA's 8px body margin. The framework owns page gutters via `.centered`
12
+ (--gutter), so the UA default just offsets every full-bleed surface — sticky
13
+ headers and `bg-*` bands end up inset by 8px with a sliver of canvas showing
14
+ around them. This is the only UA reset the framework makes: it deliberately
15
+ does NOT ship a general reset (no global box-sizing change), because that
16
+ would silently reflow existing consumer layouts. */
17
+ body {
18
+ margin: 0;
19
+ }
20
+
11
21
  @media (prefers-reduced-motion: no-preference) {
12
22
  html {
13
23
  scrollbar-gutter: stable;
@@ -56,3 +56,4 @@
56
56
  @import './patterns/nav.css';
57
57
  @import './patterns/carousel.css';
58
58
  @import './patterns/copy.css';
59
+ @import './patterns/theme-editor.css';
@@ -3,10 +3,10 @@
3
3
  * Consumes the generated token cascade (src/css/generated/tokens.css).
4
4
  */
5
5
 
6
- /* ── Inline code chip — prose <code> that isn't inside a <pre>. Element-level at
7
- zero specificity (like the schema-generated button/link patterns) so bare
6
+ /* ── Inline code — prose <code> that isn't inside a <pre>. Element-level at
7
+ zero specificity (like the schema-generated btn/link patterns) so bare
8
8
  <code> needs no class and any explicit class overrides it. .font-code styles
9
- type only; this adds the chip. ── */
9
+ type only; this adds the boxed treatment. ── */
10
10
  :where(:not(pre) > code) {
11
11
  font-family: var(--font-mono);
12
12
  font-size: 0.85em;
@@ -90,6 +90,37 @@ fieldset.fieldset,
90
90
  background: var(--surface-bg);
91
91
  }
92
92
 
93
+ /* ── Range + colour controls ───────────────────────────────────────────────── */
94
+ /* `accent-color` is the whole job for range: it themes the track fill and thumb
95
+ * natively, in both appearances, with no pseudo-element rewriting. The colour
96
+ * swatch only needs its chrome removed so the well fills the control box. */
97
+ input[type='range'] {
98
+ accent-color: var(--range-accent, var(--ui-primary-solid));
99
+ inline-size: 100%;
100
+ min-inline-size: 0;
101
+ }
102
+
103
+ input[type='color'] {
104
+ --_br: var(--br-input, var(--br-control, var(--br-default)));
105
+
106
+ inline-size: var(--color-swatch-size, 2rem);
107
+ block-size: var(--color-swatch-size, 2rem);
108
+ padding: 0;
109
+ border: var(--b-input, var(--b-control, var(--b-default)));
110
+ border-radius: var(--_br);
111
+ background: none;
112
+ cursor: pointer;
113
+
114
+ &::-webkit-color-swatch-wrapper {
115
+ padding: 2px;
116
+ }
117
+ &::-webkit-color-swatch,
118
+ &::-moz-color-swatch {
119
+ border: none;
120
+ border-radius: calc(var(--_br) - 2px);
121
+ }
122
+ }
123
+
93
124
  /* ── Input group — input flanked by icons/addons ───────────────────────────── */
94
125
  .input-group {
95
126
  --_br: var(--br-input-group, var(--br-control, var(--br-default)));
@@ -3,7 +3,7 @@
3
3
  * Consumes the generated token cascade (src/css/generated/tokens.css).
4
4
  */
5
5
 
6
- /* ── List family — base list, facets, filtered search, virtual, chips ─────── */
6
+ /* ── List family — base list, facets, filtered search, virtual, tag list ──── */
7
7
  .list {
8
8
  --_p: var(--p-list, var(--p-list-group, var(--p-default)));
9
9
  --_b: var(--b-list, var(--b-list-group, var(--b-default)));
@@ -216,11 +216,15 @@
216
216
  }
217
217
  }
218
218
 
219
- .chip-list {
220
- --_p: var(--p-chip-list, var(--p-control, var(--p-default)));
221
- --_b: var(--b-chip-list, var(--b-control, var(--b-default)));
222
- --_br: var(--br-chip-list, var(--br-control, var(--br-default)));
223
- --_fs: var(--fs-chip-list, var(--fs-control, var(--fs-default)));
219
+ /* ── Tag list — a bordered field of dismissable tags plus a free-text input.
220
+ Items are the generated `.tag` pattern (+ `.tag__remove` from tag.css): a tag is
221
+ the editable/dismissable label, a badge is the static one — so this needs no
222
+ parallel item styling of its own. ── */
223
+ .tag-list {
224
+ --_p: var(--p-tag-list, var(--p-control, var(--p-default)));
225
+ --_b: var(--b-tag-list, var(--b-control, var(--b-default)));
226
+ --_br: var(--br-tag-list, var(--br-control, var(--br-default)));
227
+ --_fs: var(--fs-tag-list, var(--fs-control, var(--fs-default)));
224
228
 
225
229
  display: flex;
226
230
  flex-wrap: wrap;
@@ -232,31 +236,7 @@
232
236
  align-items: center;
233
237
  font-size: var(--_fs);
234
238
 
235
- .chip-list__chip {
236
- display: inline-flex;
237
- align-items: center;
238
- gap: 0.25rem;
239
- padding: 0.25rem 0.5rem;
240
- border-radius: var(--br-chip, var(--br-tag, 0.25rem));
241
- font-size: 0.875rem;
242
- background: var(--color-surface-muted);
243
- }
244
-
245
- .chip-list__chip-remove {
246
- padding: 0;
247
- background: transparent;
248
- border: none;
249
- cursor: pointer;
250
- opacity: 0.6;
251
- line-height: 1;
252
- transition: opacity 0.15s ease;
253
-
254
- &:hover {
255
- opacity: 1;
256
- }
257
- }
258
-
259
- .chip-list__input {
239
+ .tag-list__input {
260
240
  flex: 1;
261
241
  min-inline-size: 6rem;
262
242
  border: none;
@@ -266,7 +246,7 @@
266
246
  }
267
247
 
268
248
  &:focus-within {
269
- outline: 2px solid var(--chip-list-focus-color, var(--color-brand-primary-muted));
249
+ outline: 2px solid var(--tag-list-focus-color, var(--color-brand-primary-muted));
270
250
  outline-offset: 2px;
271
251
  }
272
252
  }
@@ -4,14 +4,31 @@
4
4
  */
5
5
 
6
6
  /* ── Popover — native Popover API reset + anchored position variants ───────── */
7
- [popover] {
7
+
8
+ /**
9
+ * The UA gives `[popover]` a padding, border and canvas background; a bare
10
+ * popover wants none of that. But this partial is imported *after* drawer.css /
11
+ * dialog.css, so at plain `[popover]` specificity (0-1-0) the reset also beat
12
+ * `.drawer` (0-1-0, earlier) and `dialog` (0-0-1) — silently stripping the
13
+ * surface off any pattern used as a popover, which is exactly what drawer.css
14
+ * documents itself as supporting.
15
+ *
16
+ * So the reset sits in `:where()` at zero specificity: it still overrides the UA
17
+ * stylesheet, and *any* explicit class takes it back. Same mechanism the `btn`
18
+ * pattern uses with `:where(button, .btn)`. Keep the visual reset here and the
19
+ * open/closed behaviour below — that must stay at real specificity so a
20
+ * component's own rules can't accidentally reveal a closed popover.
21
+ */
22
+ :where([popover]) {
8
23
  padding: 0;
9
24
  border: none;
10
25
  background: transparent;
11
26
  color: inherit;
12
27
  overflow: visible;
13
28
  inset: auto;
29
+ }
14
30
 
31
+ [popover] {
15
32
  &:popover-open {
16
33
  opacity: 1;
17
34
  }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Theme editor — chrome for `<wc-theme-editor>` (@getvitops/core/editor).
3
+ *
4
+ * Deliberately thin: the panel is a `.drawer.drawer--right` popover, its sections
5
+ * are `.details`, its controls come from `forms.css` and its buttons from the
6
+ * generated `btn`/`cta` patterns. What's left here is only what those don't cover
7
+ * — the launcher's fixed position, the label/control row, and the density the
8
+ * panel needs to fit a whole design system in a sidebar.
9
+ *
10
+ * This partial is imported by the bundle like any other, so a consumer who never
11
+ * loads the editor bundle still pays for it (~1KB) but sees nothing: every rule is
12
+ * scoped under `wc-theme-editor`, which only exists once the element is defined.
13
+ */
14
+
15
+ wc-theme-editor {
16
+ /* Density: the panel packs ~200 controls, so it runs a step down from body. */
17
+ --_fs: var(--text-xs, 0.78rem);
18
+
19
+ .ed-launch {
20
+ position: fixed;
21
+ inset-block-end: 1rem;
22
+ inset-inline-end: 1rem;
23
+ z-index: var(--z-tier-top, 100);
24
+ }
25
+
26
+ .ed-panel {
27
+ --drawer-max-inline-size: min(28rem, 100vw);
28
+
29
+ overflow-y: auto;
30
+ padding: 1rem;
31
+ font-size: var(--_fs);
32
+ }
33
+
34
+ /* Sections: the drawer supplies the surface, so these only need separation. */
35
+ .ed-section {
36
+ border-block-start: var(--b-default);
37
+ padding-block-start: 0.5rem;
38
+ }
39
+ .ed-section > summary {
40
+ padding-block: 0.35rem;
41
+ }
42
+ .ed-sub {
43
+ border: var(--b-default);
44
+ border-radius: var(--br-default);
45
+ padding: 0.4rem 0.6rem;
46
+ }
47
+
48
+ /* A control row: fixed-width var name, control takes the rest. */
49
+ .ed-row {
50
+ display: flex;
51
+ align-items: center;
52
+ gap: 0.5rem;
53
+ }
54
+ .ed-label {
55
+ flex: 0 0 8.5rem;
56
+ overflow: hidden;
57
+ font-family: var(--font-mono, monospace);
58
+ font-size: 0.9em;
59
+ color: var(--surface-text-x-muted);
60
+ text-overflow: ellipsis;
61
+ white-space: nowrap;
62
+ }
63
+ .ed-input {
64
+ flex: 1;
65
+ min-inline-size: 0;
66
+ padding: 0.3em 0.5em;
67
+ border: var(--b-default);
68
+ border-radius: var(--br-default);
69
+ background: var(--surface-bg);
70
+ color: inherit;
71
+ font: inherit;
72
+ }
73
+ .ed-mono {
74
+ font-family: var(--font-mono, monospace);
75
+ }
76
+ .ed-pair {
77
+ flex: 1;
78
+ display: flex;
79
+ align-items: center;
80
+ gap: 0.4rem;
81
+ min-inline-size: 0;
82
+ }
83
+ .ed-color {
84
+ flex: 0 0 auto;
85
+ --color-swatch-size: 1.8rem;
86
+ }
87
+ .ed-out {
88
+ flex: 0 0 4.5rem;
89
+ font-family: var(--font-mono, monospace);
90
+ font-size: 0.9em;
91
+ text-align: end;
92
+ }
93
+
94
+ /* Toolbar: a segmented light/dark pair plus actions. */
95
+ .ed-toolbar {
96
+ flex-wrap: wrap;
97
+ gap: 0.4rem;
98
+ position: sticky;
99
+ inset-block-start: 0;
100
+ z-index: 1;
101
+ padding-block: 0.5rem;
102
+ background: var(--surface-bg);
103
+ }
104
+ .ed-segwrap {
105
+ display: inline-flex;
106
+ }
107
+ .ed-seg.is-active {
108
+ background: var(--ui-primary-solid);
109
+ color: var(--ui-primary-on-solid);
110
+ }
111
+ .ed-danger {
112
+ color: var(--danger-text);
113
+ }
114
+ }
@@ -0,0 +1,2 @@
1
+ const e=`vitops:ds-overrides`,t=`/__vitops/design-system`,n=(e,t)=>t.startsWith(`stop-`)?`--color-${e}-${t.slice(5)}`:`--${e}-${t}`,r=(e,t)=>`--color-${e}-${t}`;var i=class extends HTMLElement{constructor(...e){super(...e),this.store={light:new Map,dark:new Map},this.roles=new Map,this.roleVars=new Set,this.syncers=new Set,this.scheme=`light`,this.canSave=!1}static{this.observedAttributes=[`manifest`]}connectedCallback(){this.boot()}async boot(){let e=this.getAttribute(`manifest`)??`/vitops/design-manifest.json`;try{let t=await fetch(e);if(!t.ok)throw Error(`manifest ${t.status}`);this.manifest=await t.json()}catch(t){console.warn(`[wc-theme-editor] manifest unavailable at ${e} — editor disabled`,t);return}this.styleEl=document.createElement(`style`),this.styleEl.id=`ds-overrides`,document.head.append(this.styleEl),this.hydrate(),this.render(),this.scheme=this.currentScheme(),new MutationObserver(()=>{let e=this.currentScheme();e!==this.scheme&&(this.scheme=e,this.syncers.forEach(e=>e()))}).observe(document.documentElement,{attributes:!0,attributeFilter:[`data-theme`]}),this.canSave=await this.probeSave(),this.build(this.manifest)}async probeSave(){try{let e=await fetch(t);return e.ok?(await e.json()).writable===!0:!1}catch{return!1}}block(e,t){return t.size?`${e} {\n${[...t].map(([e,t])=>` ${e}: ${t};`).join(`
2
+ `)}\n}\n`:``}serializeCSS(){return this.block(`:root`,this.store.light)+this.block(`:root[data-brx-theme="dark"], :root[data-theme="dark"]`,this.store.dark)}render(){this.styleEl&&(this.styleEl.textContent=this.serializeCSS())}persist(){try{localStorage.setItem(e,JSON.stringify({light:[...this.store.light],dark:[...this.store.dark],roles:[...this.roles]}))}catch{}}hydrate(){try{let t=localStorage.getItem(e);if(!t)return;let n=JSON.parse(t);this.store.light=new Map(n.light??[]),this.store.dark=new Map(n.dark??[]),this.roles=new Map(n.roles??[]);for(let[e,t]of this.roles)this.markRoleVars(e,t)}catch{}}setOverride(e,t,n){let r=this.store[n];t==null||t===``?r.delete(e):r.set(e,t),this.render(),this.persist()}effective(e,t,n){return this.store[t].has(e)?this.store[t].get(e):t===`dark`&&this.store.light.has(e)?this.store.light.get(e):n}reset(){this.store.light.clear(),this.store.dark.clear(),this.roles.clear(),this.roleVars.clear(),this.render(),this.persist(),this.syncers.forEach(e=>e())}currentScheme(){let e=document.documentElement;return e.dataset.theme===`dark`||e.getAttribute(`data-brx-theme`)===`dark`?`dark`:`light`}setScheme(e){this.scheme=e,document.documentElement.dataset.theme=e,document.documentElement.style.colorScheme=`${e} only`;try{localStorage.setItem(`vitops-color-scheme`,e)}catch{}this.syncers.forEach(e=>e())}roleTokenNames(e,t,r){let i=t===`surface`?`surface`:`default`,a=e.colors.roleTokens?.[r]?.[i];if(!a)return[];let o=[];for(let e of[`light`,`dark`])for(let[r,i]of Object.entries(a[e]))o.push([n(t,r),i,e]);return o}markRoleVars(e,t){if(this.manifest)for(let[n]of this.roleTokenNames(this.manifest,e,t))this.roleVars.add(n)}remapRole(e,t,n){let r=this.roleTokenNames(e,t,n);if(r.length){this.roles.set(t,n);for(let[e,t,n]of r)this.roleVars.add(e),this.store[n].set(e,t);this.render(),this.persist()}}deepSet(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e];(typeof i[t]!=`object`||i[t]==null)&&(i[t]={}),i=i[t]}i[r[r.length-1]]=n}buildPatch(e){let t={},n=[];for(let[e,n]of this.roles)this.deepSet(t,`colors.roles.${e}`,n);for(let[r,i]of this.store.light){if(this.roleVars.has(r))continue;let a=e.reverseIndex[r];a?this.deepSet(t,a,i):n.push(r)}for(let e of this.store.dark.keys())this.roleVars.has(e)||n.push(`${e} (dark)`);return{patch:t,skipped:n}}el(e,t={},n=[]){let r=document.createElement(e),i=r;for(let[e,n]of Object.entries(t))n===!0?i.setAttribute(e,``):n!==!1&&i.setAttribute(e,String(n));for(let e of n)i.append(e);return r}row(e,t,n){return this.syncers.add(n),n(),this.el(`label`,{class:`ed-row`},[this.el(`span`,{class:`ed-label`,title:e},[e.replace(/^--/,``)]),t])}textInput(e,t,n=``){let r=this.el(`input`,{type:`text`,class:`ed-input`});return r.addEventListener(`input`,()=>this.setOverride(e,r.value.trim()||null,this.scheme)),this.row(e,r,()=>{r.value=this.store[this.scheme].get(e)??``,r.placeholder=n||t})}colorInput(e,t){let n=this.el(`input`,{type:`color`,class:`ed-color`}),r=this.el(`input`,{type:`text`,class:`ed-input ed-mono`}),i=t=>this.setOverride(e,t||null,`light`);n.addEventListener(`input`,()=>{r.value=n.value,i(n.value)}),r.addEventListener(`input`,()=>{/^#[0-9a-f]{6}$/i.test(r.value)&&(n.value=r.value),i(r.value.trim())});let a=this.el(`span`,{class:`ed-pair`},[n,r]);return this.row(e,a,()=>{let i=this.store.light.get(e)??t;r.value=i,/^#[0-9a-f]{6}$/i.test(i)&&(n.value=i)})}selectInput(e,t){let n=this.el(`select`,{class:`ed-input`});n.append(this.el(`option`,{value:``},[`— default —`]));for(let e of t)n.append(this.el(`option`,{value:e.value},[e.label]));return n.addEventListener(`change`,()=>this.setOverride(e,n.value||null,this.scheme)),this.row(e,n,()=>{n.value=this.store[this.scheme].get(e)??``})}remSlider(e,t){let n=parseFloat(t)||1,r=this.el(`input`,{type:`range`,class:`ed-range`,min:`0`,max:String(Math.max(4,Math.ceil(n*2))),step:`0.05`}),i=this.el(`output`,{class:`ed-out`});r.addEventListener(`input`,()=>{i.textContent=`${r.value}rem`,this.setOverride(e,`${r.value}rem`,this.scheme)});let a=this.el(`span`,{class:`ed-pair`},[r,i]);return this.row(e,a,()=>{r.value=String(parseFloat(this.effective(e,this.scheme,t))||n),i.textContent=this.store[this.scheme].get(e)??`auto`})}slider(e,t){let n=t.toValue??(e=>`${e}${t.unit??``}`),r=t.fromValue??(e=>Number.isNaN(parseFloat(e))?t.def:parseFloat(e)),i=this.el(`input`,{type:`range`,class:`ed-range`,min:String(t.min),max:String(t.max),step:String(t.step)}),a=this.el(`output`,{class:`ed-out`});i.addEventListener(`input`,()=>{let t=n(parseFloat(i.value));a.textContent=t,this.setOverride(e,t,this.scheme)});let o=this.el(`span`,{class:`ed-pair`},[i,a]);return this.row(e,o,()=>{let n=this.store[this.scheme].get(e);i.value=String(n==null?t.def:r(n)),a.textContent=n??`${t.def}${t.unit??``}`})}section(e,t=!1){let n=this.el(`div`,{class:`ed-body rhythm`});return{details:this.el(`details`,{class:`details ed-section`,...t?{open:!0}:{}},[this.el(`summary`,{class:`font-eyebrow`},[e]),n]),body:n}}hint(e){return this.el(`p`,{class:`font-footnote text-surface-x-muted`},[e])}sub(e){let t=this.section(e);return t.details.classList.add(`ed-sub`),t}buildPalette(e){let{details:t,body:n}=this.section(`Palette`,!0);n.append(this.hint(`Hues feed the semantic roles below — edit a hue and every role mapped to it follows. Hue edits are scheme-global: dark mode re-points which step a token reads, it never redefines the hue itself.`));for(let t of e.colors.ramps){let i=this.sub(t);for(let n of e.colors.steps){let a=e.colors.palette[t]?.[n];a!=null&&i.body.append(this.colorInput(r(t,n),a))}n.append(i.details)}return n.append(this.buildRoles(e)),t}buildRoles(e){let{details:t,body:n}=this.sub(`Semantic roles`);n.append(this.hint(`Point a role at another hue — its whole functional token set (bg / border / solid / on-solid / text) is rewritten for both appearances.`));let r=e.colors.ramps;for(let{name:t,ramp:i}of e.colors.roles){let a=this.el(`select`,{class:`ed-input`});for(let e of r)a.append(this.el(`option`,{value:e},[e]));a.addEventListener(`change`,()=>this.remapRole(e,t,a.value)),n.append(this.row(`--${t}`,a,()=>{a.value=this.roles.get(t)??i}))}return t}buildTypography(e){let{details:t,body:n}=this.section(`Typography`),r=Object.keys(e.fonts).map(e=>({label:e,value:`var(--font-${e})`})),i=e.scales.text.map(e=>({label:e.name,value:`var(--text-${e.name})`})),a={tt:[`none`,`uppercase`,`lowercase`,`capitalize`],fst:[`normal`,`italic`,`oblique`],td:[`none`,`underline`,`line-through`],tw:[`wrap`,`balance`,`pretty`,`nowrap`]};for(let t of e.typography.roles){let o=e.typography.specs[t]??{},s=this.sub(t);for(let[n,{key:c}]of Object.entries(e.typography.hooks)){let e=`--${t}-${n}`,l=o[c]==null?``:String(o[c]);n===`ff`?s.body.append(this.selectInput(e,r)):n===`fs`?s.body.append(this.selectInput(e,i)):a[n]?s.body.append(this.selectInput(e,a[n].map(e=>({label:e,value:e})))):s.body.append(this.textInput(e,l,l||c))}n.append(s.details)}return t}buildSpacing(e){let{details:t,body:n}=this.section(`Spacing`);n.append(this.hint(`Each step overrides to a fixed rem (dropping the fluid clamp). Reset restores it.`));for(let t of e.scales.space)n.append(this.remSlider(`--space-${t.name}`,t.max));return t}buildLayout(){let{details:e,body:t}=this.section(`Layout`);return t.append(this.hint(`Vertical rhythm and the .centered track widths — global structure.`)),t.append(this.slider(`--rhythm-scale`,{min:.5,max:2.5,step:.05,def:1}),this.slider(`--width-measure`,{min:30,max:110,step:1,def:65,unit:`ch`}),this.slider(`--width-breakout`,{min:40,max:150,step:1,def:90,unit:`ch`}),this.slider(`--width-spotlight`,{min:60,max:200,step:1,def:120,unit:`ch`}),this.slider(`--gutter`,{min:0,max:6,step:.1,def:3,toValue:e=>`clamp(1rem, 4cqi, ${e}rem)`,fromValue:e=>{let t=/clamp\([^,]+,[^,]+,\s*([\d.]+)/.exec(e);return t?parseFloat(t[1]):3}})),e}buildPatterns(e){let t=this.section(`Pattern defaults`);for(let[n,r]of Object.entries(e.patterns.defaults))t.body.append(this.textInput(`--${n}-default`,r,r));let n=this.section(`Radii`);for(let[t,r]of Object.entries(e.patterns.radii))n.body.append(this.textInput(`--br-${t}`,r,r));let r=this.section(`Pattern groups`);for(let[t,n]of Object.entries(e.patterns.groups)){let e=this.sub(t);for(let[r,i]of Object.entries(n))e.body.append(this.textInput(`--${r}-${t}`,i,i));r.body.append(e.details)}let i=this.section(`Components`);i.body.append(this.hint(`Per-component geometry — overrides the group defaults for just this component.`));for(let t of e.patterns.items){if(!t.wrappable.length)continue;let e=this.sub(t.name);for(let{sfx:n,prop:r}of t.wrappable){let i=t.base[r]??``;e.body.append(this.textInput(`--${n}-${t.name}`,i,i))}i.body.append(e.details)}let a=this.section(`Shadows`);for(let[t,n]of Object.entries(e.shadows))a.body.append(this.textInput(`--shadow-${t}`,n,n));return[t.details,n.details,r.details,i.details,a.details]}async flash(e,t){let n=e.textContent;e.textContent=t,setTimeout(()=>e.textContent=n,1400)}async copy(e,t){try{await navigator.clipboard.writeText(e),this.flash(t,`Copied ✓`)}catch{this.flash(t,`Copy failed`)}}async save(e,n){let{patch:r}=this.buildPatch(e);if(!Object.keys(r).length)return void this.flash(n,`Nothing to save`);try{let e=await fetch(t,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({patch:r})});if(!e.ok){let t=await e.json().catch(()=>({}));console.error(`[wc-theme-editor] save rejected`,t.errors??e.statusText),this.flash(n,`Rejected ✗`);return}this.reset(),this.flash(n,`Saved ✓`)}catch(e){console.error(`[wc-theme-editor] save failed`,e),this.flash(n,`Failed ✗`)}}buildToolbar(e){let t=this.el(`div`,{class:`cluster-start ed-toolbar`}),n=this.el(`button`,{type:`button`,class:`btn ed-seg`},[`Light`]),r=this.el(`button`,{type:`button`,class:`btn ed-seg`},[`Dark`]),i=()=>{n.classList.toggle(`is-active`,this.scheme===`light`),r.classList.toggle(`is-active`,this.scheme===`dark`)};this.syncers.add(i),n.addEventListener(`click`,()=>this.setScheme(`light`)),r.addEventListener(`click`,()=>this.setScheme(`dark`)),i(),t.append(this.el(`span`,{class:`ed-segwrap`,role:`group`},[n,r]));let a=this.el(`button`,{type:`button`,class:`btn`},[`Copy CSS`]);a.addEventListener(`click`,()=>this.copy(this.serializeCSS()||`/* no overrides yet */`,a));let o=this.el(`button`,{type:`button`,class:`btn`},[`Copy JSON patch`]);if(o.addEventListener(`click`,()=>{let{patch:t,skipped:n}=this.buildPatch(e),r=n.length?`\n// runtime-only (no source mapping): ${n.join(`, `)}`:``;this.copy(JSON.stringify(t,null,2)+r,o)}),t.append(a,o),this.canSave){let n=this.el(`button`,{type:`button`,class:`cta`},[`Save to source`]);n.addEventListener(`click`,()=>void this.save(e,n)),t.append(n)}let s=this.el(`button`,{type:`button`,class:`btn ed-danger`},[`Reset all`]);return s.addEventListener(`click`,()=>this.reset()),t.append(s),t}build(e){let t=`ds-editor-panel`,n=this.el(`div`,{id:t,popover:`auto`,class:`drawer drawer--right ed-panel bg-surface text-surface rhythm`,"aria-label":`Design-system editor`});n.append(this.el(`header`,{class:`cluster-between`},[this.el(`strong`,{class:`font-heading`},[`Theme editor`]),(()=>{let e=this.el(`button`,{type:`button`,class:`btn`,popovertarget:t,popovertargetaction:`hide`},[`×`]);return e.setAttribute(`aria-label`,`Close editor`),e})()]),this.buildToolbar(e),this.buildPalette(e),this.buildTypography(e),this.buildSpacing(e),this.buildLayout(),...this.buildPatterns(e));let r=this.el(`button`,{type:`button`,class:`cta ed-launch`,popovertarget:t},[`🎨 Theme`]);this.append(r,n)}};customElements.get(`wc-theme-editor`)||customElements.define(`wc-theme-editor`,i);
@@ -543,7 +543,7 @@ let Tt=!1;const Et=new Y.subtle.Watcher(async()=>{Tt||(Tt=!0,queueMicrotask(()=>
543
543
  >
544
544
  <span class=${e} part="icon" aria-hidden="true"></span>
545
545
  </button>
546
- `}};customElements.get(`copy-button`)||customElements.define(`copy-button`,Nt);var Pt=class extends ${static{this.properties={autoplay:{type:Number,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=!1;#r=!1;#i=null;#a=!1;#o=null;#s=!1;init(){this.autoplay=0}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.hasAttribute(`role`)||this.setAttribute(`role`,`region`),this.hasAttribute(`aria-roledescription`)||this.setAttribute(`aria-roledescription`,`carousel`),this.#e=[...this.children].filter(e=>!e.hasAttribute(`slot`)),!(this.#e.length<2)&&(this.#n=this.classList.contains(`carousel--auto-pages`),this.#n||(this.#c(),this.#d(),this.addEventListener(`scrollsnapchange`,this.#p)),!this.autoplay&&this.hasAttribute(`autoplay`)&&(this.autoplay=Number(this.getAttribute(`autoplay`))||0),this.#s=matchMedia(`(prefers-reduced-motion: reduce)`).matches,this.autoplay>0&&(this.#y(),this.#s?(this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()):this.#m(),this.addEventListener(`pointerenter`,this.#g),this.addEventListener(`pointerleave`,this.#_),this.addEventListener(`focusin`,this.#g),this.addEventListener(`focusout`,this.#_)))}disconnectedCallback(){super.disconnectedCallback(),this.#n||(this.removeEventListener(`scrollsnapchange`,this.#p),this.#u()),this.removeEventListener(`pointerenter`,this.#g),this.removeEventListener(`pointerleave`,this.#_),this.removeEventListener(`focusin`,this.#g),this.removeEventListener(`focusout`,this.#_),this.#h(),this.#o&&=(this.#o.removeEventListener(`click`,this.#v),this.#o.hasAttribute(`slot`)||this.#o.remove(),null),this.removeAttribute(`aria-live`)}#c(){let e=[],t=[];for(let n=0;n<this.#e.length;n++){let r=this.#e[n];e.push(this.#l(r,n)),t.push(this.#l(r,n))}for(let t=e.length-1;t>=0;t--)this.prepend(e[t]);for(let e of t)this.append(e);this.#t=[...e,...t]}#l(e,t){let n=e.cloneNode(!0);n.setAttribute(`data-carousel-clone`,String(t)),n.setAttribute(`aria-hidden`,`true`);for(let e of[n,...n.querySelectorAll(`[tabindex], a, button, input, select, textarea`)])e.tabIndex=-1;return n}#u(){for(let e of this.#t)e.remove();this.#t=[]}#d(){requestAnimationFrame(()=>{let e=this.#e[0];e&&(this.style.scrollBehavior=`auto`,this.scrollLeft=e.offsetLeft-this.offsetLeft-(parseFloat(getComputedStyle(this).scrollPaddingLeft)||0)+(parseFloat(getComputedStyle(this).paddingLeft)||0),requestAnimationFrame(()=>{this.style.scrollBehavior=``}))})}#f(){this.scrollBy({left:this.clientWidth,behavior:`smooth`})}#p=e=>{if(this.#r){this.#r=!1;return}let t=e.snapTargetInline;if(!t||!t.hasAttribute(`data-carousel-clone`))return;let n=Number(t.getAttribute(`data-carousel-clone`)),r=this.#e[n];if(!r)return;let i=r.offsetLeft-t.offsetLeft;this.#r=!0,this.style.scrollBehavior=`auto`,this.scrollLeft+=i,requestAnimationFrame(()=>{this.style.scrollBehavior=``})};#m(){this.#i||this.autoplay<=0||(this.#a=!1,this.#i=setInterval(()=>this.#f(),this.autoplay),this.setAttribute(`aria-live`,`off`),this.#b())}#h(){this.#i&&=(clearInterval(this.#i),null)}#g=()=>{this.#h(),this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()};#_=()=>{this.#s||this.#m()};#v=()=>{this.#a?(this.#s=!1,this.#m()):this.#g()};#y(){let e=this.querySelector(`[slot="autoplay"]`);if(e)this.#o=e;else{let e=document.createElement(`button`);e.type=`button`,this.append(e),this.#o=e}this.#o.setAttribute(`part`,`autoplay`),this.#o.addEventListener(`click`,this.#v),this.#b()}#b(){this.#o&&(this.#o.setAttribute(`aria-label`,this.#a?`Play`:`Pause`),this.#o.setAttribute(`aria-pressed`,String(!this.#a)),this.#o.hasAttribute(`slot`)||(this.#o.textContent=this.#a?`▶`:`⏸`))}};customElements.get(`wc-carousel`)||customElements.define(`wc-carousel`,Pt);var Ft=class extends ${static{this.properties={breakpoint:{type:String,reflect:!0},projection:{type:Boolean,reflect:!0},singular:{type:Boolean,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=[];#r=null;#i=null;#a=null;#o=[];#s=[];#c=0;#l=!1;#u=null;#d=0;init(){this.breakpoint=`40rem`,this.projection=!1,this.singular=!1}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.#f(),this.#e.length!==0&&(this.#m(),this.projection&&(this.#p(),this.#h(),this.#g(),this.singular&&(this.classList.add(`entries--singular`),this.#v(0))),this.#d=this.#b(),this.#x())}disconnectedCallback(){super.disconnectedCallback(),this.#u?.disconnect(),this.#u=null,this.#a?.remove(),this.#a=null,this.#o=[],this.#i?this.#i.remove():this.#r?.remove(),this.#r=null,this.#i=null,this.#s=[],this.classList.remove(`entries--wide`,`entries--projection`,`entries--singular`)}#f(){this.#e=[];let e=new Set,t=new Map,n=null;for(let r of this.children){let i=r.tagName.toLowerCase();if(/^h[1-6]$/.test(i))n=r;else if(i===`dl`&&n){let i=new Map,a=r.querySelectorAll(`dt`),o=r.querySelectorAll(`dd`);for(let n=0;n<a.length;n++){let r=a[n],s=r.textContent?.trim()??``,c=o[n]?.innerHTML??``;if(s){i.set(s,c),e.add(s);let n=r.getAttribute(`data-label`);n&&!t.has(s)&&t.set(s,n)}}this.#e.push({title:n.innerHTML,heading:n,dl:r,properties:i}),n=null}}this.#t=[...e],this.#n=this.#t.map(e=>t.get(e)??e)}#p(){this.classList.add(`entries--projection`)}#m(){let e=document.createElement(`table`);e.classList.add(`entries__table`),e.setAttribute(`aria-hidden`,`true`);let t=document.createElement(`thead`),n=document.createElement(`tr`),r=document.createElement(`th`);r.textContent=``,n.appendChild(r),this.#s=[];for(let e of this.#t){let t=document.createElement(`th`);t.textContent=e,n.appendChild(t),this.#s.push(t)}t.appendChild(n),e.appendChild(t);let i=document.createElement(`tbody`);for(let e of this.#e){let t=document.createElement(`tr`),n=document.createElement(`td`);n.innerHTML=e.title,n.style.fontWeight=`600`,t.appendChild(n);for(let n of this.#t){let r=document.createElement(`td`);r.innerHTML=e.properties.get(n)??``,t.appendChild(r)}i.appendChild(t)}e.appendChild(i),this.appendChild(e),this.#r=e}#h(){if(!this.#r)return;let e=document.createElement(`div`);e.classList.add(`entries__scroll`),this.#r.replaceWith(e),e.appendChild(this.#r),this.#i=e}#g(){let e=document.createElement(`nav`);e.classList.add(`entries__nav`),e.setAttribute(`aria-label`,`Column selector`),e.setAttribute(`aria-hidden`,`true`),this.#o=this.#t.map((t,n)=>{let r=document.createElement(`button`);return r.type=`button`,r.classList.add(`entries__nav-btn`),r.textContent=this.#n[n]??t,r.setAttribute(`aria-pressed`,String(n===0)),r.addEventListener(`click`,()=>this.#_(n)),e.appendChild(r),r}),this.#i.before(e),this.#a=e}#_(e){this.#c=e;for(let t=0;t<this.#o.length;t++)this.#o[t]?.setAttribute(`aria-pressed`,String(t===e));if(this.singular)this.#v(e);else{let t=this.#s[e];t&&this.#i&&t.scrollIntoView({behavior:`smooth`,block:`nearest`,inline:`start`})}this.dispatchEvent(new CustomEvent(`entries-column-change`,{detail:{column:e,header:this.#t[e]},bubbles:!0,composed:!0}))}#v(e){if(!this.#r)return;let t=e+1;for(let e of this.#r.rows)for(let n=1;n<e.cells.length;n++){let r=e.cells[n];r&&(r.hidden=n!==t)}}#y(){if(this.#r)for(let e of this.#r.rows)for(let t=1;t<e.cells.length;t++){let n=e.cells[t];n&&(n.hidden=!1)}}#b(){let e=this.breakpoint||`40rem`,t=document.createElement(`div`);t.style.width=e,t.style.position=`absolute`,t.style.visibility=`hidden`,this.appendChild(t);let n=t.offsetWidth;return t.remove(),n}#x(){this.#u=new ResizeObserver(this.#S),this.#u.observe(this)}#S=e=>{let t=e[0];if(!t)return;let n=t.contentBoxSize?.[0]?.inlineSize??t.contentRect.width;this.#l=n>=this.#d,this.#l?(this.classList.add(`entries--wide`),this.singular&&this.projection&&this.#y()):(this.classList.remove(`entries--wide`),this.singular&&this.projection&&this.#v(this.#c))}};customElements.get(`wc-entries`)||customElements.define(`wc-entries`,Ft);var It=class extends ${static{this.styles=[$.styles,o`
546
+ `}};customElements.get(`copy-button`)||customElements.define(`copy-button`,Nt);var Pt=class extends ${static{this.properties={autoplay:{type:Number,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=!1;#r=!1;#i=null;#a=!1;#o=null;#s=!1;init(){this.autoplay=0}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.hasAttribute(`role`)||this.setAttribute(`role`,`region`),this.hasAttribute(`aria-roledescription`)||this.setAttribute(`aria-roledescription`,`carousel`),this.#e=[...this.children].filter(e=>!e.hasAttribute(`slot`)),!(this.#e.length<2)&&(this.#n=this.classList.contains(`carousel--auto-pages`),this.#n||(this.#c(),this.#d(),this.addEventListener(`scrollsnapchange`,this.#p)),!this.autoplay&&this.hasAttribute(`autoplay`)&&(this.autoplay=Number(this.getAttribute(`autoplay`))||0),this.#s=matchMedia(`(prefers-reduced-motion: reduce)`).matches,this.autoplay>0&&(this.#y(),this.#s?(this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()):this.#m(),this.addEventListener(`pointerenter`,this.#g),this.addEventListener(`pointerleave`,this.#_),this.addEventListener(`focusin`,this.#g),this.addEventListener(`focusout`,this.#_)))}disconnectedCallback(){super.disconnectedCallback(),this.#n||(this.removeEventListener(`scrollsnapchange`,this.#p),this.#u()),this.removeEventListener(`pointerenter`,this.#g),this.removeEventListener(`pointerleave`,this.#_),this.removeEventListener(`focusin`,this.#g),this.removeEventListener(`focusout`,this.#_),this.#h(),this.#o&&=(this.#o.removeEventListener(`click`,this.#v),this.#o.hasAttribute(`slot`)||this.#o.remove(),null),this.removeAttribute(`aria-live`)}#c(){let e=[],t=[];for(let n=0;n<this.#e.length;n++){let r=this.#e[n];e.push(this.#l(r,n)),t.push(this.#l(r,n))}for(let t=e.length-1;t>=0;t--)this.prepend(e[t]);for(let e of t)this.append(e);this.#t=[...e,...t]}#l(e,t){let n=e.cloneNode(!0);n.setAttribute(`data-carousel-clone`,String(t)),n.setAttribute(`aria-hidden`,`true`);for(let e of[n,...n.querySelectorAll(`[tabindex], a, button, input, select, textarea`)])e.tabIndex=-1;return n}#u(){for(let e of this.#t)e.remove();this.#t=[]}#d(){requestAnimationFrame(()=>{let e=this.#e[0];e&&(this.style.scrollBehavior=`auto`,this.scrollLeft=e.offsetLeft-this.offsetLeft-(parseFloat(getComputedStyle(this).scrollPaddingLeft)||0)+(parseFloat(getComputedStyle(this).paddingLeft)||0),requestAnimationFrame(()=>{this.style.scrollBehavior=``}))})}#f(){this.scrollBy({left:this.clientWidth,behavior:`smooth`})}#p=e=>{if(this.#r){this.#r=!1;return}let t=e.snapTargetInline;if(!t||!t.hasAttribute(`data-carousel-clone`))return;let n=Number(t.getAttribute(`data-carousel-clone`)),r=this.#e[n];if(!r)return;let i=r.offsetLeft-t.offsetLeft;this.#r=!0,this.style.scrollBehavior=`auto`,this.scrollLeft+=i,requestAnimationFrame(()=>{this.style.scrollBehavior=``})};#m(){this.#i||this.autoplay<=0||(this.#a=!1,this.#i=setInterval(()=>this.#f(),this.autoplay),this.setAttribute(`aria-live`,`off`),this.#b())}#h(){this.#i&&=(clearInterval(this.#i),null)}#g=()=>{this.#h(),this.#a=!0,this.setAttribute(`aria-live`,`polite`),this.#b()};#_=()=>{this.#s||this.#m()};#v=()=>{this.#a?(this.#s=!1,this.#m()):this.#g()};#y(){let e=this.querySelector(`[slot="autoplay"]`);if(e)this.#o=e;else{let e=document.createElement(`button`);e.type=`button`,this.append(e),this.#o=e}this.#o.setAttribute(`part`,`autoplay`),this.#o.addEventListener(`click`,this.#v),this.#b()}#b(){this.#o&&(this.#o.setAttribute(`aria-label`,this.#a?`Play`:`Pause`),this.#o.setAttribute(`aria-pressed`,String(!this.#a)),this.#o.hasAttribute(`slot`)||(this.#o.textContent=this.#a?`▶`:`⏸`))}};customElements.get(`wc-carousel`)||customElements.define(`wc-carousel`,Pt);var Ft=class extends ${static{this.properties={breakpoint:{type:String,reflect:!0},projection:{type:Boolean,reflect:!0},singular:{type:Boolean,reflect:!0}}}createRenderRoot(){return this}#e=[];#t=[];#n=[];#r=null;#i=null;#a=null;#o=[];#s=[];#c=0;#l=!1;#u=null;#d=0;init(){this.breakpoint=`40rem`,this.projection=!1,this.singular=!1}constructor(){super(),this.init()}connectedCallback(){super.connectedCallback(),this.#f(),this.#e.length!==0&&(this.#m(),this.projection&&(this.#p(),this.#h(),this.#g(),this.singular&&(this.classList.add(`entries--singular`),this.#v(0))),this.#d=this.#b(),this.#x())}disconnectedCallback(){super.disconnectedCallback(),this.#u?.disconnect(),this.#u=null,this.#a?.remove(),this.#a=null,this.#o=[],this.#i?this.#i.remove():this.#r?.remove(),this.#r=null,this.#i=null,this.#s=[],this.classList.remove(`entries--wide`,`entries--projection`,`entries--singular`)}#f(){this.#e=[];let e=new Set,t=new Map,n=null;for(let r of this.children){let i=r.tagName.toLowerCase();if(/^h[1-6]$/.test(i))n=r;else if(i===`dl`&&n){let i=new Map,a=r.querySelectorAll(`dt`),o=r.querySelectorAll(`dd`);for(let n=0;n<a.length;n++){let r=a[n],s=r.textContent?.trim()??``,c=o[n]?.innerHTML??``;if(s){i.set(s,c),e.add(s);let n=r.getAttribute(`data-label`);n&&!t.has(s)&&t.set(s,n)}}this.#e.push({title:n.innerHTML,heading:n,dl:r,properties:i}),n=null}}this.#t=[...e],this.#n=this.#t.map(e=>t.get(e)??e)}#p(){this.classList.add(`entries--projection`)}#m(){let e=document.createElement(`table`);e.classList.add(`entries__table`),e.setAttribute(`aria-hidden`,`true`);let t=document.createElement(`thead`),n=document.createElement(`tr`),r=document.createElement(`th`);r.textContent=``,n.appendChild(r),this.#s=[];for(let e of this.#t){let t=document.createElement(`th`);t.textContent=e,n.appendChild(t),this.#s.push(t)}t.appendChild(n),e.appendChild(t);let i=document.createElement(`tbody`);for(let e of this.#e){let t=document.createElement(`tr`),n=document.createElement(`td`);n.innerHTML=e.title,n.style.fontWeight=`600`,t.appendChild(n);for(let n of this.#t){let r=document.createElement(`td`);r.innerHTML=e.properties.get(n)??``,t.appendChild(r)}i.appendChild(t)}e.appendChild(i),this.appendChild(e),this.#r=e}#h(){if(!this.#r)return;let e=document.createElement(`div`);e.classList.add(`entries__scroll`),this.#r.replaceWith(e),e.appendChild(this.#r),this.#i=e}#g(){let e=document.createElement(`nav`);e.classList.add(`entries__nav`),e.setAttribute(`aria-label`,`Column selector`),e.setAttribute(`aria-hidden`,`true`),this.#o=this.#t.map((t,n)=>{let r=document.createElement(`button`);return r.type=`button`,r.classList.add(`entries__nav-btn`),r.textContent=this.#n[n]??t,r.setAttribute(`aria-pressed`,String(n===0)),r.addEventListener(`click`,()=>this.#_(n)),e.appendChild(r),r}),this.#i.before(e),this.#a=e}#_(e){this.#c=e;for(let t=0;t<this.#o.length;t++)this.#o[t]?.setAttribute(`aria-pressed`,String(t===e));if(this.singular)this.#v(e);else{let t=this.#s[e];t&&this.#i&&t.scrollIntoView({behavior:`smooth`,block:`nearest`,inline:`start`})}this.dispatchEvent(new CustomEvent(`entries-column-change`,{detail:{column:e,header:this.#t[e]},bubbles:!0,composed:!0}))}#v(e){if(!this.#r)return;let t=e+1;for(let e of this.#r.rows)for(let n=1;n<e.cells.length;n++){let r=e.cells[n];r&&(r.hidden=n!==t)}}#y(){if(this.#r)for(let e of this.#r.rows)for(let t=1;t<e.cells.length;t++){let n=e.cells[t];n&&(n.hidden=!1)}}#b(){let e=this.breakpoint||`40rem`,t=document.createElement(`div`);t.style.width=e,t.style.position=`absolute`,t.style.visibility=`hidden`,this.appendChild(t);let n=t.offsetWidth;return t.remove(),n}#x(){this.#u=new ResizeObserver(this.#S),this.#u.observe(this)}#S=e=>{let t=e[0];if(!t)return;let n=t.contentBoxSize?.[0]?.inlineSize??t.contentRect.width;this.#l=n>=this.#d,this.#l?(this.classList.add(`entries--wide`),this.singular&&this.projection&&this.#y()):(this.classList.remove(`entries--wide`),this.singular&&this.projection&&this.#v(this.#c))}};customElements.get(`wc-entries`)||customElements.define(`wc-entries`,Ft);var It=class e extends ${static{this.styles=[$.styles,o`
547
547
  :host {
548
548
  display: none;
549
549
  }
@@ -641,7 +641,7 @@ let Tt=!1;const Et=new Y.subtle.Watcher(async()=>{Tt||(Tt=!0,queueMicrotask(()=>
641
641
  transition: none;
642
642
  }
643
643
  }
644
- `]}static{this.properties={scheme:{type:String,reflect:!0}}}constructor(){super(),this._mediaQuery=null,this._boundMediaHandler=null,this.init()}init(){this.scheme=`system`}connectedCallback(){super.connectedCallback(),this._mediaQuery=window.matchMedia(`(prefers-color-scheme: dark)`),this._boundMediaHandler=this._handleMediaChange.bind(this),this._mediaQuery.addEventListener(`change`,this._boundMediaHandler),this._applyColorScheme()}disconnectedCallback(){super.disconnectedCallback(),this._mediaQuery&&this._boundMediaHandler&&this._mediaQuery.removeEventListener(`change`,this._boundMediaHandler),document.documentElement.style.removeProperty(`color-scheme`),delete document.documentElement.dataset.theme}_handleMediaChange(e){this.scheme===`system`&&this.requestUpdate()}_applyColorScheme(){let e=document.documentElement;this.scheme===`system`?(e.style.removeProperty(`color-scheme`),delete e.dataset.theme):(e.style.colorScheme=`${this.scheme} only`,e.dataset.theme=this.scheme)}_handleSegmentClick(e){this.scheme!==e&&(this.scheme=e,this._applyColorScheme(),this.dispatchEvent(new CustomEvent(`scheme-change`,{detail:{scheme:this.scheme},bubbles:!0,composed:!0})))}updated(e){e.has(`scheme`)&&this._applyColorScheme()}_getEffectiveScheme(){return this.scheme===`system`?this._mediaQuery?.matches?`dark`:`light`:this.scheme}render(){return this._getEffectiveScheme(),Q`
644
+ `]}static{this.properties={scheme:{type:String,reflect:!0}}}constructor(){super(),this._mediaQuery=null,this._boundMediaHandler=null,this.init()}init(){this.scheme=e.readStored()??`system`}static{this.STORAGE_KEY=`vitops-color-scheme`}static readStored(){try{let t=localStorage.getItem(e.STORAGE_KEY);return t===`light`||t===`dark`||t===`system`?t:null}catch{return null}}_persist(){try{this.scheme===`system`?localStorage.removeItem(e.STORAGE_KEY):localStorage.setItem(e.STORAGE_KEY,this.scheme)}catch{}}connectedCallback(){super.connectedCallback(),this._mediaQuery=window.matchMedia(`(prefers-color-scheme: dark)`),this._boundMediaHandler=this._handleMediaChange.bind(this),this._mediaQuery.addEventListener(`change`,this._boundMediaHandler),this._applyColorScheme()}disconnectedCallback(){super.disconnectedCallback(),this._mediaQuery&&this._boundMediaHandler&&this._mediaQuery.removeEventListener(`change`,this._boundMediaHandler)}_handleMediaChange(e){this.scheme===`system`&&this.requestUpdate()}_applyColorScheme(){let e=document.documentElement;this.scheme===`system`?(e.style.removeProperty(`color-scheme`),delete e.dataset.theme):(e.style.colorScheme=`${this.scheme} only`,e.dataset.theme=this.scheme)}_handleSegmentClick(e){this.scheme!==e&&(this.scheme=e,this._applyColorScheme(),this._persist(),this.dispatchEvent(new CustomEvent(`scheme-change`,{detail:{scheme:this.scheme},bubbles:!0,composed:!0})))}updated(e){e.has(`scheme`)&&this._applyColorScheme()}render(){return Q`
645
645
  <div class="toggle__group" role="group" aria-label="Color scheme" part="group">
646
646
  <button
647
647
  class="toggle__segment"
package/dist/index.d.mts CHANGED
@@ -58,6 +58,7 @@ declare const DesignSystemSchema: z.ZodMiniObject<{
58
58
  overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
59
59
  element: z.ZodMiniOptional<z.ZodMiniString<string>>;
60
60
  class: z.ZodMiniOptional<z.ZodMiniString<string>>;
61
+ fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
61
62
  default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
62
63
  base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
63
64
  states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
@@ -147,6 +148,7 @@ declare const jsonSchema: {
147
148
  overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
148
149
  element: z.ZodMiniOptional<z.ZodMiniString<string>>;
149
150
  class: z.ZodMiniOptional<z.ZodMiniString<string>>;
151
+ fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
150
152
  default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
151
153
  base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
152
154
  states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
@@ -236,12 +238,20 @@ type ValidationResult = {
236
238
  ok: true;
237
239
  data: DesignSystem;
238
240
  errors: [];
241
+ warnings: string[];
239
242
  } | {
240
243
  ok: false;
241
244
  data: undefined;
242
245
  errors: z.core.$ZodIssue[];
246
+ warnings: string[];
243
247
  };
244
- /** Validate an unknown value against the design-system schema. */
248
+ /**
249
+ * Validate an unknown value against the design-system schema.
250
+ *
251
+ * `warnings` are configurations that parse and generate, but produce output that
252
+ * won't behave as authored — currently only the token-namespace collisions the
253
+ * flat `--<prop>-<name>` grammar makes possible.
254
+ */
245
255
  declare function validate(input: unknown): ValidationResult;
246
256
  //#endregion
247
257
  //#region src/generate.d.ts
@@ -278,8 +288,9 @@ declare function generateDocs(ds: DesignSystem, assetsDir: string): Record<strin
278
288
  */
279
289
  /**
280
290
  * Pattern base geometry props → per-pattern override-hook shorthand. Each hook
281
- * wraps the authored value (`padding: var(--p-button, 0.6em 1.2em)`) so a
282
- * consumer restyles one pattern by setting one variable.
291
+ * wraps the authored value (`padding: var(--p-btn, 0.4em 0.8em)`) so a
292
+ * consumer restyles one pattern by setting one variable. The hook is named after
293
+ * the pattern's key, not its class.
283
294
  */
284
295
  declare const BASE_HOOK: Record<string, string>;
285
296
  /**
@@ -497,6 +508,7 @@ declare const SiteConfigSchema: z.ZodMiniObject<{
497
508
  overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
498
509
  element: z.ZodMiniOptional<z.ZodMiniString<string>>;
499
510
  class: z.ZodMiniOptional<z.ZodMiniString<string>>;
511
+ fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
500
512
  default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
501
513
  base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
502
514
  states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
@@ -992,6 +1004,7 @@ declare const siteJsonSchema: {
992
1004
  overrides: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
993
1005
  element: z.ZodMiniOptional<z.ZodMiniString<string>>;
994
1006
  class: z.ZodMiniOptional<z.ZodMiniString<string>>;
1007
+ fill: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
995
1008
  default_role: z.ZodMiniOptional<z.ZodMiniString<string>>;
996
1009
  base: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniString<string>>>;
997
1010
  states: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/schema.ts","../src/generate.ts","../src/docs.ts","../src/shared.ts","../src/site.ts","../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/schema.ts","../src/generate.ts","../src/docs.ts","../src/shared.ts","../src/site.ts","../src/index.ts"],"mappings":"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"}