@getvitops/generator 8.1.0 → 8.2.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 (44) hide show
  1. package/CHANGELOG.md +797 -20
  2. package/assets/css/patterns/banner.css +20 -0
  3. package/assets/css/patterns/copy.css +5 -0
  4. package/assets/css/patterns/forms.css +5 -0
  5. package/assets/css/patterns/marquee.css +16 -0
  6. package/assets/css/patterns/splitter.css +11 -0
  7. package/assets/css/patterns/table.css +10 -0
  8. package/assets/js/consent.js +1 -1
  9. package/assets/js/deferred.js +1 -1
  10. package/assets/js/editor.js +2 -2
  11. package/assets/js/elements.js +5 -5
  12. package/assets/js/polyfills/adoptedStyleSheets.js +1 -1
  13. package/assets/js/polyfills/css-anchor-positioning-fn.js +4 -4
  14. package/assets/js/polyfills/global.esm.js +1 -1
  15. package/assets/js/polyfills/invokers-polyfill.js +1 -1
  16. package/assets/js/polyfills/popover.js +2 -2
  17. package/assets/js/polyfills/webcomponents-bundle.js +9 -9
  18. package/config.schema.json +464 -228
  19. package/dist/config-BfcWKH-5.mjs +1743 -0
  20. package/dist/config-BfcWKH-5.mjs.map +1 -0
  21. package/dist/config-Bhg3Xv3D.mjs +1774 -0
  22. package/dist/config-Bhg3Xv3D.mjs.map +1 -0
  23. package/dist/config.d.mts +2431 -0
  24. package/dist/config.d.mts.map +1 -0
  25. package/dist/config.mjs +3 -0
  26. package/dist/icons-sprite-CQ5Zj4go.d.mts +265 -0
  27. package/dist/icons-sprite-CQ5Zj4go.d.mts.map +1 -0
  28. package/dist/icons-sprite.d.mts +2 -0
  29. package/dist/icons-sprite.mjs +128 -0
  30. package/dist/icons-sprite.mjs.map +1 -0
  31. package/dist/index.d.mts +73 -2885
  32. package/dist/index.d.mts.map +1 -1
  33. package/dist/index.mjs +144 -2422
  34. package/dist/index.mjs.map +1 -1
  35. package/dist/schema-BV2n2phj.d.mts +291 -0
  36. package/dist/schema-BV2n2phj.d.mts.map +1 -0
  37. package/dist/tokens-BzBbTeTi.d.mts +225 -0
  38. package/dist/tokens-BzBbTeTi.d.mts.map +1 -0
  39. package/dist/tokens-C1RJwFeG.mjs +695 -0
  40. package/dist/tokens-C1RJwFeG.mjs.map +1 -0
  41. package/dist/tokens.d.mts +2 -0
  42. package/dist/tokens.mjs +3 -0
  43. package/package.json +19 -6
  44. package/schema.json +12 -28
@@ -69,3 +69,23 @@
69
69
  .banner[hidden] {
70
70
  display: none;
71
71
  }
72
+
73
+ /*
74
+ * `<wc-dismissable>` wraps a banner or notification — block content — and animates its own
75
+ * opacity/scale on dismiss, so it needs a box of its own: `display: contents` would drop
76
+ * that animation. Pre-upgrade it would otherwise be an inline box around a block child.
77
+ */
78
+ :where(wc-dismissable) {
79
+ display: block;
80
+ }
81
+
82
+ /*
83
+ * A dismiss button does nothing until `<wc-dismissable>` upgrades — an inert control that
84
+ * looks live is worse than none. `:not(:defined)` is true with no JS (and until elements.js
85
+ * has run), so the close affordance only appears once something can act on it. The banner
86
+ * itself stays fully readable. Markup that puts a `[data-dismiss]` button inside the element
87
+ * gets the same treatment, whatever its class.
88
+ */
89
+ wc-dismissable:not(:defined) :is(.banner__close, .notification__close, [data-dismiss]) {
90
+ display: none;
91
+ }
@@ -80,3 +80,8 @@
80
80
  visibility: visible;
81
81
  }
82
82
  }
83
+
84
+ /* Matches `<wc-copy>`'s upgraded `:host` (inline-flex) so registering causes no reflow. */
85
+ :where(wc-copy) {
86
+ display: inline-flex;
87
+ }
@@ -364,3 +364,8 @@ select.custom-select {
364
364
  outline-offset: 2px;
365
365
  }
366
366
  }
367
+
368
+ /* `<wc-multi-field>` is a group of controls, a block. Its shadow `:host` declares no display. */
369
+ :where(wc-multi-field) {
370
+ display: block;
371
+ }
@@ -56,6 +56,13 @@
56
56
  animation-play-state: paused;
57
57
  }
58
58
 
59
+ /* Keyboard users can't hover; focusing anything inside (a link in an item) also pauses, and
60
+ `<wc-marquee>`'s pause button sets `data-paused` (WCAG 2.2.2). */
61
+ &:focus-within .marquee__content,
62
+ &[data-paused] .marquee__content {
63
+ animation-play-state: paused;
64
+ }
65
+
59
66
  &.marquee--reverse {
60
67
  --_marquee-direction: reverse;
61
68
  }
@@ -100,3 +107,12 @@
100
107
  translate: 0 calc(-1 * var(--_marquee-distance, calc(100% + var(--marquee-gap, 1rem))));
101
108
  }
102
109
  }
110
+
111
+ /*
112
+ * The `.marquee` class carries `display: flex` when present (the Astro component always sets
113
+ * it). This is the fallback for a hand-written `<wc-marquee>` without the class, and it is
114
+ * zero specificity so `.marquee` still wins.
115
+ */
116
+ :where(wc-marquee) {
117
+ display: block;
118
+ }
@@ -210,3 +210,14 @@
210
210
  }
211
211
  }
212
212
  }
213
+
214
+ /*
215
+ * Pre-upgrade display for the two elements that live in this partial — see the note on
216
+ * `wc-entries` in table.css. Both are a framed block of content (two panes; two images),
217
+ * and `wc-image-compare`'s upgraded `:host` is already `display: block`, so declaring it
218
+ * here removes the layout shift when it registers. `wc-split-panel` has no `:host` display
219
+ * at all, so this also fixes it after upgrade.
220
+ */
221
+ :where(wc-split-panel, wc-image-compare) {
222
+ display: block;
223
+ }
@@ -104,3 +104,13 @@ table,
104
104
  min-inline-size: var(--table-min-inline-size, 100%);
105
105
  }
106
106
  }
107
+
108
+ /*
109
+ * Before upgrade (or with elements.js absent) an unregistered custom element is
110
+ * `display: inline`, forming an inline box around block content. The default-view
111
+ * `<h3>` + `<dl>` pairs are block content, as is the table the element builds.
112
+ * Zero specificity, so any consumer rule wins.
113
+ */
114
+ :where(wc-entries) {
115
+ display: block;
116
+ }
@@ -1 +1 @@
1
- const e=[`necessary`,`analytics`,`marketing`,`preferences`],t=`vitops:consent`,n=`vitops:consent-open`,r=`vitops_consent`,i=[`analytics`,`marketing`,`preferences`];function a(e){return{analytics:e,marketing:e,preferences:e}}function o(){return{ts:null,choices:a(null)}}function s(e,t){for(let n of e.split(`;`)){let e=n.trim();if(e.slice(0,t.length+1)===`${t}=`)return e.slice(t.length+1)}return null}function c(e){if(!e)return o();let t;try{t=JSON.parse(decodeURIComponent(e))}catch{return o()}if(typeof t!=`object`||!t)return o();let n=t;if(n.v!==2||typeof n.c!=`object`||n.c===null)return o();let r=n.c,s=a(null);for(let e of i){let t=r[e];typeof t==`boolean`&&(s[e]=t)}return{ts:typeof n.ts==`number`?n.ts:null,choices:s}}function l(e){let t={};for(let n of i){let r=e.choices[n];typeof r==`boolean`&&(t[n]=r)}return encodeURIComponent(JSON.stringify({v:2,ts:e.ts??0,c:t}))}function u(e,t){return t===`necessary`?!0:e.choices[t]===!0}function d(e,t){return t===`necessary`?!0:e.choices[t]!==null}function f(e,t){for(let n of t)if(!d(e,n))return!0;return!1}function p(e,t){return{ts:t,choices:a(e)}}function m(e,t,n){let r={...e.choices};for(let e of i){let n=t[e];typeof n==`boolean`&&(r[e]=n)}return{ts:n,choices:r}}function h(e,t){return i.filter(n=>u(e,n)&&!u(t,n))}function g(e){return`; path=/; max-age=15552000; SameSite=Lax${e?`; Secure`:``}`}const _=location.protocol===`https:`;let v=c(s(document.cookie,r));const y=new Set,b=new WeakSet,x=new Set,S=new Set,C=new Map,w=new Set;function T(e){w.has(e)||(w.add(e),queueMicrotask(()=>{document.querySelector(`wc-consent`)||console.warn(`[vitops] something requested the "${e}" consent category, but this page has no <wc-consent> element to ask with — so the request can never be granted and whatever waited on it will not run. Render <CookieConsent /> on every page that gates anything.`)}))}function E(e){S.has(e)||(S.add(e),T(e),B())}function D(){for(let[e,t]of C)if(d(v,e)){C.delete(e);for(let n of t)n(u(v,e))}}const O={idle:[],async:[],interaction:[]},k={idle:!1,async:!0,interaction:!1};function A(e){if(k[e])return;k[e]=!0;let t=O[e];O[e]=[];for(let e of t)e()}function j(e,t){k[e]?t():O[e].push(t)}function M(e){document.readyState===`complete`?e():addEventListener(`load`,e,{once:!0})}M(()=>{let e=globalThis.requestIdleCallback;e?e(()=>A(`idle`),{timeout:3e3}):setTimeout(()=>A(`idle`),1)});{let e=[`pointerdown`,`keydown`,`scroll`,`touchstart`],t=()=>{for(let n of e)removeEventListener(n,t);A(`interaction`)};for(let n of e)addEventListener(n,t,{once:!0,passive:!0});M(()=>setTimeout(()=>A(`interaction`),8e3))}const N=new Set([`type`,`src`,`data-vitops-tag`,`data-src`,`data-strategy`,`data-consent`,`data-consent-src`,`data-consent-cookies`]);function P(t){let n=t.getAttribute(`data-consent`);return e.includes(n??``)?n:`analytics`}function F(e){let t=e.textContent??``,n=e.getAttribute(`data-src`),r=t=>{let n=document.createElement(`script`);for(let{name:t,value:r}of Array.from(e.attributes))N.has(t)||n.setAttribute(t,r);t(n),e.parentNode?.insertBefore(n,e.nextSibling)};t.trim()&&r(e=>e.text=t),n&&r(e=>{e.async=!0,e.src=n})}function I(e){if(!b.has(e)){if(b.add(e),x.add(P(e)),e instanceof HTMLScriptElement)F(e);else{let t=e.getAttribute(`data-consent-src`);t&&e.setAttribute(`src`,t)}e.setAttribute(`data-vitops-activated`,``)}}function L(){let e=document.querySelectorAll(`script[data-vitops-tag]:not([data-vitops-activated]),[data-consent-src]:not([data-vitops-activated])`);for(let t of e){let e=t.getAttribute(`data-strategy`);j(e===`async`||e===`interaction`?e:`idle`,()=>{let e=P(t);u(v,e)?I(t):E(e)})}}function R(e){let t=new Set;for(let n of e)for(let e of document.querySelectorAll(`[data-consent="${n}"]`))for(let n of(e.getAttribute(`data-consent-cookies`)??``).split(`,`))n.trim()&&t.add(n.trim());if(!t.size)return;let n=document.cookie.split(`;`).map(e=>e.trim().split(`=`)[0]??``),r=location.hostname.split(`.`).slice(-2).join(`.`),i=[``,`; domain=${location.hostname}`,`; domain=.${r}`];for(let e of n)if([...t].some(t=>t.endsWith(`*`)?e.startsWith(t.slice(0,-1)):e===t))for(let t of i)document.cookie=`${e}=; path=/; max-age=0${t}`}function z(e,t){let n=h(v,e),i=v;v=e,t?document.cookie=`${r}=${l(e)}${g(_)}`:document.cookie=`${r}=; path=/; max-age=0`,B(),L(),n.length&&(R(n),n.some(e=>x.has(e)&&u(i,e))&&V.reloadOnRevoke&&location.reload())}function B(){D();for(let e of y)e(v);document.dispatchEvent(new CustomEvent(t,{detail:v}))}const V={categories:e,reloadOnRevoke:!0,get:()=>v,granted:e=>u(v,e),needed:()=>f(v,S),demanded:()=>e.filter(e=>S.has(e)),require(e){return E(e),u(v,e)},request(e){return E(e),d(v,e)?Promise.resolve(u(v,e)):new Promise(t=>{let n=C.get(e);n?n.push(t):C.set(e,[t])})},set:e=>z(m(v,e,Date.now()),!0),acceptAll:()=>z(p(!0,Date.now()),!0),rejectAll:()=>z(p(!1,Date.now()),!0),reset:()=>z(o(),!1),open:()=>document.dispatchEvent(new CustomEvent(n)),subscribe(e){return y.add(e),e(v),()=>void y.delete(e)}},H=window.vitopsConsent?.q;if(window.vitopsConsent=V,H)for(let[e,t]of H)t?V.request(e).then(t):V.require(e);document.addEventListener(`click`,e=>{e.target?.closest?.(`[data-consent-open]`)&&(e.preventDefault(),V.open())}),document.addEventListener(`astro:page-load`,L),L(),B();var U=class extends HTMLElement{#e;#t=`prompt`;#n=!1;get#r(){return window.vitopsConsent}get#i(){return this.querySelector(`[popover]`)}connectedCallback(){let e=this.#r;if(!e)return;let t=this.#i;t&&typeof t.showPopover!=`function`&&t.removeAttribute(`popover`),this.getAttribute(`reload-on-revoke`)===`false`&&(e.reloadOnRevoke=!1),this.addEventListener(`click`,this.#p),this.addEventListener(`submit`,this.#o),document.addEventListener(n,this.#a),this.#e=e.subscribe(()=>{this.#n&&this.#t===`settings`?this.#f():e.needed()?this.#u(`prompt`):this.#d()})}disconnectedCallback(){this.removeEventListener(`click`,this.#p),this.removeEventListener(`submit`,this.#o),document.removeEventListener(n,this.#a),this.#e?.()}#a=()=>this.#u(`settings`);#o=e=>e.preventDefault();#s(e){return this.querySelector(`[data-consent-row="${e}"]`)??this.#c(e)?.closest(`label`)??null}#c(e){return this.querySelector(`input[name="${e}"]`)}#l(e){let t=this.#r;if(!t)return[];if(e===`settings`){let e=i.filter(e=>this.#s(e));return e.length?e:[...i]}let n=t.get();return i.filter(e=>t.demanded().includes(e)&&!d(n,e))}#u(e){if(!this.#l(e).length)return;this.#t=e,this.#f(),this.hidden=!1,this.#n=!0;let t=this.#i;t?.isConnected&&!t.matches(`:popover-open`)&&t.showPopover()}#d(){this.#n=!1,this.#i?.hidePopover?.(),this.hidden=!0}#f(){let e=this.#r;if(!e)return;let t=this.#l(this.#t);for(let n of i){let r=this.#s(n);r&&(r.hidden=!t.includes(n));let i=this.#c(n);i&&(i.checked=e.granted(n))}this.#i?.classList.toggle(`consent--single`,t.length<2)}#p=e=>{let t=this.#r,n=e.target?.closest?.(`[data-consent-accept],[data-consent-reject],[data-consent-save]`);if(!t||!n)return;e.preventDefault();let r=this.#l(this.#t);n.hasAttribute(`data-consent-accept`)?t.set(this.#m(r,()=>!0)):n.hasAttribute(`data-consent-reject`)?t.set(this.#m(r,()=>!1)):t.set(this.#m(r,e=>this.#c(e)?.checked===!0)),this.#d()};#m(e,t){let n={};for(let r of e)n[r]=t(r);return n}};customElements.get(`wc-consent`)||customElements.define(`wc-consent`,U);export{e as CATEGORIES,t as CONSENT_EVENT,n as CONSENT_OPEN_EVENT,r as COOKIE_NAME,V as consent};
1
+ const e=[`necessary`,`analytics`,`marketing`,`preferences`],t=`vitops:consent`,n=`vitops:consent-open`,r=`vitops_consent`,i=[`analytics`,`marketing`,`preferences`];function a(e){return{analytics:e,marketing:e,preferences:e}}function o(){return{ts:null,choices:a(null)}}function s(e,t){for(let n of e.split(`;`)){let e=n.trim();if(e.slice(0,t.length+1)===`${t}=`)return e.slice(t.length+1)}return null}function c(e){if(!e)return o();let t;try{t=JSON.parse(decodeURIComponent(e))}catch{return o()}if(typeof t!=`object`||!t)return o();let n=t;if(n.v!==2||typeof n.c!=`object`||n.c===null)return o();let r=n.c,s=a(null);for(let e of i){let t=r[e];typeof t==`boolean`&&(s[e]=t)}return{ts:typeof n.ts==`number`?n.ts:null,choices:s}}function l(e){let t={};for(let n of i){let r=e.choices[n];typeof r==`boolean`&&(t[n]=r)}return encodeURIComponent(JSON.stringify({v:2,ts:e.ts??0,c:t}))}function u(e,t){return t===`necessary`||e.choices[t]===!0}function d(e,t){return t===`necessary`||e.choices[t]!==null}function f(e,t){for(let n of t)if(!d(e,n))return!0;return!1}function p(e,t){return{ts:t,choices:a(e)}}function m(e,t,n){let r={...e.choices};for(let e of i){let n=t[e];typeof n==`boolean`&&(r[e]=n)}return{ts:n,choices:r}}function h(e,t){return i.filter(n=>u(e,n)&&!u(t,n))}function g(e){return`; path=/; max-age=15552000; SameSite=Lax${e?`; Secure`:``}`}const _=location.protocol===`https:`;let v=c(s(document.cookie,r));const y=/* @__PURE__ */ new Set,b=/* @__PURE__ */ new WeakSet,x=/* @__PURE__ */ new Set,S=/* @__PURE__ */ new Set,C=/* @__PURE__ */ new Map,w=/* @__PURE__ */ new Set;function T(e){w.has(e)||(w.add(e),queueMicrotask(()=>{document.querySelector(`wc-consent`)||console.warn(`[vitops] something requested the "${e}" consent category, but this page has no <wc-consent> element to ask with — so the request can never be granted and whatever waited on it will not run. Render <CookieConsent /> on every page that gates anything.`)}))}function E(e){S.has(e)||(S.add(e),T(e),B())}function D(){for(let[e,t]of C)if(d(v,e)){C.delete(e);for(let n of t)n(u(v,e))}}const O={idle:[],async:[],interaction:[]},k={idle:!1,async:!0,interaction:!1};function A(e){if(k[e])return;k[e]=!0;let t=O[e];O[e]=[];for(let e of t)e()}function j(e,t){k[e]?t():O[e].push(t)}function M(e){document.readyState===`complete`?e():addEventListener(`load`,e,{once:!0})}M(()=>{let e=globalThis.requestIdleCallback;e?e(()=>A(`idle`),{timeout:3e3}):setTimeout(()=>A(`idle`),1)});{let e=[`pointerdown`,`keydown`,`scroll`,`touchstart`],t=()=>{for(let n of e)removeEventListener(n,t);A(`interaction`)};for(let n of e)addEventListener(n,t,{once:!0,passive:!0});M(()=>setTimeout(()=>A(`interaction`),8e3))}const N=/* @__PURE__ */ new Set([`type`,`src`,`data-vitops-tag`,`data-src`,`data-strategy`,`data-consent`,`data-consent-src`,`data-consent-cookies`]);function P(t){let n=t.getAttribute(`data-consent`);return e.includes(n??``)?n:`analytics`}function F(e){let t=e.textContent??``,n=e.getAttribute(`data-src`),r=t=>{let n=document.createElement(`script`);for(let{name:t,value:r}of Array.from(e.attributes))N.has(t)||n.setAttribute(t,r);t(n),e.parentNode?.insertBefore(n,e.nextSibling)};t.trim()&&r(e=>e.text=t),n&&r(e=>{e.async=!0,e.src=n})}function I(e){if(!b.has(e)){if(b.add(e),x.add(P(e)),e instanceof HTMLScriptElement)F(e);else{let t=e.getAttribute(`data-consent-src`);t&&e.setAttribute(`src`,t)}e.setAttribute(`data-vitops-activated`,``)}}function L(){let e=document.querySelectorAll(`script[data-vitops-tag]:not([data-vitops-activated]),[data-consent-src]:not([data-vitops-activated])`);for(let t of e){let e=t.getAttribute(`data-strategy`);j(e===`async`||e===`interaction`?e:`idle`,()=>{let e=P(t);u(v,e)?I(t):E(e)})}}function R(e){let t=/* @__PURE__ */ new Set;for(let n of e)for(let e of document.querySelectorAll(`[data-consent="${n}"]`))for(let n of(e.getAttribute(`data-consent-cookies`)??``).split(`,`))n.trim()&&t.add(n.trim());if(!t.size)return;let n=document.cookie.split(`;`).map(e=>e.trim().split(`=`)[0]??``),r=location.hostname.split(`.`).slice(-2).join(`.`),i=[``,`; domain=${location.hostname}`,`; domain=.${r}`];for(let e of n)if([...t].some(t=>t.endsWith(`*`)?e.startsWith(t.slice(0,-1)):e===t))for(let t of i)document.cookie=`${e}=; path=/; max-age=0${t}`}function z(e,t){let n=h(v,e),i=v;v=e,t?document.cookie=`${r}=${l(e)}${g(_)}`:document.cookie=`${r}=; path=/; max-age=0`,B(),L(),n.length&&(R(n),n.some(e=>x.has(e)&&u(i,e))&&V.reloadOnRevoke&&location.reload())}function B(){D();for(let e of y)e(v);document.dispatchEvent(new CustomEvent(t,{detail:v}))}const V={categories:e,reloadOnRevoke:!0,get:()=>v,granted:e=>u(v,e),needed:()=>f(v,S),demanded:()=>e.filter(e=>S.has(e)),require(e){return E(e),u(v,e)},request(e){return E(e),d(v,e)?Promise.resolve(u(v,e)):new Promise(t=>{let n=C.get(e);n?n.push(t):C.set(e,[t])})},set:e=>z(m(v,e,Date.now()),!0),acceptAll:()=>z(p(!0,Date.now()),!0),rejectAll:()=>z(p(!1,Date.now()),!0),reset:()=>z(o(),!1),open:()=>document.dispatchEvent(new CustomEvent(n)),subscribe(e){return y.add(e),e(v),()=>void y.delete(e)}},H=window.vitopsConsent?.q;if(window.vitopsConsent=V,H)for(let[e,t]of H)t?V.request(e).then(t):V.require(e);document.addEventListener(`click`,e=>{e.target?.closest?.(`[data-consent-open]`)&&(e.preventDefault(),V.open())}),document.addEventListener(`astro:page-load`,L),L(),B();var U=class extends HTMLElement{#e;#t=`prompt`;#n=!1;get#r(){return window.vitopsConsent}get#i(){return this.querySelector(`[popover]`)}connectedCallback(){let e=this.#r;if(!e)return;let t=this.#i;t&&typeof t.showPopover!=`function`&&t.removeAttribute(`popover`),this.getAttribute(`reload-on-revoke`)===`false`&&(e.reloadOnRevoke=!1),this.addEventListener(`click`,this.#m),this.addEventListener(`submit`,this.#o),document.addEventListener(n,this.#a),this.#e=e.subscribe(()=>{this.#n&&this.#t===`settings`?this.#p():e.needed()?this.#u(`prompt`):this.#f()})}disconnectedCallback(){this.removeEventListener(`click`,this.#m),this.removeEventListener(`submit`,this.#o),document.removeEventListener(n,this.#a),this.#e?.()}#a=()=>this.#u(`settings`);#o=e=>e.preventDefault();#s(e){return this.querySelector(`[data-consent-row="${e}"]`)??this.#c(e)?.closest(`label`)??null}#c(e){return this.querySelector(`input[name="${e}"]`)}#l(e){let t=this.#r;if(!t)return[];if(e===`settings`){let e=i.filter(e=>this.#s(e));return e.length?e:[...i]}let n=t.get();return i.filter(e=>t.demanded().includes(e)&&!d(n,e))}#u(e){if(!this.#l(e).length)return;this.#t=e,this.#p(),this.hidden=!1,this.#n=!0;let t=this.#i;t?.isConnected&&!t.matches(`:popover-open`)&&t.showPopover(),e===`settings`&&t&&(this.#d=document.activeElement instanceof HTMLElement?document.activeElement:null,t.tabIndex=-1,t.focus({preventScroll:!0}))}#d=null;#f(){this.#n=!1,this.#i?.hidePopover?.(),this.hidden=!0;let e=this.#d;this.#d=null,e?.isConnected&&e.focus({preventScroll:!0})}#p(){let e=this.#r;if(!e)return;let t=this.#l(this.#t);for(let n of i){let r=this.#s(n);r&&(r.hidden=!t.includes(n));let i=this.#c(n);i&&(i.checked=e.granted(n))}this.#i?.classList.toggle(`consent--single`,t.length<2)}#m=e=>{let t=this.#r,n=e.target?.closest?.(`[data-consent-accept],[data-consent-reject],[data-consent-save]`);if(!t||!n)return;e.preventDefault();let r=this.#l(this.#t);n.hasAttribute(`data-consent-accept`)?t.set(this.#h(r,()=>!0)):n.hasAttribute(`data-consent-reject`)?t.set(this.#h(r,()=>!1)):t.set(this.#h(r,e=>this.#c(e)?.checked===!0)),this.#f()};#h(e,t){let n={};for(let r of e)n[r]=t(r);return n}};customElements.get(`wc-consent`)||customElements.define(`wc-consent`,U);export{e as CATEGORIES,t as CONSENT_EVENT,n as CONSENT_OPEN_EVENT,r as COOKIE_NAME,V as consent};
@@ -1 +1 @@
1
- function e(e){let t=[...e.children];parseFloat(getComputedStyle(e).getPropertyValue(`--stagger-amount`));let n=[],r=e.getBoundingClientRect().top;t.forEach(e=>{let t=Math.round(e.getBoundingClientRect().top-r),i=n.find(e=>Math.abs(e.top-t)<10);i||(i={top:t,items:[]},n.push(i)),i.items.push(e)}),n.forEach(({items:e})=>{e.forEach((e,t)=>{e.style.setProperty(`--_stagger-index`,String(t))})})}let t;function n(){clearTimeout(t),t=setTimeout(()=>{requestAnimationFrame(()=>{document.querySelectorAll(`.stagger`).forEach(e)})},100)}const r=new IntersectionObserver((e,t)=>{e.forEach(e=>{if(!e.isIntersecting)return;let n=e.rootBounds,r=e.boundingClientRect;(!n||r.height>=n.height||r.top+r.height/2<=n.bottom)&&(e.target.classList.add(`is-active`),t.unobserve(e.target))})},{rootMargin:`0px 0px -10% 0px`,threshold:[0,.25,.5,.75,1]});function i(e){let t=e.querySelector(`.horizontal-scroll__track`);if(!t)return;let n=Array.from(t.children).reduce((e,t)=>e+t.offsetWidth,0);t.style.width=`${n}px`}document.addEventListener(`click`,e=>{let t=e.target.closest?.(`a[href^="#"]`);if(!t)return;let n=t.closest(`dialog[open]`);n&&n.close()}),window.addEventListener(`load`,()=>{requestAnimationFrame(()=>{document.querySelectorAll(`.stagger`).forEach(e),window.addEventListener(`resize`,n),document.querySelectorAll(`.horizontal-scroll`).forEach(i),document.querySelectorAll(`.animate-trigger`).forEach(e=>{r.observe(e)});let t=new Date().getFullYear();document.querySelectorAll(`[data-current-year]`).forEach(e=>{e.textContent=t.toString()})})});
1
+ function e(e){let t=[...e.children];parseFloat(getComputedStyle(e).getPropertyValue(`--stagger-amount`));let n=[],r=e.getBoundingClientRect().top;t.forEach(e=>{let t=Math.round(e.getBoundingClientRect().top-r),i=n.find(e=>Math.abs(e.top-t)<10);i||(i={top:t,items:[]},n.push(i)),i.items.push(e)}),n.forEach(({items:e})=>{e.forEach((e,t)=>{e.style.setProperty(`--_stagger-index`,String(t))})})}let t;function n(){clearTimeout(t),t=setTimeout(()=>{requestAnimationFrame(()=>{document.querySelectorAll(`.stagger`).forEach(e)})},100)}const r=new IntersectionObserver((e,t)=>{e.forEach(e=>{if(!e.isIntersecting)return;let n=e.rootBounds,r=e.boundingClientRect;(!n||r.height>=n.height||r.top+r.height/2<=n.bottom)&&(e.target.classList.add(`is-active`),t.unobserve(e.target))})},{rootMargin:`0px 0px -10% 0px`,threshold:[0,.25,.5,.75,1]});function i(e){let t=e.querySelector(`.horizontal-scroll__track`);if(!t)return;let n=Array.from(t.children).reduce((e,t)=>e+t.offsetWidth,0);t.style.width=`${n}px`}document.addEventListener(`click`,e=>{let t=e.target.closest?.(`a[href^="#"]`);if(!t)return;let n=t.closest(`dialog[open]`);n&&n.close()}),window.addEventListener(`load`,()=>{requestAnimationFrame(()=>{document.querySelectorAll(`.stagger`).forEach(e),window.addEventListener(`resize`,n),document.querySelectorAll(`.horizontal-scroll`).forEach(i),document.querySelectorAll(`.animate-trigger`).forEach(e=>{r.observe(e)});let t=(/* @__PURE__ */ new Date()).getFullYear();document.querySelectorAll(`[data-current-year]`).forEach(e=>{e.textContent=t.toString()})})});
@@ -1,2 +1,2 @@
1
- const e=`vitops:ds-overrides`,t=`/__vitops/design-system`,n=(e,t)=>{let n=t.indexOf(`-`),r=n===-1?t:t.slice(0,n),i=n===-1?``:t.slice(n+1);return i===`on`?`--color-${r}-on-${e}`:i.startsWith(`on-`)?`--color-${r}-on-${e}-${i.slice(3)}`:i?`--color-${r}-${e}-${i}`:`--color-${r}-${e}`},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=e.colors.roles.find(e=>e.name===t)?.kind??`chromatic`,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[n,r]of this.roles){let i=e.colors.roles.find(e=>e.name===n)?.kind??`chromatic`;this.deepSet(t,`colors.roles.${n}`,{hue:r,kind:i})}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 details--marker-start ed-section`,...t?{open:!0}:{}},[this.el(`summary`,{class:`font-eyebrow`},[this.el(`span`,{class:`icon-mask details-icon ed-icon ed-icon--caret`,"aria-hidden":`true`}),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:`manual`,class:`drawer drawer--right drawer--modeless 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`},[this.el(`span`,{class:`icon-mask ed-icon ed-icon--close`,"aria-hidden":`true`})]);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},[this.el(`span`,{class:`icon-mask ed-icon ed-icon--theme`,"aria-hidden":`true`}),`Theme`]);document.addEventListener(`keydown`,e=>{e.key===`Escape`&&n.matches(`:popover-open`)&&n.hidePopover()}),this.append(r,n)}};customElements.get(`wc-theme-editor`)||customElements.define(`wc-theme-editor`,i);
1
+ const e=`vitops:ds-overrides`,t=(e,t)=>{let n=t.indexOf(`-`),r=n===-1?t:t.slice(0,n),i=n===-1?``:t.slice(n+1);return i===`on`?`--color-${r}-on-${e}`:i.startsWith(`on-`)?`--color-${r}-on-${e}-${i.slice(3)}`:i?`--color-${r}-${e}-${i}`:`--color-${r}-${e}`},n=(e,t)=>`--color-${e}-${t}`;var r=class extends HTMLElement{constructor(...e){super(...e),this.store={light:/* @__PURE__ */ new Map,dark:/* @__PURE__ */ new Map},this.roles=/* @__PURE__ */ new Map,this.roleVars=/* @__PURE__ */ new Set,this.syncers=/* @__PURE__ */ new Set,this.scheme=`light`,this.canSave=!1}static{this.observedAttributes=[`manifest`,`save-endpoint`]}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)}get saveUrl(){return this.getAttribute(`save-endpoint`)??`/__vitops/design-system`}async probeSave(){try{let e=await fetch(this.saveUrl);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,n,r){let i=e.colors.roles.find(e=>e.name===n)?.kind??`chromatic`,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([t(n,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[n,r]of this.roles){let i=e.colors.roles.find(e=>e.name===n)?.kind??`chromatic`;this.deepSet(t,`colors.roles.${n}`,{hue:r,kind:i})}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 details--marker-start ed-section`,...t?{open:!0}:{}},[this.el(`summary`,{class:`font-eyebrow`},[this.el(`span`,{class:`icon-mask details-icon ed-icon ed-icon--caret`,"aria-hidden":`true`}),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:r}=this.section(`Palette`,!0);r.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 r of e.colors.steps){let a=e.colors.palette[t]?.[r];a!=null&&i.body.append(this.colorInput(n(t,r),a))}r.append(i.details)}return r.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,t){let{patch:n}=this.buildPatch(e);if(!Object.keys(n).length)return void this.flash(t,`Nothing to save`);try{let e=await fetch(this.saveUrl,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({patch:n})});if(!e.ok){let n=await e.json().catch(()=>({}));console.error(`[wc-theme-editor] save rejected`,n.errors??e.statusText),this.flash(t,`Rejected ✗`);return}this.reset(),this.flash(t,`Saved ✓`)}catch(e){console.error(`[wc-theme-editor] save failed`,e),this.flash(t,`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:`manual`,class:`drawer drawer--right drawer--modeless 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`},[this.el(`span`,{class:`icon-mask ed-icon ed-icon--close`,"aria-hidden":`true`})]);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},[this.el(`span`,{class:`icon-mask ed-icon ed-icon--theme`,"aria-hidden":`true`}),`Theme`]);document.addEventListener(`keydown`,e=>{e.key===`Escape`&&n.matches(`:popover-open`)&&n.hidePopover()}),this.append(r,n)}};customElements.get(`wc-theme-editor`)||customElements.define(`wc-theme-editor`,r);