@taprootio/espalier 4.18.0 → 4.20.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.
@@ -33,11 +33,13 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
33
33
  *
34
34
  * A section may also tint one raster alpha mask behind its content.
35
35
  * The component owns clipping, no-repeat mask behavior, stacking, and
36
- * interaction isolation; consumers supply only the image, semantic tint,
37
- * position, size, and opacity:
36
+ * interaction isolation; consumers opt in with the `decoration`
37
+ * attribute and supply only the image, semantic tint, position, size, and
38
+ * opacity:
38
39
  *
39
40
  * ```html
40
41
  * <esp-section
42
+ * decoration
41
43
  * style="
42
44
  * --esp-section-decoration-image: url('/assets/brand-mark.png');
43
45
  * --esp-section-decoration-position: calc(100% + 2rem) -2rem;
@@ -49,6 +51,15 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
49
51
  * </esp-section>
50
52
  * ```
51
53
  *
54
+ * Without `decoration` the section renders no decorative layer at all, and
55
+ * the `--esp-section-decoration-*` hooks have no effect. The attribute is
56
+ * what keeps an undecorated band free of painted planes: accessibility
57
+ * auditors such as axe-core and Lighthouse do not model `mask-image`, so a
58
+ * tinted plane hidden only by a mask is read as the background behind every
59
+ * word in the section. Set it together with the image, never on its own. A
60
+ * decorated band is audited as though the tint covered it everywhere, so
61
+ * text that passes an audit also reads where it crosses the mark.
62
+ *
52
63
  * CSS image values are trusted stylesheet input. Products that accept image
53
64
  * references from documents or users must enforce their own asset ownership
54
65
  * and URL policy before mapping a value to this hook.
@@ -61,7 +72,7 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
61
72
  * @cssprop --esp-section-max-width - The content well's cap. Defaults to `var(--esp-page-well-max-width, 72rem)`; `none` lets content span the band.
62
73
  * @cssprop --esp-section-padding-block - Vertical rhythm above and below the well. Defaults to `var(--esp-size-section)`.
63
74
  * @cssprop --esp-section-padding-inline - Horizontal breathing room inside the band at narrow viewports. Defaults to `var(--esp-size-medium)`.
64
- * @cssprop --esp-section-decoration-image - Raster alpha mask painted behind the well. Defaults to `none`.
75
+ * @cssprop --esp-section-decoration-image - Raster alpha mask painted behind the well when `decoration` is set. Defaults to `none`.
65
76
  * @cssprop --esp-section-decoration-color - Semantic tint applied through the mask. Defaults to the local `--esp-color-headings`.
66
77
  * @cssprop --esp-section-decoration-position - Mask position, including responsive or bleeding values. Defaults to `center`.
67
78
  * @cssprop --esp-section-decoration-size - Mask size. Defaults to `contain`.
@@ -72,6 +83,15 @@ import { EspalierElementBase } from "../shared/esp-element-base.js";
72
83
  * @menuIcon layout
73
84
  */
74
85
  export declare class EspalierSection extends EspalierElementBase {
86
+ /**
87
+ * Whether the section paints its decorative mask plane. Set it whenever
88
+ * `--esp-section-decoration-image` names an image; without it the
89
+ * section renders no decorative layer and the decoration hooks are
90
+ * inert.
91
+ *
92
+ * @type {boolean}
93
+ */
94
+ decoration: boolean;
75
95
  protected render(): import("lit-html").TemplateResult<1>;
76
96
  static styles: import("lit").CSSResult[];
77
97
  }
@@ -1,11 +1,11 @@
1
- var c=function(i,o,t,n){var a=arguments.length,e=a<3?o:n===null?n=Object.getOwnPropertyDescriptor(o,t):n,s;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")e=Reflect.decorate(i,o,t,n);else for(var l=i.length-1;l>=0;l--)(s=i[l])&&(e=(a<3?s(e):a>3?s(o,t,e):s(o,t))||e);return a>3&&e&&Object.defineProperty(o,t,e),e};import{css as d,html as v}from"lit";import{customElement as m}from"lit/decorators.js";import{EspalierElementBase as p}from"../shared/esp-element-base.js";import{renderVisualOverlay as u,visualOverlayStyles as y}from"../shared/visual-overlay.js";let r=class extends p{render(){return v`
1
+ var p=function(r,t,o,n){var s=arguments.length,e=s<3?t:n===null?n=Object.getOwnPropertyDescriptor(t,o):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")e=Reflect.decorate(r,t,o,n);else for(var l=r.length-1;l>=0;l--)(a=r[l])&&(e=(s<3?a(e):s>3?a(t,o,e):a(t,o))||e);return s>3&&e&&Object.defineProperty(t,o,e),e};import{css as d,html as v,nothing as m}from"lit";import{customElement as u,property as h}from"lit/decorators.js";import{EspalierElementBase as c}from"../shared/esp-element-base.js";import{renderVisualOverlay as y,visualOverlayStyles as f}from"../shared/visual-overlay.js";let i=class extends c{constructor(){super(...arguments),this.decoration=!1}render(){return v`
2
2
  <div class="esp-section" part="section">
3
- ${u({className:"decoration"})}
3
+ ${this.decoration?y({className:"decoration"}):m}
4
4
  <div class="esp-section-well" part="well">
5
5
  <slot></slot>
6
6
  </div>
7
7
  </div>
8
- `}};r.styles=[...p.styles,d`
8
+ `}};i.styles=[...c.styles,d`
9
9
  :host {
10
10
  display: block;
11
11
  }
@@ -40,4 +40,4 @@ var c=function(i,o,t,n){var a=arguments.length,e=a<3?o:n===null?n=Object.getOwnP
40
40
  position: relative;
41
41
  z-index: 1;
42
42
  }
43
- `,y],r=c([m("esp-section")],r);export{r as EspalierSection};
43
+ `,f],p([h({type:Boolean,reflect:!0})],i.prototype,"decoration",void 0),i=p([u("esp-section")],i);export{i as EspalierSection};
@@ -114,6 +114,19 @@ export interface ThemeFitToken {
114
114
  * since a zone's unexpected value then traces to a root theme line.
115
115
  */
116
116
  explicit?: "declared" | "inherited";
117
+ /**
118
+ * Present on a role-paired ink the role layer compiled (ESP0223).
119
+ * `"declared"` means the theme named the slot — a separate claim about
120
+ * this token's family. `"derived"` means it paired off another role,
121
+ * which for `action.ink` is the canvas: the token IS the page ground
122
+ * by contract, and its distance from the anchor it reports describes
123
+ * that contract rather than a theme that missed its brand.
124
+ *
125
+ * Absent when no such role is declared, and absent on a token an
126
+ * explicit mapping pinned — there the pin, not the role, chose the
127
+ * value, and {@link explicit} is the mark that says so.
128
+ */
129
+ pairing?: "declared" | "derived";
117
130
  }
118
131
  /**
119
132
  * A theme's fit report — the stable JSON shape the docs site renders.
@@ -184,7 +197,7 @@ export declare function printThemeFitReport(report: ThemeFitReport): void;
184
197
  /** One cross-token finding over a single surface's emitted values. */
185
198
  export interface ThemeFitLint {
186
199
  /** Stable lint identifier. */
187
- id: "action-canvas-separation" | "link-hover-ordering";
200
+ id: "action-anchor-inversion" | "action-canvas-separation" | "apca-target-unmet" | "link-hover-ordering";
188
201
  /** Lints describe design-quality hazards, not validation failures. */
189
202
  severity: "warning";
190
203
  /** The tokens the finding is about, recommended retune target first. */
@@ -212,7 +225,7 @@ export interface ThemeFitDataPaletteLint {
212
225
  message: string;
213
226
  }
214
227
  /** Runtime validation/comparison vocabulary used by the exported field descriptors. */
215
- export type ThemeFitFieldKind = "anchor" | "anchor-record" | "apca" | "boolean" | "data-palette-record" | "explicit" | "fit-lint-id" | "lint-array" | "message" | "number" | "palette-lint-id" | "palette-lint-record" | "report-array" | "scheme" | "semantic" | "semantic-array" | "series-pair" | "simulation" | "string" | "string-array" | "token-array" | "warning";
228
+ export type ThemeFitFieldKind = "anchor" | "anchor-record" | "apca" | "boolean" | "data-palette-record" | "explicit" | "fit-lint-id" | "lint-array" | "message" | "number" | "pairing" | "palette-lint-id" | "palette-lint-record" | "report-array" | "scheme" | "semantic" | "semantic-array" | "series-pair" | "simulation" | "string" | "string-array" | "token-array" | "warning";
216
229
  /** One runtime field descriptor used by fit-suite validation and comparison. */
217
230
  export interface ThemeFitFieldDescriptor<Field extends PropertyKey = PropertyKey> {
218
231
  readonly field: Field;
@@ -226,6 +239,8 @@ export declare const THEME_FIT_LINT_IDS: readonly ThemeFitLint["id"][];
226
239
  export declare const THEME_FIT_DATA_PALETTE_LINT_IDS: readonly ThemeFitDataPaletteLint["id"][];
227
240
  /** Every stable explicit-pin provenance value. */
228
241
  export declare const THEME_FIT_EXPLICIT_VALUES: readonly NonNullable<ThemeFitToken["explicit"]>[];
242
+ /** Every stable role-paired-ink provenance value. */
243
+ export declare const THEME_FIT_PAIRING_VALUES: readonly NonNullable<ThemeFitToken["pairing"]>[];
229
244
  type ThemeFitLintSeverity = ThemeFitLint["severity"] | ThemeFitDataPaletteLint["severity"];
230
245
  /** Every stable fit-suite lint severity. */
231
246
  export declare const THEME_FIT_LINT_SEVERITIES: readonly ThemeFitLintSeverity[];
@@ -256,6 +271,27 @@ export declare const THEME_FIT_DATA_PALETTE_LINT_FIELDS: readonly ThemeFitFieldD
256
271
  * wash itself signals the state and the ink must clear the text tier
257
272
  * there; when the wash equals the background (no visible wash), hover
258
273
  * must not read weaker than rest — a dimming hover feels disabled.
274
+ * - **action-anchor-inversion** (ESP0223) — the filled action rendered
275
+ * the *opposite way round* from the swatches it names: a surface whose
276
+ * swatch wants dark ink took light ink instead, or a declared pair's
277
+ * rendered lightness order reversed. Anchor drift on its own is by
278
+ * design — a stop supplies lightness (ADR-015) — and a raw distance
279
+ * cannot tell "a deeper rose" from "the gold became brown": a coral
280
+ * action drifts ΔE 0.29 and reads correctly, while a gold one drifts
281
+ * 0.34 and reads as a different design. The sign does tell them
282
+ * apart, and needs no threshold. This is also the one anchor drift an
283
+ * author cannot chase down: the action's stop is chosen by the engine,
284
+ * so seating the ramp — the remedy the lightness-ramps guide gives for
285
+ * every other token — cannot move it, and the fix is a pin.
286
+ * - **apca-target-unmet** (ESP0223) — enforcement moved a text token as
287
+ * far as its ramp allows and the pair still misses the legibility
288
+ * floor. The per-token `apca` block has always carried the numbers;
289
+ * nothing read them, so a theme could pin a surface no ink can carry
290
+ * and check clean.
291
+ *
292
+ * The two ESP0223 lints read `anchor`, `pairing` and `apca` rather than
293
+ * only `resolved`, because both findings are about how a token got where
294
+ * it is, which a colour alone cannot say.
259
295
  */
260
296
  export declare function themeFitLints(report: ThemeFitReport): ThemeFitLint[];
261
297
  /**
@@ -1 +1 @@
1
- import{apcaContrast as g,deltaEOK as _,parseOklch as v,serializeOklch as I}from"./color-engine.js";import{DATA_SERIES_KEYS as A,auditDataPalette as j,describePaletteCollision as C}from"./data-colors.js";import{DEFAULT_DARK_THEME as D,DEFAULT_LIGHT_THEME as $,explicitMappingTokens as w,mergeTheme as F,parseAnchorSource as P,resolveContextTheme as N}from"./theme.js";import{computeThemeProperties as y}from"../root/helpers/compute-theme-properties.js";function te(e,t,r={}){return L(e,t,r).report}function L(e,t,r={}){let o=e,s=null;if(r.context!==void 0){const n=N(e,r.context);if(!n)throw new Error(`themeFitReport: context "${r.context}" is not defined by the theme.`);o=n,s=new Set(Object.keys(e.contexts[r.context]?.semanticMappings??{}))}const c=[],m=y(o,t,c),k=w(o),l=c.map(n=>{const a=Y(n);return k.has(a.token)&&(a.explicit=s===null||s.has(a.token)?"declared":"inherited"),a});return{properties:m,report:{scheme:t,seedColor:o.seedColor,anchors:G(o.anchors),tokens:l,adjustedTokens:l.filter(n=>n.adjusted).map(n=>n.token)}}}function B(e){return e.tokens.map(t=>({token:t.token,source:t.source,requested:t.requested,resolved:t.resolved,apca:X(t),anchor:W(t)}))}function re(e){const t=e.adjustedTokens.length>0?`APCA moved ${e.adjustedTokens.join(", ")}`:"APCA moved nothing";console.info(`Espalier theme fit \u2014 ${e.scheme} scheme, seed ${e.seedColor}. ${t}.`),console.table(B(e))}function E(e){const t=Object.entries(e).map(([r,o])=>Object.freeze({field:r,kind:o.kind,compared:o.compared}));return Object.freeze(t)}const V={"action-canvas-separation":!0,"link-hover-ordering":!0},oe=Object.freeze(Object.keys(V)),q={"data-palette-cvd-collision":!0},ne=Object.freeze(Object.keys(q)),z={declared:!0,inherited:!0},se=Object.freeze(Object.keys(z)),U={warning:!0},ae=Object.freeze(Object.keys(U)),ce=E({token:{kind:"semantic",compared:!0},property:{kind:"string",compared:!0},source:{kind:"string",compared:!0},lightness:{kind:"string",compared:!0},requested:{kind:"string",compared:!0},resolved:{kind:"string",compared:!0},adjusted:{kind:"boolean",compared:!0},sourceResolved:{kind:"boolean",compared:!0},anchor:{kind:"anchor",compared:!0},apca:{kind:"apca",compared:!0},explicit:{kind:"explicit",compared:!0}}),ie=E({reference:{kind:"string",compared:!0},color:{kind:"string",compared:!0},deltaE:{kind:"number",compared:!0}}),de=E({from:{kind:"string",compared:!0},to:{kind:"string",compared:!0},targetLc:{kind:"number",compared:!0},against:{kind:"semantic",compared:!0},againstColor:{kind:"string",compared:!0},fromLc:{kind:"number",compared:!0},toLc:{kind:"number",compared:!0}}),ue=E({id:{kind:"fit-lint-id",compared:!0},severity:{kind:"warning",compared:!0},tokens:{kind:"semantic-array",compared:!0},measured:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),le=E({id:{kind:"palette-lint-id",compared:!0},severity:{kind:"warning",compared:!0},series:{kind:"series-pair",compared:!0},simulation:{kind:"simulation",compared:!0},measured:{kind:"number",compared:!0},threshold:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),x=.045,O=.5,b=75,K=.045;function S(e){const t=[],r=new Map(e.tokens.map(n=>[n.token,n.resolved])),o=n=>{const a=r.get(n);return a===void 0?null:v(a)},s=o("background"),c=o("actionBackground");if(s&&c){const n=_(c,s);if(n<x){const a=u(n,4);t.push({id:"action-canvas-separation",severity:"warning",tokens:["actionBackground","background"],measured:a,message:`actionBackground sits \u0394E ${a} from background (floor ${x}) \u2014 filled actions vanish into this canvas. Retune the surface apart: move the background stop, or pin actionBackground to a separated stop.`})}}const m=o("link"),k=o("linkHover"),l=o("linkHoverBg");if(s&&m&&k&&l){const n=Math.abs(g(m,s)),a=Math.abs(g(k,l));_(l,s)>=K?a+O<b&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHoverBg","linkHover"],measured:u(b-a,1),message:`linkHover reaches only Lc ${u(a,1)} on the linkHoverBg wash it actually paints (tier ${b}) \u2014 retune linkHoverBg before changing linkHover; the wash has one consumer while the ink has many.`}):a+O<n&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHover","link"],measured:u(n-a,1),message:`linkHover reads weaker than link on the same canvas (Lc ${u(a,1)} vs ${u(n,1)}) \u2014 a dimming hover feels disabled. Retune linkHover toward more contrast than the resting link.`})}return t}const R=":root",pe=E({scheme:{kind:"scheme",compared:!0},seedColor:{kind:"string",compared:!0},anchors:{kind:"anchor-record",compared:!0},tokens:{kind:"token-array",compared:!0},adjustedTokens:{kind:"semantic-array",compared:!0},surface:{kind:"string",compared:!0},lints:{kind:"lint-array",compared:!0}}),me=E({surfaces:{kind:"string-array",compared:!0},dataPalette:{kind:"data-palette-record",compared:!0},paletteLints:{kind:"palette-lint-record",compared:!0},light:{kind:"report-array",compared:!0},dark:{kind:"report-array",compared:!0}});function ke(e,t){const r=F($,e),o=F(D,t),s=[R,...[...new Set([...Object.keys(r.contexts),...Object.keys(o.contexts)])].sort()],c=p=>{const i={};for(let d=0;d<A.length;d+=1){const f=A[d],h=`--esp-color-series-${d+1}`,T=p[h];if(T===void 0)throw new Error(`Theme fit report did not emit required property ${h}.`);i[f]=T}return i},m=p=>j(p).map(i=>{const d=u(i.distance,4);return{id:"data-palette-cvd-collision",severity:"warning",series:i.series,simulation:i.simulation,measured:d,threshold:i.threshold,message:C(i)}}),k=(p,i)=>{const d=L(p,i);if(Object.keys(d.properties).length===0)throw new Error(`themeFitReportSuite: ${i} root emitted no properties for seed "${p.seedColor}".`);const f=[{...d.report,surface:R,lints:S(d.report)}];for(const h of s){if(h===R||!(h in p.contexts))continue;const H=L(p,i,{context:h}).report;f.push({...H,surface:h,lints:S(H)})}return{dataPalette:c(d.properties),reports:f}},l=k(r,"light"),n=k(o,"dark"),a={light:l.dataPalette,dark:n.dataPalette};return{surfaces:s,dataPalette:a,paletteLints:{light:m(a.light),dark:m(a.dark)},light:l.reports,dark:n.reports}}function u(e,t){const r=Math.pow(10,t);return Math.round(e*r)/r}function M(e,t){return t===void 0?e:`${e}.${t}`}function G(e){const t={};for(const[r,o]of Object.entries(e)){if(typeof o=="string"){t[r]=o;continue}for(const[s,c]of Object.entries(o))t[s==="color"?r:M(r,s)]=c}return t}function Y(e){const t=v(e.resolved),r=e.requested===void 0?e.resolved:I(e.requested),o={token:e.token,property:e.property,source:e.source,lightness:e.lightness,requested:r,resolved:e.resolved,adjusted:r!==e.resolved,sourceResolved:e.sourceResolved},s=P(e.source);if(s&&e.sourceResolved&&(o.anchor={reference:M(s.name,s.slot),color:I(e.base),deltaE:u(_(e.base,t),4)}),e.contrast){const c=e.contrast.background;o.apca={from:r,to:e.resolved,targetLc:e.contrast.targetLc,against:e.contrast.against,againstColor:I(c),fromLc:u(Math.abs(g(v(r),c)),1),toLc:u(Math.abs(g(t,c)),1)}}return o}function X(e){if(!e.apca)return"";const{targetLc:t,against:r,fromLc:o,toLc:s}=e.apca;return e.adjusted?`Lc ${t} vs ${r} \u2014 pushed from Lc ${o} to Lc ${s}`:`Lc ${t} vs ${r} \u2014 met at Lc ${o}`}function W(e){return e.anchor?`${e.anchor.reference} \u0394E ${e.anchor.deltaE}`:e.sourceResolved?"":"unresolved \u2014 seed used"}export{R as ROOT_SURFACE,ie as THEME_FIT_ANCHOR_FIELDS,de as THEME_FIT_APCA_FIELDS,le as THEME_FIT_DATA_PALETTE_LINT_FIELDS,ne as THEME_FIT_DATA_PALETTE_LINT_IDS,se as THEME_FIT_EXPLICIT_VALUES,ue as THEME_FIT_LINT_FIELDS,oe as THEME_FIT_LINT_IDS,ae as THEME_FIT_LINT_SEVERITIES,pe as THEME_FIT_REPORT_FIELDS,me as THEME_FIT_SUITE_FIELDS,ce as THEME_FIT_TOKEN_FIELDS,re as printThemeFitReport,S as themeFitLints,te as themeFitReport,ke as themeFitReportSuite,B as themeFitRows};
1
+ import{apcaContrast as T,deltaEOK as x,parseOklch as _,serializeOklch as $}from"./color-engine.js";import{DATA_SERIES_KEYS as C,auditDataPalette as q,describePaletteCollision as K}from"./data-colors.js";import{DEFAULT_DARK_THEME as G,DEFAULT_LIGHT_THEME as Y,explicitMappingTokens as W,mergeTheme as j,parseAnchorSource as X,resolveContextTheme as J,roleInkProvenance as Q}from"./theme.js";import{computeThemeProperties as Z}from"../root/helpers/compute-theme-properties.js";function ke(e,t,o={}){return H(e,t,o).report}function H(e,t,o={}){let n=e,c=null;if(o.context!==void 0){const s=J(e,o.context);if(!s)throw new Error(`themeFitReport: context "${o.context}" is not defined by the theme.`);n=s,c=new Set(Object.keys(e.contexts[o.context]?.semanticMappings??{}))}const p=[],v=Z(n,t,p),L=W(n),f=Q(n.roles),E=p.map(s=>{const a=ie(s);if(L.has(a.token))a.explicit=c===null||c.has(a.token)?"declared":"inherited";else{const i=f[a.token];i!==void 0&&(a.pairing=i)}return a});return{properties:v,report:{scheme:t,seedColor:n.seedColor,anchors:ce(n.anchors),tokens:E,adjustedTokens:E.filter(s=>s.adjusted).map(s=>s.token)}}}function ee(e){return e.tokens.map(t=>({token:t.token,source:t.source,requested:t.requested,resolved:t.resolved,apca:de(t),anchor:le(t)}))}function ge(e){const t=e.adjustedTokens.length>0?`APCA moved ${e.adjustedTokens.join(", ")}`:"APCA moved nothing";console.info(`Espalier theme fit \u2014 ${e.scheme} scheme, seed ${e.seedColor}. ${t}.`),console.table(ee(e))}function I(e){const t=Object.entries(e).map(([o,n])=>Object.freeze({field:o,kind:n.kind,compared:n.compared}));return Object.freeze(t)}const te={"action-anchor-inversion":!0,"action-canvas-separation":!0,"apca-target-unmet":!0,"link-hover-ordering":!0},fe=Object.freeze(Object.keys(te)),re={"data-palette-cvd-collision":!0},Ee=Object.freeze(Object.keys(re)),ne={declared:!0,inherited:!0},Te=Object.freeze(Object.keys(ne)),oe={declared:!0,derived:!0},_e=Object.freeze(Object.keys(oe)),ae={warning:!0},ve=Object.freeze(Object.keys(ae)),Le=I({token:{kind:"semantic",compared:!0},property:{kind:"string",compared:!0},source:{kind:"string",compared:!0},lightness:{kind:"string",compared:!0},requested:{kind:"string",compared:!0},resolved:{kind:"string",compared:!0},adjusted:{kind:"boolean",compared:!0},sourceResolved:{kind:"boolean",compared:!0},anchor:{kind:"anchor",compared:!0},apca:{kind:"apca",compared:!0},explicit:{kind:"explicit",compared:!0},pairing:{kind:"pairing",compared:!0}}),Ie=I({reference:{kind:"string",compared:!0},color:{kind:"string",compared:!0},deltaE:{kind:"number",compared:!0}}),be=I({from:{kind:"string",compared:!0},to:{kind:"string",compared:!0},targetLc:{kind:"number",compared:!0},against:{kind:"semantic",compared:!0},againstColor:{kind:"string",compared:!0},fromLc:{kind:"number",compared:!0},toLc:{kind:"number",compared:!0}}),Re=I({id:{kind:"fit-lint-id",compared:!0},severity:{kind:"warning",compared:!0},tokens:{kind:"semantic-array",compared:!0},measured:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),Me=I({id:{kind:"palette-lint-id",compared:!0},severity:{kind:"warning",compared:!0},series:{kind:"series-pair",compared:!0},simulation:{kind:"simulation",compared:!0},measured:{kind:"number",compared:!0},threshold:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),D=.045,N=.045,M=75,y={l:0,c:0,h:0},P={l:1,c:0,h:0},B=.5,F=75,se=.045;function V(e){const t=[],o=new Map(e.tokens.map(r=>[r.token,r.resolved])),n=r=>{const d=o.get(r);return d===void 0?null:_(d)},c=n("background"),p=n("actionBackground");if(c&&p){const r=x(p,c);if(r<D){const d=u(r,4);t.push({id:"action-canvas-separation",severity:"warning",tokens:["actionBackground","background"],measured:d,message:`actionBackground sits \u0394E ${d} from background (floor ${D}) \u2014 filled actions vanish into this canvas. Retune the surface apart: move the background stop, or pin actionBackground to a separated stop.`})}}const v=n("link"),L=n("linkHover"),f=n("linkHoverBg");if(c&&v&&L&&f){const r=Math.abs(T(v,c)),d=Math.abs(T(L,f));x(f,c)>=se?d+B<F&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHoverBg","linkHover"],measured:u(F-d,1),message:`linkHover reaches only Lc ${u(d,1)} on the linkHoverBg wash it actually paints (tier ${F}) \u2014 retune linkHoverBg before changing linkHover; the wash has one consumer while the ink has many.`}):d+B<r&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHover","link"],measured:u(r-d,1),message:`linkHover reads weaker than link on the same canvas (Lc ${u(d,1)} vs ${u(r,1)}) \u2014 a dimming hover feels disabled. Retune linkHover toward more contrast than the resting link.`})}const E=r=>Math.abs(T(y,r))>=Math.abs(T(P,r))?"dark":"light",s=e.tokens.find(r=>r.token==="actionBackground"),a=e.tokens.find(r=>r.token==="actionText"),i=[],l=[];let m=0;const h=a?.anchor?_(a.anchor.color):null,g=a?_(a.resolved):null,k=s?.anchor?_(s.anchor.color):null,b=s?_(s.resolved):null,O=g&&b?g.l>b.l?"light":"dark":null;s?.anchor&&k&&b&&O&&s.anchor.deltaE>=N&&E(k)!==O&&(i.push("actionBackground"),m=Math.max(m,s.anchor.deltaE),l.push(`"${s.anchor.reference}" wants ${E(k)} ink but actionBackground renders carrying a ${O} label (\u0394E ${u(s.anchor.deltaE,4)})`)),a?.anchor&&a.pairing!=="derived"&&h&&g&&k&&b&&a.anchor.deltaE>=N&&k.l!==h.l&&Math.sign(k.l-h.l)!==Math.sign(b.l-g.l)&&(i.push("actionText"),m=Math.max(m,a.anchor.deltaE),l.push(`the declared pair puts "${s.anchor.reference}" ${k.l>h.l?"above":"below"} "${a.anchor.reference}" in lightness and the rendered pair puts it ${b.l>g.l?"above":"below"} (\u0394E ${u(a.anchor.deltaE,4)})`)),i.length>0&&t.push({id:"action-anchor-inversion",severity:"warning",tokens:i,measured:u(m,4),message:`The filled action renders the opposite way round from the swatches it names: ${l.join("; ")}. `+(s?.explicit===void 0?"A filled action's ramp stop is chosen by the engine near its mid-band target, so seating the ramp cannot move it the way it moves every other anchored token. Retune by pinning semanticMappings.actionBackground to a stop that carries the swatch":"semanticMappings.actionBackground is already pinned, so the engine did not place this \u2014 retune the stop that pin names")+" \u2014 and check the pair still clears its tier there, because a swatch this far off the band often cannot hold a label at its own lightness."});const A=e.tokens.filter(r=>r.apca!==void 0&&r.apca.toLc<Math.min(r.apca.targetLc,M)).sort((r,d)=>Math.min(d.apca.targetLc,M)-d.apca.toLc-(Math.min(r.apca.targetLc,M)-r.apca.toLc)||(r.token<d.token?-1:r.token>d.token?1:0));if(A.length>0){const r=A[0].apca,d=A.map(R=>`${R.token} reaches Lc ${u(R.apca.toLc,1)} on ${R.apca.against} (floor ${Math.min(R.apca.targetLc,M)})`),w=_(r.againstColor),U=w!==null&&Math.max(Math.abs(T(y,w)),Math.abs(T(P,w)))>=Math.min(r.targetLc,M);t.push({id:"apca-target-unmet",severity:"warning",tokens:A.map(R=>R.token),measured:u(Math.min(r.targetLc,M)-r.toLc,1),message:`${d.join(", ")} \u2014 enforcement moved the ink as far as this ramp allows and the pair still falls short. `+(U?"The opposite ink pole does clear the floor on that ground, so the emitted ink is on the weaker side rather than the ground being impossible \u2014 check the pairing before retuning the ground.":"No ink reaches the floor on that ground, so retune the ground each pair reads against toward a lightness that can carry it.")})}return t}const S=":root",Ae=I({scheme:{kind:"scheme",compared:!0},seedColor:{kind:"string",compared:!0},anchors:{kind:"anchor-record",compared:!0},tokens:{kind:"token-array",compared:!0},adjustedTokens:{kind:"semantic-array",compared:!0},surface:{kind:"string",compared:!0},lints:{kind:"lint-array",compared:!0}}),we=I({surfaces:{kind:"string-array",compared:!0},dataPalette:{kind:"data-palette-record",compared:!0},paletteLints:{kind:"palette-lint-record",compared:!0},light:{kind:"report-array",compared:!0},dark:{kind:"report-array",compared:!0}});function Oe(e,t){const o=j(Y,e),n=j(G,t),c=[S,...[...new Set([...Object.keys(o.contexts),...Object.keys(n.contexts)])].sort()],p=a=>{const i={};for(let l=0;l<C.length;l+=1){const m=C[l],h=`--esp-color-series-${l+1}`,g=a[h];if(g===void 0)throw new Error(`Theme fit report did not emit required property ${h}.`);i[m]=g}return i},v=a=>q(a).map(i=>{const l=u(i.distance,4);return{id:"data-palette-cvd-collision",severity:"warning",series:i.series,simulation:i.simulation,measured:l,threshold:i.threshold,message:K(i)}}),L=(a,i)=>{const l=H(a,i);if(Object.keys(l.properties).length===0)throw new Error(`themeFitReportSuite: ${i} root emitted no properties for seed "${a.seedColor}".`);const m=[{...l.report,surface:S,lints:V(l.report)}];for(const h of c){if(h===S||!(h in a.contexts))continue;const k=H(a,i,{context:h}).report;m.push({...k,surface:h,lints:V(k)})}return{dataPalette:p(l.properties),reports:m}},f=L(o,"light"),E=L(n,"dark"),s={light:f.dataPalette,dark:E.dataPalette};return{surfaces:c,dataPalette:s,paletteLints:{light:v(s.light),dark:v(s.dark)},light:f.reports,dark:E.reports}}function u(e,t){const o=Math.pow(10,t);return Math.round(e*o)/o}function z(e,t){return t===void 0?e:`${e}.${t}`}function ce(e){const t={};for(const[o,n]of Object.entries(e)){if(typeof n=="string"){t[o]=n;continue}for(const[c,p]of Object.entries(n))t[c==="color"?o:z(o,c)]=p}return t}function ie(e){const t=_(e.resolved),o=e.requested===void 0?e.resolved:$(e.requested),n={token:e.token,property:e.property,source:e.source,lightness:e.lightness,requested:o,resolved:e.resolved,adjusted:o!==e.resolved,sourceResolved:e.sourceResolved},c=X(e.source);if(c&&e.sourceResolved&&(n.anchor={reference:z(c.name,c.slot),color:$(e.base),deltaE:u(x(e.base,t),4)}),e.contrast){const p=e.contrast.background;n.apca={from:o,to:e.resolved,targetLc:e.contrast.targetLc,against:e.contrast.against,againstColor:$(p),fromLc:u(Math.abs(T(_(o),p)),1),toLc:u(Math.abs(T(t,p)),1)}}return n}function de(e){if(!e.apca)return"";const{targetLc:t,against:o,fromLc:n,toLc:c}=e.apca;return e.adjusted?`Lc ${t} vs ${o} \u2014 pushed from Lc ${n} to Lc ${c}`:`Lc ${t} vs ${o} \u2014 met at Lc ${n}`}function le(e){return e.anchor?`${e.anchor.reference} \u0394E ${e.anchor.deltaE}`:e.sourceResolved?"":"unresolved \u2014 seed used"}export{S as ROOT_SURFACE,Ie as THEME_FIT_ANCHOR_FIELDS,be as THEME_FIT_APCA_FIELDS,Me as THEME_FIT_DATA_PALETTE_LINT_FIELDS,Ee as THEME_FIT_DATA_PALETTE_LINT_IDS,Te as THEME_FIT_EXPLICIT_VALUES,Re as THEME_FIT_LINT_FIELDS,fe as THEME_FIT_LINT_IDS,ve as THEME_FIT_LINT_SEVERITIES,_e as THEME_FIT_PAIRING_VALUES,Ae as THEME_FIT_REPORT_FIELDS,we as THEME_FIT_SUITE_FIELDS,Le as THEME_FIT_TOKEN_FIELDS,ge as printThemeFitReport,V as themeFitLints,ke as themeFitReport,Oe as themeFitReportSuite,ee as themeFitRows};
@@ -269,6 +269,32 @@ export declare const ROLE_NAMES: readonly RoleName[];
269
269
  * following `accent.text` exactly as before.
270
270
  */
271
271
  export declare const ROLE_TOKEN_PLAN: Readonly<Record<RoleName, Readonly<Record<string, ReadonlyArray<[SemanticColorName, LightnessKey]>>>>>;
272
+ /**
273
+ * Role slots whose ink lightness is derived from the surface that role
274
+ * actually painted, rather than taken from {@link ROLE_TOKEN_PLAN}.
275
+ *
276
+ * {@link resolvePairedInkStop} used to run only for a slot the theme
277
+ * left *undeclared*, so naming `action.ink` took the plan's `surface`
278
+ * stop verbatim. In a light ramp both rules answer `surface` and the
279
+ * difference never showed. In a dark ramp the plan's stop is the
280
+ * near-black page ground, which is the wrong side of a mid-dark action
281
+ * surface: enforcement had to walk the label the whole way across the
282
+ * ramp and stopped at the first value that cleared the target, emitting
283
+ * a weaker ink than the ramp could give. ADR-016 is explicit that the
284
+ * model's job is to hand enforcement the strongest available starting
285
+ * point on the correct side, so the derivation now runs for a declared
286
+ * slot too (ESP0223).
287
+ *
288
+ * The source still comes from the theme: naming `action.ink` chooses
289
+ * the family, exactly as ADR-015 says an anchor supplies hue and chroma
290
+ * while the ramp supplies lightness.
291
+ *
292
+ * Every entry here must also appear in {@link ROLE_PAIRED_INK}: the
293
+ * compile branch is gated on `paired` first, and
294
+ * {@link roleInkProvenance} walks the pairing table, so an entry in only
295
+ * this set would be silently inert in both.
296
+ */
297
+ export declare const ROLE_DERIVED_INK: ReadonlySet<string>;
272
298
  /**
273
299
  * Ink slots that derive from another role when the theme does not
274
300
  * declare them.
@@ -293,6 +319,8 @@ interface CompileRoleOptions {
293
319
  actionSurfaceContrast?: (source: MappingSource, stop: LightnessKey) => number;
294
320
  /** ΔE-OK between an action surface candidate and the theme's background. */
295
321
  actionSurfaceSeparation?: (source: MappingSource, stop: LightnessKey) => number;
322
+ /** Which ink pole reads better on a finished action surface at a lightness. */
323
+ actionSurfacePole?: (source: MappingSource, lightness: number) => "dark" | "light";
296
324
  }
297
325
  /**
298
326
  * Compile roles into semantic mappings.
@@ -304,6 +332,23 @@ interface CompileRoleOptions {
304
332
  * reach.
305
333
  */
306
334
  export declare function compileRoles(roles: ThemeRoles, lightness: LightnessMap, baseMappings: SemanticMappings, options?: CompileRoleOptions): Partial<SemanticMappings>;
335
+ /**
336
+ * Whether each role-paired ink token's *source* was named by the theme
337
+ * or paired off another role (ESP0223).
338
+ *
339
+ * The distinction matters to anything judging how far a token landed
340
+ * from the swatch it names. `action.ink` defaults to the canvas colour,
341
+ * so an undeclared ink IS the page ground by contract — it is re-lit to
342
+ * the opposite end of the ramp on purpose, and the large anchor ΔE that
343
+ * follows describes the contract working, not a theme missing its
344
+ * brand. A theme that names the slot has made a separate claim about
345
+ * the label's family, and the same ΔE then describes a claim that did
346
+ * not survive.
347
+ *
348
+ * A pure read of `roles`: the compile is not re-run, and a role the
349
+ * theme never declared reports nothing rather than guessing.
350
+ */
351
+ export declare function roleInkProvenance(roles: ThemeRoles): Partial<Record<SemanticColorName, "declared" | "derived">>;
307
352
  /** The complete, resolved Espalier theme. */
308
353
  export interface EspalierTheme {
309
354
  /**
@@ -665,6 +710,11 @@ export declare const DEFAULT_DARK_LIGHTNESS: Readonly<LightnessMap>;
665
710
  *
666
711
  * Each entry tells the color engine which variant supplies the
667
712
  * hue and which lightness key sets the perceived brightness.
713
+ *
714
+ * `actionBackground` carries the **light** scheme's stop; the dark
715
+ * theme overrides it through {@link buildDefaultSemanticMappings}. See
716
+ * {@link DEFAULT_ACTION_BACKGROUND_STOP} for why that one mapping
717
+ * cannot share a name across schemes.
668
718
  */
669
719
  export declare const DEFAULT_SEMANTIC_MAPPINGS: Readonly<SemanticMappings>;
670
720
  /** Built-in authored stack for body and UI text. */
@@ -1 +1 @@
1
- import{UNSAFE_KEYS as dt,isSafeKey as M}from"./unsafe-keys.js";import{ACCEPTED_COLOR_FORMS as oe,apcaContrast as mt,clampChannel as ge,deltaEOK as gt,deriveSemantic as ae,gamutMapToSRGB as he,linearRgbToOklab as ht,oklchToSRGB as yt,parseCssColor as W,parseOklch as bt,serializeOklch as ce,srgbToLinearRGB as $t}from"./color-engine.js";import{computeVariants as ye,parseAnchorSource as xt,resolveAnchorColor as kt,resolveMappingSource as ue}from"./variant-engine.js";import{auditColorDistances as Fe,auditDataPalette as St,describePaletteCollision as At,DATA_SERIES_KEYS as fe,DEFAULT_DATA_PALETTE as be,DEFAULT_DATA_RAMP_STEPS as Mt,MAX_DATA_RAMP_STEPS as $e,MIN_DATA_RAMP_LIGHTNESS_STEP as We,MIN_DATA_RAMP_STEPS as xe}from"./data-colors.js";const j=/^[a-z][a-z0-9-]*$/;function ke(e){return xt(e)}function je(e,n){return kt(e,n)}function Ot(e,n){const t=ke(e);if(t){const o=je(n,t);return o&&W(o)?o:null}return W(e)?e:null}const se=["canvas","ink","accent","action","structure"],Se={canvas:{color:[["background","surface"],["layer1","raised1"],["layer2","raised2"],["layer3","raised3"],["layer4","raised4"]]},ink:{color:[["text","text"],["typeOverline","text"],["typeLabel","text"],["typeLead","text"],["typeCaption","text"],["inputSelection","text"]],heading:[["headings","muted"],["headingsHover","ink"]]},accent:{color:[["linkHoverBg","raised2"],["inputSelectionBg","raised2"],["inputCaret","ink"]],text:[["link","accent"]],hover:[["linkHover","text"]]},action:{color:[["actionBackground","muted"]],ink:[["actionText","surface"]]},structure:{color:[["border","border"],["shadow","shadow"]]}},Tt=new Set(["action.color"]),Ct={canvas:"background",ink:"text",accent:"link",action:"actionBackground",structure:"border"},Rt={"action.ink":{role:"canvas",slot:"color"}},vt=.45,Et=.045;function ze(e,n,t){const o=Ue.actionText,i=[...U].sort((y,T)=>e[y]-e[T]||U.indexOf(y)-U.indexOf(T)),a=n?i.filter(y=>n(y)>=o.targetLc):i,u=t?a.filter(y=>t(y)>=Et):a,d=u.length>0?u:a,m=d.length>0?d:i;let A,k=1/0;for(const y of m){const T=Math.abs(e[y]-vt);T<k&&(k=T,A=y)}return A??"muted"}function wt(e,n,t){const o=Oe(n,t,e)>.5;let i=U[0];for(const a of U)(o?n[a]<n[i]:n[a]>n[i])&&(i=a);return i}const Bt={"accent.hover":"text"};function _t(e,n){const t=new Map;try{const o=de(n,e),i=(a,u,d,m)=>{const A=ke(u),k=A?je(m,A):null,y=k===null?null:W(k),T=t.get(a)??[];T.some(_=>_.source===u&&_.chroma===y?.c)||(T.push({source:u,where:d,chroma:y?.c}),t.set(a,T))};for(const[a,u]of Object.entries(o.semanticMappings))u.source.startsWith("anchor:")&&i(a,u.source,"the root table",o.anchors);for(const a of Object.keys(o.contexts)){const u=it(o,a);if(u)for(const[d,m]of Object.entries(u.semanticMappings))m.source.startsWith("anchor:")&&i(d,m.source,`contexts.${a}`,u.anchors)}}catch{return new Map}return t}function X(e,n){if(e===void 0)return;if(typeof e=="string")return n==="color"?e:void 0;const t=e[n];return typeof t=="string"?t:void 0}function Ke(e,n,t,o={}){const i={},a={};for(const[u,d]of Object.entries(o.explicitMappings??{}))d!==void 0&&(a[u]=d.lightness);for(const u of se){const d=e[u];if(d!==void 0)for(const[m,A]of Object.entries(Se[u])){const k=Rt[`${u}.${m}`];let y=X(d,m),T=!1;if(y===void 0){k&&(y=X(e[k.role],k.slot),y??=t[Ct[k.role]]?.source,T=y!==void 0);const _=Bt[`${u}.${m}`];_!==void 0&&(y??=X(d,_)),y??=X(d,"color")}if(y!==void 0)for(const[_,z]of A){let H=z;if(Tt.has(`${u}.${m}`))H=ze(n,o.actionSurfaceContrast?s=>o.actionSurfaceContrast(y,s):void 0,o.actionSurfaceSeparation?s=>o.actionSurfaceSeparation(y,s):void 0);else if(T&&k){const s=Ue[_],r=(s&&a[s.bg])??ze(n,o.actionSurfaceContrast?c=>o.actionSurfaceContrast(X(d,"color"),c):void 0,o.actionSurfaceSeparation?c=>o.actionSurfaceSeparation(X(d,"color"),c):void 0);H=wt(r,n,o.tones??{})}i[_]={source:y,lightness:H}}}}return i}const Ue={text:{bg:"background",targetLc:75},typeOverline:{bg:"background",targetLc:90},typeLabel:{bg:"background",targetLc:75},typeLead:{bg:"background",targetLc:75},typeCaption:{bg:"background",targetLc:90},dangerText:{bg:"background",targetLc:75},headings:{bg:"background",targetLc:60},headingsHover:{bg:"background",targetLc:60},link:{bg:"background",targetLc:75},linkHover:{bg:"linkHoverBg",targetLc:75},actionText:{bg:"actionBackground",targetLc:75},inputCaret:{bg:"layer2",targetLc:60},inputSelection:{bg:"inputSelectionBg",targetLc:60}},K=["background","layer1","layer2","layer3","layer4","actionBackground","actionText","border","shadow","text","typeOverline","typeLabel","typeLead","typeCaption","dangerText","headings","headingsHover","link","linkHover","linkHoverBg","inputCaret","inputSelection","inputSelectionBg"];function cn(e){return typeof e=="string"&&K.includes(e)}const Lt=["typeOverline","typeLabel","typeLead","typeCaption"],Ae=["primary","analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning","info"],ee=["danger","success","warning","info"],It=["analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning","info"],U=["surface","raised1","raised2","raised3","raised4","accent","muted","text","border","ink","shadow"],Ge="tone:";function Me(e){if(typeof e!="string"||!e.startsWith(Ge))return null;const n=e.slice(Ge.length);return M(n)&&j.test(n)?n:null}function te(e){return typeof e!="string"?!1:U.includes(e)}function Oe(e,n,t){if(te(t))return e[t];const o=Me(t);return o===null?e.surface:n?.[o]??e.surface}const Nt={surface:.99,raised1:.97,raised2:.9,raised3:.8,raised4:.72,accent:.5,muted:.45,text:.35,border:.3,ink:.25,shadow:.2},Ht={surface:.15,raised1:.2,raised2:.3,raised3:.4,raised4:.36,accent:.6,muted:.75,text:.85,border:.7,ink:.95,shadow:.6},Te={background:{source:"primary",lightness:"surface"},layer1:{source:"primary",lightness:"raised1"},layer2:{source:"primary",lightness:"raised2"},layer3:{source:"primary",lightness:"raised3"},layer4:{source:"primary",lightness:"raised4"},actionBackground:{source:"primary",lightness:"raised3"},actionText:{source:"primary",lightness:"ink"},border:{source:"primary",lightness:"border"},shadow:{source:"primary",lightness:"shadow"},text:{source:"primary",lightness:"text"},typeOverline:{source:"primary",lightness:"text"},typeLabel:{source:"primary",lightness:"text"},typeLead:{source:"primary",lightness:"text"},typeCaption:{source:"primary",lightness:"text"},dangerText:{source:"danger",lightness:"text"},headings:{source:"primary",lightness:"muted"},headingsHover:{source:"primary",lightness:"text"},link:{source:"complementary",lightness:"accent"},linkHover:{source:"complementary",lightness:"text"},linkHoverBg:{source:"triadic-left",lightness:"raised2"},inputCaret:{source:"triadic-right",lightness:"ink"},inputSelection:{source:"complementary",lightness:"text"},inputSelectionBg:{source:"triadic-left",lightness:"raised2"}},Y=.4;function Ce(){const e={};for(const n of K)e[n]={min:0,max:Y};return e}const Ve="system-ui, sans-serif",Je="monospace",Ye={seedColor:"oklch(0.7 0.125 216)",fontBody:Ve,fontHeadings:"",fontBrand:"",fontMenu:"",fontMonospace:Je,fontWeightBody:"normal",fontWeightHeadings:"bold",fontWeightBrand:"bold",fontWeightMenu:"bold",fontWeightMonospace:"normal",stylesheets:[],rootFontSize:16,typeRatio:1.25,spaceRatio:1.618,borderRadius:.2,viewportMin:320,viewportMax:1200,angles:{analogous:30,complementary:180,splitComplementary:30,triadic:120},semanticHues:{danger:27,success:150,warning:90,info:244},variantChroma:{},intents:{},tones:{},chroma:Ce(),semanticMappings:{...Te},explicitMappingTokens:[],anchors:{},roles:{},contexts:{},dataPalette:{...be},dataRamps:{}},Re={...Ye,chroma:Ce(),semanticMappings:{...Te},anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...be},dataRamps:{},lightness:{...Nt}},qe={...Ye,chroma:Ce(),semanticMappings:{...Te},anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...be},dataRamps:{},lightness:{...Ht}},le=new WeakMap;le.set(Re,new Set),le.set(qe,new Set);function Pt(e,n){return dt.has(e)?void 0:n}function pe(e){const n=e.explicitMappingTokens;if(!Array.isArray(n)||n.some(o=>typeof o!="string"||!K.includes(o)))return;const t=new Set(n);if(t.size===n.length&&!(t.size>0&&(!L(e.semanticMappings)||[...t].some(o=>!Object.prototype.hasOwnProperty.call(e.semanticMappings,o)))))return t}function Xe(e){return K.filter(n=>e.has(n))}function un(e){return`--esp-color-${e.replace(/([A-Z])/g,"-$1").replace(/(\d)/g,"-$1").toLowerCase()}`}function Dt(e){try{const n=Ze(e),t=JSON.parse(n,Pt);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}const ve="\xEF\xBB\xBF";function Ft(e){if(/^[\u0000-\u007f]*$/.test(e))return btoa(e);const n=new TextEncoder().encode(e);let t=ve;for(const o of n)t+=String.fromCharCode(o);return btoa(t)}function Ze(e){const n=atob(e);if(!n.startsWith(ve))return n;const t=Uint8Array.from(n.slice(ve.length),o=>o.charCodeAt(0));return new TextDecoder("utf-8",{fatal:!0}).decode(t)}function Ee(e){return Ft(JSON.stringify(e))}function Wt(e){const n={};for(const t of ee){const o=e[t];typeof o=="string"&&(n[t]=o.startsWith("anchor:")?o:re(o))}return n}function re(e){if(bt(e))return e;const n=W(e);return n?ce(n):e}function Qe(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&(t[o]=i);if(!n)return t;for(const[o,i]of Object.entries(n)){if(i===void 0||!M(o))continue;const a=t[o];if(a!==void 0&&typeof i=="object"&&i!==null){const u={};if(typeof a=="string")u.color=a;else for(const[d,m]of Object.entries(a))M(d)&&(u[d]=m);for(const[d,m]of Object.entries(i))m!==void 0&&M(d)&&(u[d]=m);t[o]=u;continue}t[o]=i}return t}function we(e){const n={};if(!L(e))return n;for(const[t,o]of Object.entries(e))M(t)&&j.test(t)&&!te(t)&&typeof o=="number"&&Number.isFinite(o)&&o>=0&&o<=1&&(n[t]=o);return n}function jt(e,n){return{...we(e),...we(n)}}function zt(e,n){const t={...e};if(!L(n))return t;for(const o of U){const i=n[o];typeof i=="number"&&Number.isFinite(i)&&i>=0&&i<=1&&(t[o]=i)}return t}function et(e){if(typeof e!="object"||e===null||Array.isArray(e))return null;const n=e,t={};for(const o of se){const i=n[o];i!==void 0&&(t[o]=i)}if(typeof n.lightness=="object"&&n.lightness!==null&&!Array.isArray(n.lightness)){const o={};for(const i of U){const a=n.lightness[i];a!==void 0&&(o[i]=a)}t.lightness=o}if(n.tones!==void 0){const o=we(n.tones);Object.keys(o).length>0&&(t.tones=o)}if(typeof n.semanticMappings=="object"&&n.semanticMappings!==null&&!Array.isArray(n.semanticMappings)){const o={};for(const[i,a]of Object.entries(n.semanticMappings)){if(!M(i)||!K.includes(i)||typeof a!="object"||a===null||Array.isArray(a))continue;const{source:u,lightness:d}=a;typeof u=="string"&&(typeof d!="string"||!te(d)&&Me(d)===null||(o[i]={source:u,lightness:d}))}Object.keys(o).length>0&&(t.semanticMappings=o)}return t}function Kt(e,n){const t={};for(const[o,i]of Object.entries(e)){if(!M(o)||!j.test(o))continue;const a=et(i);a&&(t[o]=a)}if(!n)return t;for(const[o,i]of Object.entries(n)){if(!M(o)||!j.test(o)||i===void 0)continue;const a=et(i);if(!a)continue;const u=t[o];t[o]={...u??{},...a,...u?.lightness||a.lightness?{lightness:{...u?.lightness,...a.lightness}}:{},...u?.tones||a.tones?{tones:{...u?.tones,...a.tones}}:{},...u?.semanticMappings||a.semanticMappings?{semanticMappings:{...u?.semanticMappings,...a.semanticMappings}}:{}}}return t}function L(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function F(e){const n={};for(const[t,o]of Object.entries(e))o!==void 0&&M(t)&&(n[t]=o);return n}function tt(e){if(!L(e))return e;const n=F(e);return L(e.lightness)&&(n.lightness=F(e.lightness)),L(e.tones)&&(n.tones=F(e.tones)),n}function Ut(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&(t[o]=tt(i));if(!n)return t;for(const[o,i]of Object.entries(n)){if(!M(o)||i===void 0)continue;const a=t[o];if(!L(a)||!L(i)){t[o]=tt(i);continue}const u={...F(a),...F(i)};L(a.lightness)&&L(i.lightness)?u.lightness={...F(a.lightness),...F(i.lightness)}:L(i.lightness)&&(u.lightness=F(i.lightness)),L(a.tones)&&L(i.tones)?u.tones={...F(a.tones),...F(i.tones)}:L(i.tones)&&(u.tones=F(i.tones)),L(a.semanticMappings)&&L(i.semanticMappings)?u.semanticMappings={...F(a.semanticMappings),...F(i.semanticMappings)}:L(i.semanticMappings)&&(u.semanticMappings=F(i.semanticMappings)),t[o]=u}return t}function Gt(e){const n={};for(const[t,o]of Object.entries(e)){if(!M(t))continue;if(typeof o=="string"){n[t]=re(o);continue}const i={};for(const[a,u]of Object.entries(o))M(a)&&(i[a]=typeof u=="string"?re(u):u);n[t]=i}return n}function ie(e){return typeof e!="string"?"":e.startsWith("anchor:")?e:re(e)}function Vt(e){const n={};for(const t of fe)n[t]=ie(e[t]);return n}function nt(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&j.test(o)&&i&&typeof i=="object"&&!Array.isArray(i)&&(t[o]={...i});if(!n)return t;for(const[o,i]of Object.entries(n)){if(!M(o)||!j.test(o)||!i||typeof i!="object"||Array.isArray(i))continue;const a=t[o],u=a!==void 0&&i.type!==void 0&&i.type!==a.type;t[o]={...u?{}:a??{},...i}}return t}function Jt(e){const n={};for(const[t,o]of Object.entries(e))if(M(t)){if(o.type==="sequential"&&typeof o.source=="string"){n[t]={...o,source:ie(o.source)};continue}if(o.type==="diverging"&&typeof o.start=="string"&&typeof o.end=="string"){n[t]={...o,start:ie(o.start),end:ie(o.end),...typeof o.neutral=="string"?{neutral:ie(o.neutral)}:{}};continue}n[t]={...o}}return n}function ot(e){const n=W(e.seedColor);if(!n)return;const t=ye(n,e);return(o,i)=>{const a=ue(o,t,e.anchors)??t.primary,u=e.chroma.actionBackground,d=ae(a,e.lightness[i],u.min,u.max),m={l:d.l>.5?0:1,c:0,h:0};return Math.abs(mt(m,d))}}function Yt(e,n,t){if(n?.background)return n.background;const o=X(e.canvas,"color");if(o!==void 0){const i=Se.canvas.color?.find(([a])=>a==="background");if(i)return{source:o,lightness:i[1]}}return t.background}function st(e,n){const t=W(e.seedColor);if(!t||!n)return;const o=ye(t,e),i=ue(n.source,o,e.anchors)??o.primary,a=e.chroma.background,u=ae(i,Oe(e.lightness,e.tones,n.lightness),a.min,a.max);return(d,m)=>{const A=ue(d,o,e.anchors)??o.primary,k=e.chroma.actionBackground,y=ae(A,e.lightness[m],k.min,k.max);return gt(y,u)}}function qt(e){const n=le.get(e);if(n)return new Set(n);const t=pe(e);if(t)return t;const o=new Set,i=Ke(e.roles,e.lightness,e.semanticMappings,{tones:e.tones,actionSurfaceContrast:ot(e),actionSurfaceSeparation:st(e,e.semanticMappings.background)});for(const[a,u]of Object.entries(i)){const d=e.semanticMappings[a];(d.source!==u.source||d.lightness!==u.lightness)&&o.add(a)}return o}function de(e,n){const t={...e.roles,...n.roles},o=Kt(e.contexts,n.contexts),i=zt(e.lightness,n.lightness),a=jt(e.tones,n.tones),u=Gt(Qe(e.anchors,n.anchors)),d=typeof n.seedColor=="string"?re(n.seedColor):e.seedColor,m=n.semanticMappings,A={...e.angles,...n.angles},k={...e.semanticHues,...n.semanticHues},y={...e.variantChroma,...n.variantChroma},T=Wt({...e.intents,...n.intents}),_=n.chroma,z=ne(e.chroma,_),H=Vt(ne(e.dataPalette,n.dataPalette)),s=Jt(nt(e.dataRamps,n.dataRamps)),r=qt(e),c=new Set(r),l=pe(n),p={};for(const x of r)p[x]=e.semanticMappings[x];for(const[x,O]of Object.entries(m??{}))O!==void 0&&(l===void 0||l.has(x)?(c.add(x),p[x]=O):(c.delete(x),delete p[x]));const g=ne(e.semanticMappings,p),f={angles:A,anchors:u,chroma:z,intents:T,lightness:i,tones:a,seedColor:d,semanticHues:k,variantChroma:y},h=ot(f),$=st(f,Yt(t,p,g)),b=Ke(t,i,g,{explicitMappings:p,tones:a,actionSurfaceContrast:h,actionSurfaceSeparation:$}),R={};for(const[x,O]of Object.entries(b))c.has(x)||(R[x]=O);const C={};for(const x of Lt)!c.has(x)&&R[x]===void 0&&(C[x]={source:g.text.source,lightness:g.text.lightness},_?.text!==void 0&&_[x]===void 0&&(z[x]={...z.text}));const w=ne(ne(ne(e.semanticMappings,C),R),p),S={...e,seedColor:d,fontBody:n.fontBody||e.fontBody||Ve,fontHeadings:n.fontHeadings??e.fontHeadings,fontBrand:n.fontBrand??e.fontBrand,fontMenu:n.fontMenu??e.fontMenu,fontMonospace:n.fontMonospace||e.fontMonospace||Je,fontWeightBody:String(n.fontWeightBody??e.fontWeightBody),fontWeightHeadings:String(n.fontWeightHeadings??e.fontWeightHeadings),fontWeightBrand:String(n.fontWeightBrand??e.fontWeightBrand),fontWeightMenu:String(n.fontWeightMenu??e.fontWeightMenu),fontWeightMonospace:String(n.fontWeightMonospace??e.fontWeightMonospace),stylesheets:n.stylesheets??[...e.stylesheets],rootFontSize:n.rootFontSize??e.rootFontSize,typeRatio:n.typeRatio??e.typeRatio,spaceRatio:n.spaceRatio??e.spaceRatio,borderRadius:n.borderRadius??e.borderRadius,viewportMin:n.viewportMin??e.viewportMin,viewportMax:n.viewportMax??e.viewportMax,angles:A,semanticHues:k,variantChroma:y,intents:T,lightness:i,tones:a,chroma:z,semanticMappings:w,explicitMappingTokens:Xe(c),anchors:u,roles:t,contexts:o,dataPalette:H,dataRamps:s};return n.pageBackgroundImage!==void 0&&(S.pageBackgroundImage=n.pageBackgroundImage),n.pageBackgroundImageOpacity!==void 0&&(S.pageBackgroundImageOpacity=n.pageBackgroundImageOpacity),n.boxBackgroundImage!==void 0&&(S.boxBackgroundImage=n.boxBackgroundImage),n.boxBackgroundImageOpacity!==void 0&&(S.boxBackgroundImageOpacity=n.boxBackgroundImageOpacity),n.vellumOpacity!==void 0&&(S.vellumOpacity=n.vellumOpacity),n.vellumBackgroundImage!==void 0&&(S.vellumBackgroundImage=n.vellumBackgroundImage),n.vellumBackgroundImageOpacity!==void 0&&(S.vellumBackgroundImageOpacity=n.vellumBackgroundImageOpacity),le.set(S,new Set(c)),S}const rt=new WeakMap;function it(e,n){const t=e.contexts&&Object.prototype.hasOwnProperty.call(e.contexts,n)?e.contexts[n]:void 0;if(!t)return null;let o=rt.get(e);const i=o?.get(n);if(i)return i;const a={};for(const d of se){const m=t[d];m!==void 0&&(a[d]=m)}const u=de(e,{lightness:t.lightness,tones:t.tones,roles:a,semanticMappings:t.semanticMappings});return o||(o=new Map,rt.set(e,o)),o.set(n,u),u}function ne(e,n){if(!n)return{...e};const t={...e};for(const o of Object.keys(n)){const i=n[o];i!==void 0&&(t[o]=i)}return t}function Be(e){let n;try{n=Ze(e)}catch{return{error:"Failed to decode Base64 string."}}let t;try{t=JSON.parse(n)}catch{return{error:"Decoded string is not valid JSON."}}return typeof t!="object"||t===null||Array.isArray(t)?{error:"Theme must be a JSON object."}:{value:t}}function fn(e){const n=Be(e);return n.error!==void 0?{valid:!1,errors:[n.error],warnings:[]}:_e(n.value)}function _e(e,n=Re){const t=[],o=[];"seedColor"in e&&(typeof e.seedColor!="string"?t.push("seedColor must be a string."):W(e.seedColor)||t.push(`seedColor is not a valid CSS color: "${e.seedColor}". Accepted forms: ${oe}.`));for(const s of["fontBody","fontHeadings","fontBrand","fontMenu","fontMonospace"])s in e&&typeof e[s]!="string"&&t.push(`${s} must be a string.`);const i=["normal","bold","lighter","bolder"],a=["inherit","initial","unset","revert","revert-layer"];for(const s of["fontWeightBody","fontWeightHeadings","fontWeightBrand","fontWeightMenu","fontWeightMonospace"])if(s in e){const r=e[s];if(typeof r=="number")(r<1||r>1e3)&&t.push(`${s} numeric value must be 1\u20131000 (got ${r}).`);else if(typeof r=="string"){const c=i.includes(r)||a.includes(r);if(/^\d+$/.test(r)){const p=Number(r);(p<1||p>1e3)&&t.push(`${s} numeric value must be 1\u20131000 (got "${r}").`)}else c||o.push(`${s} = "${r}" is not a standard font-weight value.`)}else t.push(`${s} must be a string or number.`)}"stylesheets"in e&&(Array.isArray(e.stylesheets)?e.stylesheets.some(s=>typeof s!="string")&&t.push("Every entry in stylesheets must be a string."):t.push("stylesheets must be an array of strings."));const u=[["rootFontSize",1,100],["borderRadius",0,10],["viewportMin",100,1e4],["viewportMax",200,1e4]];for(const[s,r,c]of u)if(s in e)if(typeof e[s]!="number"||!isFinite(e[s]))t.push(`${s} must be a finite number.`);else{const l=e[s];r!==void 0&&l<r&&t.push(`${s} must be \u2265 ${r} (got ${l}).`),c!==void 0&&l>c&&o.push(`${s} = ${l} is unusually high (max ${c}).`)}for(const s of["typeRatio","spaceRatio"])if(s in e)if(typeof e[s]!="number"||!isFinite(e[s]))t.push(`${s} must be a finite number.`);else{const r=e[s];r<=1&&t.push(`${s} must be > 1 (got ${r}).`);const c=s==="typeRatio"?1.3:2;r>c&&o.push(`${s} = ${r} is very high (max ${c}); scales may be extreme.`)}if("viewportMin"in e&&"viewportMax"in e){const s=e.viewportMin,r=e.viewportMax;typeof s=="number"&&typeof r=="number"&&s>=r&&t.push(`viewportMin (${s}) must be less than viewportMax (${r}).`)}if("angles"in e)if(typeof e.angles!="object"||e.angles===null)t.push("angles must be an object.");else{const s=e.angles;for(const r of["analogous","complementary","splitComplementary","triadic"])if(r in s)if(typeof s[r]!="number"||!isFinite(s[r]))t.push(`angles.${r} must be a finite number.`);else{const c=s[r];(c<0||c>360)&&o.push(`angles.${r} = ${c} is outside 0\u2013360.`)}}if("semanticHues"in e)if(typeof e.semanticHues!="object"||e.semanticHues===null)t.push("semanticHues must be an object.");else{const s=e.semanticHues;for(const r of["danger","success","warning","info"])if(r in s)if(typeof s[r]!="number"||!isFinite(s[r]))t.push(`semanticHues.${r} must be a finite number.`);else{const c=s[r];(c<0||c>360)&&o.push(`semanticHues.${r} = ${c} is outside 0\u2013360.`)}}if("variantChroma"in e)if(typeof e.variantChroma!="object"||e.variantChroma===null)t.push("variantChroma must be an object.");else{const s=e.variantChroma;for(const r of It)if(r in s)if(typeof s[r]!="number"||!isFinite(s[r]))t.push(`variantChroma["${r}"] must be a finite number.`);else{const c=s[r];c<0&&t.push(`variantChroma["${r}"] must be \u2265 0 (got ${c}).`),c>Y&&o.push(`variantChroma["${r}"] = ${c} exceeds ${Y}.`)}}function d(s,r){if(typeof s!="object"||s===null||Array.isArray(s)){t.push(`${r} must be an object.`);return}const c=s;for(const l of Object.keys(c))(!M(l)||!te(l))&&t.push(`${r}.${l} is not a built-in lightness stop; expected one of: ${U.join(", ")}.`);for(const l of U)if(l in c)if(typeof c[l]!="number"||!isFinite(c[l]))t.push(`${r}.${l} must be a finite number.`);else{const p=c[l];(p<0||p>1)&&t.push(`${r}.${l} must be 0\u20131 (got ${p}).`)}}"lightness"in e&&d(e.lightness,"lightness");function m(s,r){const c=new Set;if(!L(s))return t.push(`${r} must be an object.`),c;for(const[l,p]of Object.entries(s)){if(!M(l)||!j.test(l)){t.push(`${r}.${l} must be a lowercase slug matching ${j.source}.`);continue}if(te(l)){t.push(`${r}.${l} conflicts with the built-in "${l}" lightness stop; choose a distinct custom tone name.`);continue}c.add(l),typeof p!="number"||!Number.isFinite(p)?t.push(`${r}.${l} must be a finite number.`):(p<0||p>1)&&t.push(`${r}.${l} must be 0\u20131 (got ${p}).`)}return c}const A=new Set(Object.keys(n.tones??{}));if("tones"in e)for(const s of m(e.tones,"tones"))A.add(s);if("chroma"in e)if(typeof e.chroma!="object"||e.chroma===null)t.push("chroma must be an object.");else{const s=e.chroma,r=_t(e,n);for(const c of K)if(c in s){const l=s[c];if(typeof l!="object"||l===null){t.push(`chroma.${c} must be { min, max }.`);continue}const p=l;for(const f of r.get(c)??[])f.chroma!==void 0&&typeof p.min=="number"&&typeof p.max=="number"&&(f.chroma<p.min-1e-9||f.chroma>p.max+1e-9)&&o.push(`chroma.${c} clamps the anchor-sourced token ${c} ("${f.source}", effective in ${f.where}) and moves it off its declared swatch. Remove the band if that is unintended \u2014 anchors otherwise keep their own chroma.`);const g=l;(typeof g.min!="number"||g.min<0)&&t.push(`chroma.${c}.min must be \u2265 0.`),(typeof g.max!="number"||g.max<0||g.max>Y)&&t.push(`chroma.${c}.max must be 0\u2013${Y}.`),typeof g.min=="number"&&typeof g.max=="number"&&g.min>g.max&&t.push(`chroma.${c}.min (${g.min}) must be \u2264 max (${g.max}).`)}}if("anchors"in e)if(typeof e.anchors!="object"||e.anchors===null||Array.isArray(e.anchors))t.push("anchors must be an object of named colors.");else for(const[s,r]of Object.entries(e.anchors))if(M(s)?j.test(s)||t.push(`anchors: "${s}" is not a valid anchor name; use a lowercase slug (letters, digits, hyphens).`):t.push(`anchors: "${s}" is a reserved JavaScript property name and cannot be an anchor name; rename it.`),Ae.includes(s)&&t.push(`anchors: "${s}" collides with a reserved color source name.`),typeof r=="string")W(r)||t.push(`anchors.${s} is not a valid CSS color: "${r}". Accepted forms: ${oe}.`);else if(typeof r=="object"&&r!==null&&!Array.isArray(r)){const c=r;typeof c.color!="string"&&t.push(`anchors.${s} must declare its base "color".`);for(const[l,p]of Object.entries(c))M(l)?l!=="color"&&!j.test(l)&&t.push(`anchors.${s}: "${l}" is not a valid slot name; use a lowercase slug.`):t.push(`anchors.${s}: "${l}" is a reserved JavaScript property name and cannot be a slot name; rename it.`),typeof p!="string"?t.push(`anchors.${s}.${l} must be a CSS color string.`):W(p)||t.push(`anchors.${s}.${l} is not a valid CSS color: "${p}". Accepted forms: ${oe}.`)}else t.push(`anchors.${s} must be a color string or a { color, \u2026slots } object.`);const k=new Map;if("anchors"in e&&typeof e.anchors=="object"&&e.anchors!==null&&!Array.isArray(e.anchors))for(const[s,r]of Object.entries(e.anchors))k.set(s,r);function y(s,r){const c=ke(s);if(!c){t.push(`${r} "${s}" is not valid anchor syntax; use anchor:<name> or anchor:<name>.<slot>.`);return}if(!k.has(c.name)){const l=[...k.keys()];t.push(`${r} references undeclared anchor "${c.name}". Declared anchors: ${l.length>0?l.join(", "):"(none)"}.`);return}if(c.slot!==void 0){const l=k.get(c.name);if(typeof(typeof l=="object"&&l!==null&&!Array.isArray(l)?l[c.slot]:void 0)!="string"){const g=typeof l=="object"&&l!==null?Object.keys(l).filter(f=>f!=="color"):[];t.push(`${r} references unknown slot "${c.slot}" on anchor "${c.name}". Declared slots: ${g.length>0?g.join(", "):"(none)"}.`)}}}function T(s,r){if(s.startsWith("anchor:")){y(s,r);return}Ae.includes(s)||t.push(`${r} must be one of: ${Ae.join(", ")}, or a declared anchor as anchor:<name> / anchor:<name>.<slot>.`)}if("intents"in e)if(typeof e.intents!="object"||e.intents===null||Array.isArray(e.intents))t.push("intents must be an object.");else for(const[s,r]of Object.entries(e.intents)){const c=`intents.${s}`;if(!ee.includes(s)){t.push(`${c} is not a status family; expected one of: ${ee.join(", ")}.`);continue}if(typeof r!="string"){t.push(`${c} must be a string (a CSS color or an anchor: reference).`);continue}if(r.startsWith("anchor:")){y(r,c);continue}W(r)||t.push(`${c} "${r}" is not a supported color form or anchor: reference. Accepted forms: ${oe}, or anchor:<name> / anchor:<name>.<slot>. An override retunes a family with a declared color; it never points one family at another \u2014 retune, never reassign.`)}function _(s,r){if(s.startsWith("anchor:")){y(s,r);return}W(s)||t.push(`${r} is not a valid CSS color: "${s}". Accepted forms: ${oe}, or a declared anchor as anchor:<name> / anchor:<name>.<slot>.`)}if("dataPalette"in e)if(typeof e.dataPalette!="object"||e.dataPalette===null||Array.isArray(e.dataPalette))t.push("dataPalette must be an object with series1\u2013series8 color values.");else{const s=e.dataPalette;for(const[r,c]of Object.entries(s)){if(!fe.includes(r)){t.push(`dataPalette.${r} is not a series slot; expected one of: ${fe.join(", ")}.`);continue}typeof c!="string"?t.push(`dataPalette.${r} must be a CSS color or anchor reference string.`):_(c,`dataPalette.${r}`)}}if("dataRamps"in e)if(typeof e.dataRamps!="object"||e.dataRamps===null||Array.isArray(e.dataRamps))t.push("dataRamps must be an object of named ramp declarations.");else for(const[s,r]of Object.entries(e.dataRamps)){if(M(s)?j.test(s)||t.push(`dataRamps: "${s}" is not a valid ramp name; use a lowercase slug (letters, digits, hyphens).`):t.push(`dataRamps: "${s}" is a reserved JavaScript property name and cannot be a ramp name; rename it.`),typeof r!="object"||r===null||Array.isArray(r)){t.push(`dataRamps.${s} must be a sequential or diverging ramp object.`);continue}const c=r,l=c.steps??Mt;if((typeof l!="number"||!Number.isInteger(l)||l<xe||l>$e)&&t.push(`dataRamps.${s}.steps must be an integer from ${xe} through ${$e}.`),c.type==="sequential"){typeof c.source!="string"?t.push(`dataRamps.${s}.source must be a CSS color or anchor reference string.`):_(c.source,`dataRamps.${s}.source`);const p=c.lightnessStart??.95,g=c.lightnessEnd??.25;for(const[f,h]of[["lightnessStart",p],["lightnessEnd",g]])(typeof h!="number"||!Number.isFinite(h)||h<0||h>1)&&t.push(`dataRamps.${s}.${f} must be a finite number from 0 through 1.`);typeof p=="number"&&typeof g=="number"&&p<=g?t.push(`dataRamps.${s}.lightnessStart must be greater than lightnessEnd.`):typeof p=="number"&&Number.isFinite(p)&&typeof g=="number"&&Number.isFinite(g)&&typeof l=="number"&&Number.isInteger(l)&&l>=xe&&l<=$e&&(p-g)/(l-1)<=We&&t.push(`dataRamps.${s} lightness bounds must leave more than ${We} lightness between serialized stops.`);continue}if(c.type==="diverging"){typeof l=="number"&&Number.isInteger(l)&&l%2===0&&t.push(`dataRamps.${s}.steps must be odd so the neutral is the exact midpoint.`);for(const p of["start","end"])typeof c[p]!="string"?t.push(`dataRamps.${s}.${p} must be a CSS color or anchor reference string.`):_(c[p],`dataRamps.${s}.${p}`);"neutral"in c&&(typeof c.neutral!="string"?t.push(`dataRamps.${s}.neutral must be a CSS color or anchor reference string.`):_(c.neutral,`dataRamps.${s}.neutral`));continue}t.push(`dataRamps.${s}.type must be "sequential" or "diverging".`)}if("dataPalette"in e&&t.length===0){const s=de(Re,e),r={};let c=!0;for(const l of fe){const p=Ot(s.dataPalette[l],s.anchors);if(!p){c=!1;break}r[l]=p}if(c)for(const l of St(r))o.push(At(l))}function z(s,r){if(typeof s!="object"||s===null||Array.isArray(s)){t.push(`${r} must be an object.`);return}const c=s;for(const[l,p]of Object.entries(c)){const g=`${r}.${l}`;if(!se.includes(l)){t.push(`${g} is not a role; expected one of: ${se.join(", ")}. (The status family is reserved and is not a role.)`);continue}const f=l,h=Se[f];if(typeof p=="string"){T(p,g);continue}if(typeof p!="object"||p===null||Array.isArray(p)){t.push(`${g} must be a color source or a { color, \u2026slots } object.`);continue}const $=p;typeof $.color!="string"&&t.push(`${g} must declare its base "color".`);for(const[b,R]of Object.entries($)){if(!Object.prototype.hasOwnProperty.call(h,b)||!M(b)){const C=Object.keys(h).filter(w=>w!=="color");t.push(`${g}.${b} is not a slot of the ${f} role. Declared slots: ${C.length>0?C.join(", "):"(none)"}.`);continue}typeof R!="string"?t.push(`${g}.${b} must be a color source string.`):T(R,`${g}.${b}`)}}}if("roles"in e&&z(e.roles,"roles"),"contexts"in e)if(typeof e.contexts!="object"||e.contexts===null||Array.isArray(e.contexts))t.push("contexts must be an object.");else for(const[s,r]of Object.entries(e.contexts)){if(!M(s)||!j.test(s)){t.push(`contexts.${s} must be a lowercase slug matching ${j.source}.`);continue}if(typeof r!="object"||r===null||Array.isArray(r)){z(r,`contexts.${s}`);continue}const c=r,l=Object.fromEntries(Object.entries(c).filter(([g])=>g!=="lightness"&&g!=="tones"&&g!=="semanticMappings"));z(l,`contexts.${s}`),"lightness"in c&&d(c.lightness,`contexts.${s}.lightness`);const p=new Set(A);if("tones"in c)for(const g of m(c.tones,`contexts.${s}.tones`))p.add(g);"semanticMappings"in c&&H(c.semanticMappings,`contexts.${s}.semanticMappings`,p)}function H(s,r,c){if(typeof s!="object"||s===null||Array.isArray(s)){t.push(`${r} must be an object.`);return}const l=s;for(const p of Object.keys(l))K.includes(p)||t.push(`${r}.${p} is not a semantic token; expected one of: ${K.join(", ")}.`);for(const p of K)if(p in l){const g=l[p];if(typeof g!="object"||g===null){t.push(`${r}.${p} must be { source, lightness }.`);continue}const f=g;if(typeof f.source!="string"?t.push(`${r}.${p}.source must be a string.`):T(f.source,`${r}.${p}.source`),typeof f.lightness!="string")t.push(`${r}.${p}.lightness must be one of: ${U.join(", ")}, or a declared tone:<name>.`);else if(!te(f.lightness)){const h=Me(f.lightness);if(h===null)t.push(`${r}.${p}.lightness must be one of: ${U.join(", ")}, or a declared tone:<name>.`);else if(!c.has(h)){const $=[...c].sort();t.push(`${r}.${p}.lightness references undeclared tone "${h}". Declared tones: ${$.length>0?$.join(", "):"(none)"}.`)}}}}if("semanticMappings"in e&&H(e.semanticMappings,"semanticMappings",A),"explicitMappingTokens"in e)if(!Array.isArray(e.explicitMappingTokens))t.push("explicitMappingTokens must be an array of semantic token names.");else{const s=new Set,r=L(e.semanticMappings)?e.semanticMappings:void 0;for(const c of e.explicitMappingTokens){if(typeof c!="string"||!K.includes(c)){t.push(`explicitMappingTokens entries must be one of: ${K.join(", ")}.`);continue}s.has(c)&&t.push(`explicitMappingTokens contains duplicate token "${c}".`),s.add(c),(!r||!Object.prototype.hasOwnProperty.call(r,c))&&t.push(`explicitMappingTokens names "${c}" without a semanticMappings entry.`)}}for(const s of["pageBackgroundImage","boxBackgroundImage","vellumBackgroundImage"])s in e&&typeof e[s]!="string"&&t.push(`${s} must be a string.`);for(const s of["pageBackgroundImageOpacity","boxBackgroundImageOpacity","vellumOpacity","vellumBackgroundImageOpacity"])if(s in e)if(typeof e[s]!="number"||!isFinite(e[s]))t.push(`${s} must be a finite number.`);else{const r=e[s];(r<0||r>1)&&t.push(`${s} must be 0\u20131 (got ${r}).`)}return o.push(...Xt(e,n)),{valid:t.length===0,errors:t,warnings:o}}const B=.045;function Xt(e,n){try{return Zt(e,n)}catch{return[]}}function Zt(e,n){const t=de(n,e),o=ut(t),i=[...o],a=new Set(o);for(const u of Object.keys(t.contexts)){const d=it(t,u);if(d)for(const m of ut(d))a.has(m)||i.push(`contexts.${u}: ${m}`)}return i}function Qt(e){const n=yt(he(e)),t=$t(n);return ht({r:ge(t.r),g:ge(t.g),b:ge(t.b)})}function Z(e,n){return Math.hypot(e.L-n.L,e.a-n.a,e.b-n.b)}function q(e){return Qt(W(ce(he(e))))}function at(e){return(Math.floor(e*1e4)/1e4).toFixed(4)}const Q=2,ct=1e-4;function ut(e){const n=W(e.seedColor);if(!n)return[];const t=ye(n,e),o=e.semanticMappings.actionBackground,i=e.chroma.actionBackground,a=Oe(e.lightness,e.tones,o.lightness),u=(f,h,$,b)=>he(ae(f,h,$,b)),d=ee.map(f=>({name:f,base:t[f]})),m=[];if(ee.includes(o.source))m.push(`actionBackground is sourced from the "${o.source}" status family: ordinary and ${o.source}-intent action surfaces render identically (their labels may still differ). Remap the action to a non-status source \u2014 retuning "${o.source}" via intents moves both colors together.`);else{const f=ue(o.source,t,e.anchors);f&&d.push({name:"action",base:f})}const A=Fe(d.map(({name:f,base:h})=>[f,ce(u(h,a,i.min,i.max))]),B,["normal"]);if(A.length===0)return m;const k=new Map,y=(f,h)=>{const $=`${f}:${h}`;let b=k.get($);if(!b){b=[];for(let R=0;R<360;R+=Q)b.push(q({l:f,c:h,h:R}));k.set($,b)}return b},T=B-.002,_=(f,h,$,b)=>{const R=Math.hypot(f.a,f.b),C=Math.atan2(f.b,f.a)*180/Math.PI+180;let w=0;for(const S of $===b?[b]:[$,b]){if(S+R<B-1e-4)continue;let x=C,O=Z(q({l:h,c:S,h:C}),f);if(O>=B)return O;const D=y(h,S);for(let E=0;E<D.length;E+=1){const v=Z(D[E],f);if(v>=B)return v;v>O&&(O=v,x=E*Q)}let P=x;for(let E=x-Q;E<=x+Q;E+=.1){const v=Z(q({l:h,c:S,h:E}),f);if(v>=B)return v;v>O&&(O=v,P=E)}if(O>=T)for(let E=P-.1;E<=P+.1;E+=.001){const v=Z(q({l:h,c:S,h:E}),f);if(v>=B)return v;v>O&&(O=v)}O>w&&(w=O)}return w},z=(f,h,$)=>{const b=h===$?[$]:[h,$];let R=0;for(const C of b)for(const w of b){if(C+w<B-1e-4)continue;const S=y(f,C),x=y(f,w);let O=0,D=0,P=-1;for(let N=0;N<S.length;N+=1)for(let G=0;G<x.length;G+=1){const V=Z(S[N],x[G]);if(V>=B)return V;V>P&&(P=V,O=N*Q,D=G*Q)}const E=(N,G,V,Le)=>{const Ie=[];for(let J=G-V;J<=G+V;J+=Le)Ie.push({h:J,lab:q({l:f,c:w,h:J})});let me=-1,Ne=N,He=G;for(let J=N-V;J<=N+V;J+=Le){const pt=q({l:f,c:C,h:J});for(const Pe of Ie){const De=Z(pt,Pe.lab);De>me&&(me=De,Ne=J,He=Pe.h)}}return{distance:me,hueA:Ne,hueB:He}},v=E(O,D,Q,.1);if(v.distance>=B)return v.distance;let I=Math.max(P,v.distance);if(I>=T){const N=E(v.hueA,v.hueB,.1,.001);if(N.distance>I&&(I=N.distance),I>=B)return I}I>R&&(R=I)}return R},H=f=>ee.includes(f),s=(f,h,$,b,R)=>{const C=q(u(f.base,$,b,R)),w=q(u(h.base,$,b,R));if(Z(C,w)>=B)return{outcome:"direct"};const S=H(f.name)&&H(h.name),x=[f,h].filter(P=>H(P.name)),O=S?"one of them":`"${H(f.name)?f.name:h.name}"`;let D;for(const P of x){const E=_(P===f?w:C,$,b,R);if(E>=B)return{outcome:"retune",target:O};E>=B-ct&&(D=D??O)}if(S){const P=z($,b,R);if(P>=B)return{outcome:"retune",target:"both"};P>=B-ct&&(D=D??"both")}return D!==void 0?{outcome:"near",target:D}:{outcome:"no"}},r=f=>f.outcome==="direct"?4:f.outcome==="retune"?f.target==="both"?2:3:f.outcome==="near"?1:0,c=f=>[...f].sort().join("|"),l=new Set(Fe(d.map(({name:f,base:h})=>[f,ce(u(h,a,0,Y))]),B,["normal"]).map(f=>c(f.pair))),p=new Map(d.map(f=>[f.name,f])),g=new Map;for(const{pair:f,distance:h}of A){const $=p.get(f[0]),b=p.get(f[1]),R=H($.name)&&H(b.name),C=s($,b,a,i.min,i.max);if(C.outcome==="direct"||C.outcome==="retune"){const I=C.target??(R?"one of them":`"${H($.name)?$.name:b.name}"`);l.has(c(f))?m.push(`Status colors "${f[0]}" and "${f[1]}" are hard to distinguish under normal vision (distance ${at(h)} < ${B}); status meanings must stay distinguishable \u2014 retune ${I} via intents.`):m.push(`Status colors "${f[0]}" and "${f[1]}" are hard to distinguish as rendered (distance ${at(h)} < ${B}); the actionBackground chroma band ({ min: ${i.min}, max: ${i.max} }) pushes them together \u2014 widen the band, or retune ${I} via intents.`);continue}const w=s($,b,a,0,Y);let S={outcome:"no"};for(let I=1;I<=19&&S.outcome!=="direct";I+=1){const N=I*.05;if(Math.abs(N-a)<.001)continue;const G=s($,b,N,i.min,i.max);r(G)>r(S)&&(S=G)}let x={outcome:"no"};const O=w.outcome==="direct"||w.outcome==="retune",D=S.outcome==="direct"||S.outcome==="retune";if(!O&&!D)for(let I=1;I<=19&&x.outcome!=="direct";I+=1){const N=s($,b,I*.05,0,Y);r(N)>r(x)&&(x=N)}const P=en(w,S,x),E=`${C.outcome}|${P}`;let v=g.get(E);v||(v=[],g.set(E,v)),v.push(f)}for(const[f,h]of g){const $=f.indexOf("|"),b=f.slice(0,$),R=f.slice($+1),C=h.map(([x,O])=>`"${x}"/"${O}"`),w=C.length>1?`${C.slice(0,-1).join(", ")} and ${C[C.length-1]}`:C[0],S=b==="near"?`Status colors ${w} may not separate by retuning as rendered: at the action stop's lightness (${a}) with the actionBackground chroma band ({ min: ${i.min}, max: ${i.max} }), the closest reachable retune found comes within the audit's search margin of the ${B} threshold`:`Status colors ${w} cannot be separated as rendered: at the action stop's lightness (${a}) with the actionBackground chroma band ({ min: ${i.min}, max: ${i.max} }), no intent retuning can pull ${h.length>1?"these pairs":"the pair"} ${B} apart`;m.push(S+R)}return m}function en(e,n,t){if(e.outcome==="direct"&&n.outcome==="direct")return" \u2014 widen the chroma band or move the action lightness stop.";if(e.outcome==="direct")return n.outcome==="no"?"; no other action lightness stop can help while the band holds \u2014 widen the chroma band.":" \u2014 widen the chroma band.";if(n.outcome==="direct")return e.outcome==="no"?"; no wider chroma band can help at this lightness \u2014 move the action lightness stop.":" \u2014 move the action lightness stop.";if(e.outcome==="retune"&&n.outcome==="retune")return` \u2014 widen the chroma band or move the action lightness stop, then retune ${e.target} via intents.`;if(e.outcome==="retune")return n.outcome==="no"?`; no other action lightness stop can help while the band holds \u2014 widen the chroma band, then retune ${e.target} via intents.`:` \u2014 widen the chroma band, then retune ${e.target} via intents.`;if(n.outcome==="retune")return e.outcome==="no"?`; no wider chroma band can help at this lightness \u2014 move the action lightness stop, then retune ${n.target} via intents.`:` \u2014 move the action lightness stop, then retune ${n.target} via intents.`;const o=e.outcome==="no"&&n.outcome==="no"?"; neither a wider chroma band alone nor another stop alone can help":"; neither a wider chroma band alone nor another stop alone provably helps";return t.outcome==="direct"?`${o} \u2014 change the band and the stop together.`:t.outcome==="retune"?`${o} \u2014 change the band and the stop together, then retune ${t.target} via intents.`:"; no explored band or stop change provably separates this pair."}function ln(e,n){const t=Be(e),o=Be(n),i=t.error!==void 0?{valid:!1,errors:[t.error],warnings:[]}:_e(t.value),a=o.error!==void 0?{valid:!1,errors:[o.error],warnings:[]}:_e(o.value,qe),u=[...i.errors.map(m=>`light: ${m}`),...a.errors.map(m=>`dark: ${m}`)],d=[...i.warnings.map(m=>`light: ${m}`),...a.warnings.map(m=>`dark: ${m}`)];if(i.valid&&a.valid){const m=new Set(Object.keys(t.value?.contexts??{})),A=new Set(Object.keys(o.value?.contexts??{})),k=[...A].filter(T=>!m.has(T)).sort(),y=[...m].filter(T=>!A.has(T)).sort();(k.length>0||y.length>0)&&u.push(`contexts must declare the same names in both schemes. Missing from light: ${k.join(", ")||"(none)"}. Missing from dark: ${y.join(", ")||"(none)"}.`)}return{valid:u.length===0,errors:u,warnings:d}}const tn=["anchors","angles","contexts","dataPalette","dataRamps","intents","roles","chroma","lightness","tones","semanticHues","semanticMappings","variantChroma"];function nn(e,n){const t={};for(const[a,u]of Object.entries(e))M(a)&&(t[a]=u);for(const[a,u]of Object.entries(n))u!==void 0&&M(a)&&(t[a]=u);for(const a of tn){const u=e[a],d=n[a];if(u&&typeof u=="object"&&!Array.isArray(u)&&d&&typeof d=="object"&&!Array.isArray(d)){if(a==="anchors"){t[a]=Qe(u,d);continue}if(a==="contexts"){t[a]=Ut(u,d);continue}if(a==="dataRamps"){t[a]=nt(u,d);continue}const m={};for(const[A,k]of Object.entries(u))M(A)&&(m[A]=k);for(const[A,k]of Object.entries(d))k!==void 0&&M(A)&&(m[A]=k);t[a]=m}}const o=pe(e),i=pe(n);if(o!==void 0||i!==void 0){const a=o??new Set(Object.keys(e.semanticMappings??{}).filter(u=>K.includes(u)));for(const u of Object.keys(n.semanticMappings??{}))i===void 0||i.has(u)?a.add(u):a.delete(u);t.explicitMappingTokens=Xe(a)}return t}function pn(...e){let n={};for(const t of e){if(!t)continue;const o=Dt(t);o&&(n=nn(n,o))}return Ee(n)}function ft(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")}const lt={borderRadius:.1,fontBody:'"Noto Sans", sans-serif',fontWeightBody:"normal",fontHeadings:'"Inika", serif',fontWeightHeadings:"normal",fontBrand:'"Inika", serif',fontWeightBrand:"normal",fontMonospace:'"JetBrains Mono", monospace',fontWeightMonospace:"normal",seedColor:"oklch(.07 0.15 216)"};function dn(e){return Ee({...lt,pageBackgroundImage:`url("${ft(e)}")`,pageBackgroundImageOpacity:.5})}function mn(e){return Ee({...lt,pageBackgroundImage:`url("${ft(e)}")`,pageBackgroundImageOpacity:.55})}export{j as ANCHOR_SLUG_PATTERN,Ae as COLOR_SOURCES,Ve as DEFAULT_BODY_FONT_FAMILY,Ht as DEFAULT_DARK_LIGHTNESS,qe as DEFAULT_DARK_THEME,Nt as DEFAULT_LIGHT_LIGHTNESS,Re as DEFAULT_LIGHT_THEME,Je as DEFAULT_MONOSPACE_FONT_FAMILY,Te as DEFAULT_SEMANTIC_MAPPINGS,U as LIGHTNESS_KEYS,tn as NESTED_THEME_KEYS,se as ROLE_NAMES,Rt as ROLE_PAIRED_INK,Se as ROLE_TOKEN_PLAN,K as SEMANTIC_COLOR_NAMES,ee as STATUS_COLOR_SOURCES,Ue as TOKEN_PAIRINGS,It as VARIANT_COLOR_SOURCES,mn as buildTaprootDarkTheme,dn as buildTaprootLightTheme,Ke as compileRoles,Ee as encodeTheme,qt as explicitMappingTokens,te as isLightnessKey,L as isObjectRecord,cn as isSemanticColorName,pn as layerThemes,nn as mergePartials,de as mergeTheme,ke as parseAnchorSource,Dt as parseTheme,je as resolveAnchorColor,it as resolveContextTheme,Ot as resolveDataColorSource,Oe as resolveLightnessReference,un as semanticToCSS,Me as toneReferenceName,fn as validateTheme,ln as validateThemePair};
1
+ import{UNSAFE_KEYS as yt,isSafeKey as M}from"./unsafe-keys.js";import{ACCEPTED_COLOR_FORMS as oe,apcaContrast as se,clampChannel as be,deltaEOK as bt,deriveSemantic as re,gamutMapToSRGB as $e,linearRgbToOklab as $t,oklchToSRGB as kt,parseCssColor as W,parseOklch as xt,serializeOklch as fe,srgbToLinearRGB as St}from"./color-engine.js";import{computeVariants as le,parseAnchorSource as At,resolveAnchorColor as Mt,resolveMappingSource as ie}from"./variant-engine.js";import{auditColorDistances as Fe,auditDataPalette as Ot,describePaletteCollision as Tt,DATA_SERIES_KEYS as pe,DEFAULT_DATA_PALETTE as ke,DEFAULT_DATA_RAMP_STEPS as Ct,MAX_DATA_RAMP_STEPS as xe,MIN_DATA_RAMP_LIGHTNESS_STEP as We,MIN_DATA_RAMP_STEPS as Se}from"./data-colors.js";const K=/^[a-z][a-z0-9-]*$/;function Ae(e){return At(e)}function je(e,n){return Mt(e,n)}function Rt(e,n){const t=Ae(e);if(t){const o=je(n,t);return o&&W(o)?o:null}return W(e)?e:null}const ae=["canvas","ink","accent","action","structure"],de={canvas:{color:[["background","surface"],["layer1","raised1"],["layer2","raised2"],["layer3","raised3"],["layer4","raised4"]]},ink:{color:[["text","text"],["typeOverline","text"],["typeLabel","text"],["typeLead","text"],["typeCaption","text"],["inputSelection","text"]],heading:[["headings","muted"],["headingsHover","ink"]]},accent:{color:[["linkHoverBg","raised2"],["inputSelectionBg","raised2"],["inputCaret","ink"]],text:[["link","accent"]],hover:[["linkHover","text"]]},action:{color:[["actionBackground","muted"]],ink:[["actionText","surface"]]},structure:{color:[["border","border"],["shadow","shadow"]]}},vt=new Set(["action.color"]),Et=new Set(["action.ink"]),wt={canvas:"background",ink:"text",accent:"link",action:"actionBackground",structure:"border"},Ke={"action.ink":{role:"canvas",slot:"color"}},Bt=.45,_t=.045;function ze(e,n,t){const o=Ge.actionText,i=[...U].sort((S,A)=>e[S]-e[A]||U.indexOf(S)-U.indexOf(A)),a=n?i.filter(S=>n(S)>=o.targetLc):i,u=t?a.filter(S=>t(S)>=_t):a,d=u.length>0?u:a,m=d.length>0?d:i;let x,b=1/0;for(const S of m){const A=Math.abs(e[S]-Bt);A<b&&(b=A,x=S)}return x??"muted"}function Lt(e){const n={l:e,c:0,h:0};return Math.abs(se({l:0,c:0,h:0},n))>=Math.abs(se({l:1,c:0,h:0},n))?"dark":"light"}function It(e,n,t,o){const i=Te(n,t,e),a=(o??Lt)(i)==="dark";let u=U[0];for(const d of U)(a?n[d]<n[u]:n[d]>n[u])&&(u=d);return u}const Nt={"accent.hover":"text"};function Pt(e,n){const t=new Map;try{const o=he(n,e),i=(a,u,d,m)=>{const x=Ae(u),b=x?je(m,x):null,S=b===null?null:W(b),A=t.get(a)??[];A.some(D=>D.source===u&&D.chroma===S?.c)||(A.push({source:u,where:d,chroma:S?.c}),t.set(a,A))};for(const[a,u]of Object.entries(o.semanticMappings))u.source.startsWith("anchor:")&&i(a,u.source,"the root table",o.anchors);for(const a of Object.keys(o.contexts)){const u=ft(o,a);if(u)for(const[d,m]of Object.entries(u.semanticMappings))m.source.startsWith("anchor:")&&i(d,m.source,`contexts.${a}`,u.anchors)}}catch{return new Map}return t}function Y(e,n){if(e===void 0)return;if(typeof e=="string")return n==="color"?e:void 0;const t=e[n];return typeof t=="string"?t:void 0}function Ue(e,n,t,o={}){const i={};for(const a of ae){const u=e[a];if(u!==void 0)for(const[d,m]of Object.entries(de[a])){const x=Ke[`${a}.${d}`];let b=Y(u,d),S=!1;if(b===void 0){x&&(b=Y(e[x.role],x.slot),b??=t[wt[x.role]]?.source,S=b!==void 0);const A=Nt[`${a}.${d}`];A!==void 0&&(b??=Y(u,A)),b??=Y(u,"color")}if(b!==void 0)for(const[A,D]of m){let F=D;if(vt.has(`${a}.${d}`))F=ze(n,o.actionSurfaceContrast?L=>o.actionSurfaceContrast(b,L):void 0,o.actionSurfaceSeparation?L=>o.actionSurfaceSeparation(b,L):void 0);else if(x&&(S||Et.has(`${a}.${d}`))){const L=Ge[A],s=L?o.explicitMappings?.[L.bg]:void 0,r=s?.lightness??ze(n,o.actionSurfaceContrast?f=>o.actionSurfaceContrast(Y(u,"color"),f):void 0,o.actionSurfaceSeparation?f=>o.actionSurfaceSeparation(Y(u,"color"),f):void 0),c=s?.source??Y(u,"color");F=It(r,n,o.tones??{},o.actionSurfacePole&&c!==void 0?f=>o.actionSurfacePole(c,f):void 0)}i[A]={source:b,lightness:F}}}}return i}function dn(e){const n={};for(const t of Object.keys(Ke)){const o=t.indexOf("."),i=t.slice(0,o),a=t.slice(o+1),u=e[i];if(u===void 0)continue;const d=Y(u,a)!==void 0?"declared":"derived";for(const[m]of de[i][a]??[])n[m]=d}return n}const Ge={text:{bg:"background",targetLc:75},typeOverline:{bg:"background",targetLc:90},typeLabel:{bg:"background",targetLc:75},typeLead:{bg:"background",targetLc:75},typeCaption:{bg:"background",targetLc:90},dangerText:{bg:"background",targetLc:75},headings:{bg:"background",targetLc:60},headingsHover:{bg:"background",targetLc:60},link:{bg:"background",targetLc:75},linkHover:{bg:"linkHoverBg",targetLc:75},actionText:{bg:"actionBackground",targetLc:75},inputCaret:{bg:"layer2",targetLc:60},inputSelection:{bg:"inputSelectionBg",targetLc:60}},z=["background","layer1","layer2","layer3","layer4","actionBackground","actionText","border","shadow","text","typeOverline","typeLabel","typeLead","typeCaption","dangerText","headings","headingsHover","link","linkHover","linkHoverBg","inputCaret","inputSelection","inputSelectionBg"];function mn(e){return typeof e=="string"&&z.includes(e)}const Ht=["typeOverline","typeLabel","typeLead","typeCaption"],Me=["primary","analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning","info"],ee=["danger","success","warning","info"],Dt=["analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning","info"],U=["surface","raised1","raised2","raised3","raised4","accent","muted","text","border","ink","shadow"],Ve="tone:";function Oe(e){if(typeof e!="string"||!e.startsWith(Ve))return null;const n=e.slice(Ve.length);return M(n)&&K.test(n)?n:null}function te(e){return typeof e!="string"?!1:U.includes(e)}function Te(e,n,t){if(te(t))return e[t];const o=Oe(t);return o===null?e.surface:n?.[o]??e.surface}const Ft={surface:.99,raised1:.97,raised2:.9,raised3:.8,raised4:.72,accent:.5,muted:.45,text:.35,border:.3,ink:.25,shadow:.2},Wt={surface:.15,raised1:.2,raised2:.3,raised3:.4,raised4:.36,accent:.6,muted:.75,text:.85,border:.7,ink:.95,shadow:.6},Je={background:{source:"primary",lightness:"surface"},layer1:{source:"primary",lightness:"raised1"},layer2:{source:"primary",lightness:"raised2"},layer3:{source:"primary",lightness:"raised3"},layer4:{source:"primary",lightness:"raised4"},actionBackground:{source:"primary",lightness:"muted"},actionText:{source:"primary",lightness:"ink"},border:{source:"primary",lightness:"border"},shadow:{source:"primary",lightness:"shadow"},text:{source:"primary",lightness:"text"},typeOverline:{source:"primary",lightness:"text"},typeLabel:{source:"primary",lightness:"text"},typeLead:{source:"primary",lightness:"text"},typeCaption:{source:"primary",lightness:"text"},dangerText:{source:"danger",lightness:"text"},headings:{source:"primary",lightness:"muted"},headingsHover:{source:"primary",lightness:"text"},link:{source:"complementary",lightness:"accent"},linkHover:{source:"complementary",lightness:"text"},linkHoverBg:{source:"triadic-left",lightness:"raised2"},inputCaret:{source:"triadic-right",lightness:"ink"},inputSelection:{source:"complementary",lightness:"text"},inputSelectionBg:{source:"triadic-left",lightness:"raised2"}},jt={light:"muted",dark:"raised3"};function Ye(e){return{...Je,actionBackground:{source:"primary",lightness:jt[e]}}}const q=.4;function Ce(){const e={};for(const n of z)e[n]={min:0,max:q};return e}const qe="system-ui, sans-serif",Xe="monospace",Ze={seedColor:"oklch(0.7 0.125 216)",fontBody:qe,fontHeadings:"",fontBrand:"",fontMenu:"",fontMonospace:Xe,fontWeightBody:"normal",fontWeightHeadings:"bold",fontWeightBrand:"bold",fontWeightMenu:"bold",fontWeightMonospace:"normal",stylesheets:[],rootFontSize:16,typeRatio:1.25,spaceRatio:1.618,borderRadius:.2,viewportMin:320,viewportMax:1200,angles:{analogous:30,complementary:180,splitComplementary:30,triadic:120},semanticHues:{danger:27,success:150,warning:90,info:244},variantChroma:{},intents:{},tones:{},chroma:Ce(),semanticMappings:{...Je},explicitMappingTokens:[],anchors:{},roles:{},contexts:{},dataPalette:{...ke},dataRamps:{}},Re={...Ze,chroma:Ce(),semanticMappings:Ye("light"),anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...ke},dataRamps:{},lightness:{...Ft}},Qe={...Ze,chroma:Ce(),semanticMappings:Ye("dark"),anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...ke},dataRamps:{},lightness:{...Wt}},me=new WeakMap;me.set(Re,new Set),me.set(Qe,new Set);function Kt(e,n){return yt.has(e)?void 0:n}function ge(e){const n=e.explicitMappingTokens;if(!Array.isArray(n)||n.some(o=>typeof o!="string"||!z.includes(o)))return;const t=new Set(n);if(t.size===n.length&&!(t.size>0&&(!I(e.semanticMappings)||[...t].some(o=>!Object.prototype.hasOwnProperty.call(e.semanticMappings,o)))))return t}function et(e){return z.filter(n=>e.has(n))}function gn(e){return`--esp-color-${e.replace(/([A-Z])/g,"-$1").replace(/(\d)/g,"-$1").toLowerCase()}`}function zt(e){try{const n=tt(e),t=JSON.parse(n,Kt);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}const ve="\xEF\xBB\xBF";function Ut(e){if(/^[\u0000-\u007f]*$/.test(e))return btoa(e);const n=new TextEncoder().encode(e);let t=ve;for(const o of n)t+=String.fromCharCode(o);return btoa(t)}function tt(e){const n=atob(e);if(!n.startsWith(ve))return n;const t=Uint8Array.from(n.slice(ve.length),o=>o.charCodeAt(0));return new TextDecoder("utf-8",{fatal:!0}).decode(t)}function Ee(e){return Ut(JSON.stringify(e))}function Gt(e){const n={};for(const t of ee){const o=e[t];typeof o=="string"&&(n[t]=o.startsWith("anchor:")?o:ce(o))}return n}function ce(e){if(xt(e))return e;const n=W(e);return n?fe(n):e}function nt(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&(t[o]=i);if(!n)return t;for(const[o,i]of Object.entries(n)){if(i===void 0||!M(o))continue;const a=t[o];if(a!==void 0&&typeof i=="object"&&i!==null){const u={};if(typeof a=="string")u.color=a;else for(const[d,m]of Object.entries(a))M(d)&&(u[d]=m);for(const[d,m]of Object.entries(i))m!==void 0&&M(d)&&(u[d]=m);t[o]=u;continue}t[o]=i}return t}function we(e){const n={};if(!I(e))return n;for(const[t,o]of Object.entries(e))M(t)&&K.test(t)&&!te(t)&&typeof o=="number"&&Number.isFinite(o)&&o>=0&&o<=1&&(n[t]=o);return n}function Vt(e,n){return{...we(e),...we(n)}}function Jt(e,n){const t={...e};if(!I(n))return t;for(const o of U){const i=n[o];typeof i=="number"&&Number.isFinite(i)&&i>=0&&i<=1&&(t[o]=i)}return t}function ot(e){if(typeof e!="object"||e===null||Array.isArray(e))return null;const n=e,t={};for(const o of ae){const i=n[o];i!==void 0&&(t[o]=i)}if(typeof n.lightness=="object"&&n.lightness!==null&&!Array.isArray(n.lightness)){const o={};for(const i of U){const a=n.lightness[i];a!==void 0&&(o[i]=a)}t.lightness=o}if(n.tones!==void 0){const o=we(n.tones);Object.keys(o).length>0&&(t.tones=o)}if(typeof n.semanticMappings=="object"&&n.semanticMappings!==null&&!Array.isArray(n.semanticMappings)){const o={};for(const[i,a]of Object.entries(n.semanticMappings)){if(!M(i)||!z.includes(i)||typeof a!="object"||a===null||Array.isArray(a))continue;const{source:u,lightness:d}=a;typeof u=="string"&&(typeof d!="string"||!te(d)&&Oe(d)===null||(o[i]={source:u,lightness:d}))}Object.keys(o).length>0&&(t.semanticMappings=o)}return t}function Yt(e,n){const t={};for(const[o,i]of Object.entries(e)){if(!M(o)||!K.test(o))continue;const a=ot(i);a&&(t[o]=a)}if(!n)return t;for(const[o,i]of Object.entries(n)){if(!M(o)||!K.test(o)||i===void 0)continue;const a=ot(i);if(!a)continue;const u=t[o];t[o]={...u??{},...a,...u?.lightness||a.lightness?{lightness:{...u?.lightness,...a.lightness}}:{},...u?.tones||a.tones?{tones:{...u?.tones,...a.tones}}:{},...u?.semanticMappings||a.semanticMappings?{semanticMappings:{...u?.semanticMappings,...a.semanticMappings}}:{}}}return t}function I(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function j(e){const n={};for(const[t,o]of Object.entries(e))o!==void 0&&M(t)&&(n[t]=o);return n}function st(e){if(!I(e))return e;const n=j(e);return I(e.lightness)&&(n.lightness=j(e.lightness)),I(e.tones)&&(n.tones=j(e.tones)),n}function qt(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&(t[o]=st(i));if(!n)return t;for(const[o,i]of Object.entries(n)){if(!M(o)||i===void 0)continue;const a=t[o];if(!I(a)||!I(i)){t[o]=st(i);continue}const u={...j(a),...j(i)};I(a.lightness)&&I(i.lightness)?u.lightness={...j(a.lightness),...j(i.lightness)}:I(i.lightness)&&(u.lightness=j(i.lightness)),I(a.tones)&&I(i.tones)?u.tones={...j(a.tones),...j(i.tones)}:I(i.tones)&&(u.tones=j(i.tones)),I(a.semanticMappings)&&I(i.semanticMappings)?u.semanticMappings={...j(a.semanticMappings),...j(i.semanticMappings)}:I(i.semanticMappings)&&(u.semanticMappings=j(i.semanticMappings)),t[o]=u}return t}function Xt(e){const n={};for(const[t,o]of Object.entries(e)){if(!M(t))continue;if(typeof o=="string"){n[t]=ce(o);continue}const i={};for(const[a,u]of Object.entries(o))M(a)&&(i[a]=typeof u=="string"?ce(u):u);n[t]=i}return n}function ue(e){return typeof e!="string"?"":e.startsWith("anchor:")?e:ce(e)}function Zt(e){const n={};for(const t of pe)n[t]=ue(e[t]);return n}function rt(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&K.test(o)&&i&&typeof i=="object"&&!Array.isArray(i)&&(t[o]={...i});if(!n)return t;for(const[o,i]of Object.entries(n)){if(!M(o)||!K.test(o)||!i||typeof i!="object"||Array.isArray(i))continue;const a=t[o],u=a!==void 0&&i.type!==void 0&&i.type!==a.type;t[o]={...u?{}:a??{},...i}}return t}function Qt(e){const n={};for(const[t,o]of Object.entries(e))if(M(t)){if(o.type==="sequential"&&typeof o.source=="string"){n[t]={...o,source:ue(o.source)};continue}if(o.type==="diverging"&&typeof o.start=="string"&&typeof o.end=="string"){n[t]={...o,start:ue(o.start),end:ue(o.end),...typeof o.neutral=="string"?{neutral:ue(o.neutral)}:{}};continue}n[t]={...o}}return n}function it(e){const n=W(e.seedColor);if(!n)return;const t=le(n,e);return(o,i)=>{const a=ie(o,t,e.anchors)??t.primary,u=e.chroma.actionBackground,d=re(a,e.lightness[i],u.min,u.max),m={l:d.l>.5?0:1,c:0,h:0};return Math.abs(se(m,d))}}function at(e){const n=W(e.seedColor);if(!n)return;const t=le(n,e);return(o,i)=>{const a=ie(o,t,e.anchors)??t.primary,u=e.chroma.actionBackground,d=re(a,i,u.min,u.max);return Math.abs(se({l:0,c:0,h:0},d))>=Math.abs(se({l:1,c:0,h:0},d))?"dark":"light"}}function en(e,n,t){if(n?.background)return n.background;const o=Y(e.canvas,"color");if(o!==void 0){const i=de.canvas.color?.find(([a])=>a==="background");if(i)return{source:o,lightness:i[1]}}return t.background}function ct(e,n){const t=W(e.seedColor);if(!t||!n)return;const o=le(t,e),i=ie(n.source,o,e.anchors)??o.primary,a=e.chroma.background,u=re(i,Te(e.lightness,e.tones,n.lightness),a.min,a.max);return(d,m)=>{const x=ie(d,o,e.anchors)??o.primary,b=e.chroma.actionBackground,S=re(x,e.lightness[m],b.min,b.max);return bt(S,u)}}function tn(e){const n=me.get(e);if(n)return new Set(n);const t=ge(e);if(t)return t;const o=new Set,i=Ue(e.roles,e.lightness,e.semanticMappings,{tones:e.tones,actionSurfaceContrast:it(e),actionSurfacePole:at(e),actionSurfaceSeparation:ct(e,e.semanticMappings.background)});for(const[a,u]of Object.entries(i)){const d=e.semanticMappings[a];(d.source!==u.source||d.lightness!==u.lightness)&&o.add(a)}return o}function he(e,n){const t={...e.roles,...n.roles},o=Yt(e.contexts,n.contexts),i=Jt(e.lightness,n.lightness),a=Vt(e.tones,n.tones),u=Xt(nt(e.anchors,n.anchors)),d=typeof n.seedColor=="string"?ce(n.seedColor):e.seedColor,m=n.semanticMappings,x={...e.angles,...n.angles},b={...e.semanticHues,...n.semanticHues},S={...e.variantChroma,...n.variantChroma},A=Gt({...e.intents,...n.intents}),D=n.chroma,F=ne(e.chroma,D),L=Zt(ne(e.dataPalette,n.dataPalette)),s=Qt(rt(e.dataRamps,n.dataRamps)),r=tn(e),c=new Set(r),f=ge(n),p={};for(const y of r)p[y]=e.semanticMappings[y];for(const[y,_]of Object.entries(m??{}))_!==void 0&&(f===void 0||f.has(y)?(c.add(y),p[y]=_):(c.delete(y),delete p[y]));const g=ne(e.semanticMappings,p),l={angles:x,anchors:u,chroma:F,intents:A,lightness:i,tones:a,seedColor:d,semanticHues:b,variantChroma:S},h=it(l),k=at(l),$=ct(l,en(t,p,g)),R=Ue(t,i,g,{explicitMappings:p,tones:a,actionSurfaceContrast:h,actionSurfacePole:k,actionSurfaceSeparation:$}),O={};for(const[y,_]of Object.entries(R))c.has(y)||(O[y]=_);const v={};for(const y of Ht)!c.has(y)&&O[y]===void 0&&(v[y]={source:g.text.source,lightness:g.text.lightness},D?.text!==void 0&&D[y]===void 0&&(F[y]={...F.text}));const E=ne(ne(ne(e.semanticMappings,v),O),p),T={...e,seedColor:d,fontBody:n.fontBody||e.fontBody||qe,fontHeadings:n.fontHeadings??e.fontHeadings,fontBrand:n.fontBrand??e.fontBrand,fontMenu:n.fontMenu??e.fontMenu,fontMonospace:n.fontMonospace||e.fontMonospace||Xe,fontWeightBody:String(n.fontWeightBody??e.fontWeightBody),fontWeightHeadings:String(n.fontWeightHeadings??e.fontWeightHeadings),fontWeightBrand:String(n.fontWeightBrand??e.fontWeightBrand),fontWeightMenu:String(n.fontWeightMenu??e.fontWeightMenu),fontWeightMonospace:String(n.fontWeightMonospace??e.fontWeightMonospace),stylesheets:n.stylesheets??[...e.stylesheets],rootFontSize:n.rootFontSize??e.rootFontSize,typeRatio:n.typeRatio??e.typeRatio,spaceRatio:n.spaceRatio??e.spaceRatio,borderRadius:n.borderRadius??e.borderRadius,viewportMin:n.viewportMin??e.viewportMin,viewportMax:n.viewportMax??e.viewportMax,angles:x,semanticHues:b,variantChroma:S,intents:A,lightness:i,tones:a,chroma:F,semanticMappings:E,explicitMappingTokens:et(c),anchors:u,roles:t,contexts:o,dataPalette:L,dataRamps:s};return n.pageBackgroundImage!==void 0&&(T.pageBackgroundImage=n.pageBackgroundImage),n.pageBackgroundImageOpacity!==void 0&&(T.pageBackgroundImageOpacity=n.pageBackgroundImageOpacity),n.boxBackgroundImage!==void 0&&(T.boxBackgroundImage=n.boxBackgroundImage),n.boxBackgroundImageOpacity!==void 0&&(T.boxBackgroundImageOpacity=n.boxBackgroundImageOpacity),n.vellumOpacity!==void 0&&(T.vellumOpacity=n.vellumOpacity),n.vellumBackgroundImage!==void 0&&(T.vellumBackgroundImage=n.vellumBackgroundImage),n.vellumBackgroundImageOpacity!==void 0&&(T.vellumBackgroundImageOpacity=n.vellumBackgroundImageOpacity),me.set(T,new Set(c)),T}const ut=new WeakMap;function ft(e,n){const t=e.contexts&&Object.prototype.hasOwnProperty.call(e.contexts,n)?e.contexts[n]:void 0;if(!t)return null;let o=ut.get(e);const i=o?.get(n);if(i)return i;const a={};for(const d of ae){const m=t[d];m!==void 0&&(a[d]=m)}const u=he(e,{lightness:t.lightness,tones:t.tones,roles:a,semanticMappings:t.semanticMappings});return o||(o=new Map,ut.set(e,o)),o.set(n,u),u}function ne(e,n){if(!n)return{...e};const t={...e};for(const o of Object.keys(n)){const i=n[o];i!==void 0&&(t[o]=i)}return t}function Be(e){let n;try{n=tt(e)}catch{return{error:"Failed to decode Base64 string."}}let t;try{t=JSON.parse(n)}catch{return{error:"Decoded string is not valid JSON."}}return typeof t!="object"||t===null||Array.isArray(t)?{error:"Theme must be a JSON object."}:{value:t}}function hn(e){const n=Be(e);return n.error!==void 0?{valid:!1,errors:[n.error],warnings:[]}:_e(n.value)}function _e(e,n=Re){const t=[],o=[];"seedColor"in e&&(typeof e.seedColor!="string"?t.push("seedColor must be a string."):W(e.seedColor)||t.push(`seedColor is not a valid CSS color: "${e.seedColor}". Accepted forms: ${oe}.`));for(const s of["fontBody","fontHeadings","fontBrand","fontMenu","fontMonospace"])s in e&&typeof e[s]!="string"&&t.push(`${s} must be a string.`);const i=["normal","bold","lighter","bolder"],a=["inherit","initial","unset","revert","revert-layer"];for(const s of["fontWeightBody","fontWeightHeadings","fontWeightBrand","fontWeightMenu","fontWeightMonospace"])if(s in e){const r=e[s];if(typeof r=="number")(r<1||r>1e3)&&t.push(`${s} numeric value must be 1\u20131000 (got ${r}).`);else if(typeof r=="string"){const c=i.includes(r)||a.includes(r);if(/^\d+$/.test(r)){const p=Number(r);(p<1||p>1e3)&&t.push(`${s} numeric value must be 1\u20131000 (got "${r}").`)}else c||o.push(`${s} = "${r}" is not a standard font-weight value.`)}else t.push(`${s} must be a string or number.`)}"stylesheets"in e&&(Array.isArray(e.stylesheets)?e.stylesheets.some(s=>typeof s!="string")&&t.push("Every entry in stylesheets must be a string."):t.push("stylesheets must be an array of strings."));const u=[["rootFontSize",1,100],["borderRadius",0,10],["viewportMin",100,1e4],["viewportMax",200,1e4]];for(const[s,r,c]of u)if(s in e)if(typeof e[s]!="number"||!isFinite(e[s]))t.push(`${s} must be a finite number.`);else{const f=e[s];r!==void 0&&f<r&&t.push(`${s} must be \u2265 ${r} (got ${f}).`),c!==void 0&&f>c&&o.push(`${s} = ${f} is unusually high (max ${c}).`)}for(const s of["typeRatio","spaceRatio"])if(s in e)if(typeof e[s]!="number"||!isFinite(e[s]))t.push(`${s} must be a finite number.`);else{const r=e[s];r<=1&&t.push(`${s} must be > 1 (got ${r}).`);const c=s==="typeRatio"?1.3:2;r>c&&o.push(`${s} = ${r} is very high (max ${c}); scales may be extreme.`)}if("viewportMin"in e&&"viewportMax"in e){const s=e.viewportMin,r=e.viewportMax;typeof s=="number"&&typeof r=="number"&&s>=r&&t.push(`viewportMin (${s}) must be less than viewportMax (${r}).`)}if("angles"in e)if(typeof e.angles!="object"||e.angles===null)t.push("angles must be an object.");else{const s=e.angles;for(const r of["analogous","complementary","splitComplementary","triadic"])if(r in s)if(typeof s[r]!="number"||!isFinite(s[r]))t.push(`angles.${r} must be a finite number.`);else{const c=s[r];(c<0||c>360)&&o.push(`angles.${r} = ${c} is outside 0\u2013360.`)}}if("semanticHues"in e)if(typeof e.semanticHues!="object"||e.semanticHues===null)t.push("semanticHues must be an object.");else{const s=e.semanticHues;for(const r of["danger","success","warning","info"])if(r in s)if(typeof s[r]!="number"||!isFinite(s[r]))t.push(`semanticHues.${r} must be a finite number.`);else{const c=s[r];(c<0||c>360)&&o.push(`semanticHues.${r} = ${c} is outside 0\u2013360.`)}}if("variantChroma"in e)if(typeof e.variantChroma!="object"||e.variantChroma===null)t.push("variantChroma must be an object.");else{const s=e.variantChroma;for(const r of Dt)if(r in s)if(typeof s[r]!="number"||!isFinite(s[r]))t.push(`variantChroma["${r}"] must be a finite number.`);else{const c=s[r];c<0&&t.push(`variantChroma["${r}"] must be \u2265 0 (got ${c}).`),c>q&&o.push(`variantChroma["${r}"] = ${c} exceeds ${q}.`)}}function d(s,r){if(typeof s!="object"||s===null||Array.isArray(s)){t.push(`${r} must be an object.`);return}const c=s;for(const f of Object.keys(c))(!M(f)||!te(f))&&t.push(`${r}.${f} is not a built-in lightness stop; expected one of: ${U.join(", ")}.`);for(const f of U)if(f in c)if(typeof c[f]!="number"||!isFinite(c[f]))t.push(`${r}.${f} must be a finite number.`);else{const p=c[f];(p<0||p>1)&&t.push(`${r}.${f} must be 0\u20131 (got ${p}).`)}}"lightness"in e&&d(e.lightness,"lightness");function m(s,r){const c=new Set;if(!I(s))return t.push(`${r} must be an object.`),c;for(const[f,p]of Object.entries(s)){if(!M(f)||!K.test(f)){t.push(`${r}.${f} must be a lowercase slug matching ${K.source}.`);continue}if(te(f)){t.push(`${r}.${f} conflicts with the built-in "${f}" lightness stop; choose a distinct custom tone name.`);continue}c.add(f),typeof p!="number"||!Number.isFinite(p)?t.push(`${r}.${f} must be a finite number.`):(p<0||p>1)&&t.push(`${r}.${f} must be 0\u20131 (got ${p}).`)}return c}const x=new Set(Object.keys(n.tones??{}));if("tones"in e)for(const s of m(e.tones,"tones"))x.add(s);if("chroma"in e)if(typeof e.chroma!="object"||e.chroma===null)t.push("chroma must be an object.");else{const s=e.chroma,r=Pt(e,n);for(const c of z)if(c in s){const f=s[c];if(typeof f!="object"||f===null){t.push(`chroma.${c} must be { min, max }.`);continue}const p=f;for(const l of r.get(c)??[])l.chroma!==void 0&&typeof p.min=="number"&&typeof p.max=="number"&&(l.chroma<p.min-1e-9||l.chroma>p.max+1e-9)&&o.push(`chroma.${c} clamps the anchor-sourced token ${c} ("${l.source}", effective in ${l.where}) and moves it off its declared swatch. Remove the band if that is unintended \u2014 anchors otherwise keep their own chroma.`);const g=f;(typeof g.min!="number"||g.min<0)&&t.push(`chroma.${c}.min must be \u2265 0.`),(typeof g.max!="number"||g.max<0||g.max>q)&&t.push(`chroma.${c}.max must be 0\u2013${q}.`),typeof g.min=="number"&&typeof g.max=="number"&&g.min>g.max&&t.push(`chroma.${c}.min (${g.min}) must be \u2264 max (${g.max}).`)}}if("anchors"in e)if(typeof e.anchors!="object"||e.anchors===null||Array.isArray(e.anchors))t.push("anchors must be an object of named colors.");else for(const[s,r]of Object.entries(e.anchors))if(M(s)?K.test(s)||t.push(`anchors: "${s}" is not a valid anchor name; use a lowercase slug (letters, digits, hyphens).`):t.push(`anchors: "${s}" is a reserved JavaScript property name and cannot be an anchor name; rename it.`),Me.includes(s)&&t.push(`anchors: "${s}" collides with a reserved color source name.`),typeof r=="string")W(r)||t.push(`anchors.${s} is not a valid CSS color: "${r}". Accepted forms: ${oe}.`);else if(typeof r=="object"&&r!==null&&!Array.isArray(r)){const c=r;typeof c.color!="string"&&t.push(`anchors.${s} must declare its base "color".`);for(const[f,p]of Object.entries(c))M(f)?f!=="color"&&!K.test(f)&&t.push(`anchors.${s}: "${f}" is not a valid slot name; use a lowercase slug.`):t.push(`anchors.${s}: "${f}" is a reserved JavaScript property name and cannot be a slot name; rename it.`),typeof p!="string"?t.push(`anchors.${s}.${f} must be a CSS color string.`):W(p)||t.push(`anchors.${s}.${f} is not a valid CSS color: "${p}". Accepted forms: ${oe}.`)}else t.push(`anchors.${s} must be a color string or a { color, \u2026slots } object.`);const b=new Map;if("anchors"in e&&typeof e.anchors=="object"&&e.anchors!==null&&!Array.isArray(e.anchors))for(const[s,r]of Object.entries(e.anchors))b.set(s,r);function S(s,r){const c=Ae(s);if(!c){t.push(`${r} "${s}" is not valid anchor syntax; use anchor:<name> or anchor:<name>.<slot>.`);return}if(!b.has(c.name)){const f=[...b.keys()];t.push(`${r} references undeclared anchor "${c.name}". Declared anchors: ${f.length>0?f.join(", "):"(none)"}.`);return}if(c.slot!==void 0){const f=b.get(c.name);if(typeof(typeof f=="object"&&f!==null&&!Array.isArray(f)?f[c.slot]:void 0)!="string"){const g=typeof f=="object"&&f!==null?Object.keys(f).filter(l=>l!=="color"):[];t.push(`${r} references unknown slot "${c.slot}" on anchor "${c.name}". Declared slots: ${g.length>0?g.join(", "):"(none)"}.`)}}}function A(s,r){if(s.startsWith("anchor:")){S(s,r);return}Me.includes(s)||t.push(`${r} must be one of: ${Me.join(", ")}, or a declared anchor as anchor:<name> / anchor:<name>.<slot>.`)}if("intents"in e)if(typeof e.intents!="object"||e.intents===null||Array.isArray(e.intents))t.push("intents must be an object.");else for(const[s,r]of Object.entries(e.intents)){const c=`intents.${s}`;if(!ee.includes(s)){t.push(`${c} is not a status family; expected one of: ${ee.join(", ")}.`);continue}if(typeof r!="string"){t.push(`${c} must be a string (a CSS color or an anchor: reference).`);continue}if(r.startsWith("anchor:")){S(r,c);continue}W(r)||t.push(`${c} "${r}" is not a supported color form or anchor: reference. Accepted forms: ${oe}, or anchor:<name> / anchor:<name>.<slot>. An override retunes a family with a declared color; it never points one family at another \u2014 retune, never reassign.`)}function D(s,r){if(s.startsWith("anchor:")){S(s,r);return}W(s)||t.push(`${r} is not a valid CSS color: "${s}". Accepted forms: ${oe}, or a declared anchor as anchor:<name> / anchor:<name>.<slot>.`)}if("dataPalette"in e)if(typeof e.dataPalette!="object"||e.dataPalette===null||Array.isArray(e.dataPalette))t.push("dataPalette must be an object with series1\u2013series8 color values.");else{const s=e.dataPalette;for(const[r,c]of Object.entries(s)){if(!pe.includes(r)){t.push(`dataPalette.${r} is not a series slot; expected one of: ${pe.join(", ")}.`);continue}typeof c!="string"?t.push(`dataPalette.${r} must be a CSS color or anchor reference string.`):D(c,`dataPalette.${r}`)}}if("dataRamps"in e)if(typeof e.dataRamps!="object"||e.dataRamps===null||Array.isArray(e.dataRamps))t.push("dataRamps must be an object of named ramp declarations.");else for(const[s,r]of Object.entries(e.dataRamps)){if(M(s)?K.test(s)||t.push(`dataRamps: "${s}" is not a valid ramp name; use a lowercase slug (letters, digits, hyphens).`):t.push(`dataRamps: "${s}" is a reserved JavaScript property name and cannot be a ramp name; rename it.`),typeof r!="object"||r===null||Array.isArray(r)){t.push(`dataRamps.${s} must be a sequential or diverging ramp object.`);continue}const c=r,f=c.steps??Ct;if((typeof f!="number"||!Number.isInteger(f)||f<Se||f>xe)&&t.push(`dataRamps.${s}.steps must be an integer from ${Se} through ${xe}.`),c.type==="sequential"){typeof c.source!="string"?t.push(`dataRamps.${s}.source must be a CSS color or anchor reference string.`):D(c.source,`dataRamps.${s}.source`);const p=c.lightnessStart??.95,g=c.lightnessEnd??.25;for(const[l,h]of[["lightnessStart",p],["lightnessEnd",g]])(typeof h!="number"||!Number.isFinite(h)||h<0||h>1)&&t.push(`dataRamps.${s}.${l} must be a finite number from 0 through 1.`);typeof p=="number"&&typeof g=="number"&&p<=g?t.push(`dataRamps.${s}.lightnessStart must be greater than lightnessEnd.`):typeof p=="number"&&Number.isFinite(p)&&typeof g=="number"&&Number.isFinite(g)&&typeof f=="number"&&Number.isInteger(f)&&f>=Se&&f<=xe&&(p-g)/(f-1)<=We&&t.push(`dataRamps.${s} lightness bounds must leave more than ${We} lightness between serialized stops.`);continue}if(c.type==="diverging"){typeof f=="number"&&Number.isInteger(f)&&f%2===0&&t.push(`dataRamps.${s}.steps must be odd so the neutral is the exact midpoint.`);for(const p of["start","end"])typeof c[p]!="string"?t.push(`dataRamps.${s}.${p} must be a CSS color or anchor reference string.`):D(c[p],`dataRamps.${s}.${p}`);"neutral"in c&&(typeof c.neutral!="string"?t.push(`dataRamps.${s}.neutral must be a CSS color or anchor reference string.`):D(c.neutral,`dataRamps.${s}.neutral`));continue}t.push(`dataRamps.${s}.type must be "sequential" or "diverging".`)}if("dataPalette"in e&&t.length===0){const s=he(Re,e),r={};let c=!0;for(const f of pe){const p=Rt(s.dataPalette[f],s.anchors);if(!p){c=!1;break}r[f]=p}if(c)for(const f of Ot(r))o.push(Tt(f))}function F(s,r){if(typeof s!="object"||s===null||Array.isArray(s)){t.push(`${r} must be an object.`);return}const c=s;for(const[f,p]of Object.entries(c)){const g=`${r}.${f}`;if(!ae.includes(f)){t.push(`${g} is not a role; expected one of: ${ae.join(", ")}. (The status family is reserved and is not a role.)`);continue}const l=f,h=de[l];if(typeof p=="string"){A(p,g);continue}if(typeof p!="object"||p===null||Array.isArray(p)){t.push(`${g} must be a color source or a { color, \u2026slots } object.`);continue}const k=p;typeof k.color!="string"&&t.push(`${g} must declare its base "color".`);for(const[$,R]of Object.entries(k)){if(!Object.prototype.hasOwnProperty.call(h,$)||!M($)){const O=Object.keys(h).filter(v=>v!=="color");t.push(`${g}.${$} is not a slot of the ${l} role. Declared slots: ${O.length>0?O.join(", "):"(none)"}.`);continue}typeof R!="string"?t.push(`${g}.${$} must be a color source string.`):A(R,`${g}.${$}`)}}}if("roles"in e&&F(e.roles,"roles"),"contexts"in e)if(typeof e.contexts!="object"||e.contexts===null||Array.isArray(e.contexts))t.push("contexts must be an object.");else for(const[s,r]of Object.entries(e.contexts)){if(!M(s)||!K.test(s)){t.push(`contexts.${s} must be a lowercase slug matching ${K.source}.`);continue}if(typeof r!="object"||r===null||Array.isArray(r)){F(r,`contexts.${s}`);continue}const c=r,f=Object.fromEntries(Object.entries(c).filter(([g])=>g!=="lightness"&&g!=="tones"&&g!=="semanticMappings"));F(f,`contexts.${s}`),"lightness"in c&&d(c.lightness,`contexts.${s}.lightness`);const p=new Set(x);if("tones"in c)for(const g of m(c.tones,`contexts.${s}.tones`))p.add(g);"semanticMappings"in c&&L(c.semanticMappings,`contexts.${s}.semanticMappings`,p)}function L(s,r,c){if(typeof s!="object"||s===null||Array.isArray(s)){t.push(`${r} must be an object.`);return}const f=s;for(const p of Object.keys(f))z.includes(p)||t.push(`${r}.${p} is not a semantic token; expected one of: ${z.join(", ")}.`);for(const p of z)if(p in f){const g=f[p];if(typeof g!="object"||g===null){t.push(`${r}.${p} must be { source, lightness }.`);continue}const l=g;if(typeof l.source!="string"?t.push(`${r}.${p}.source must be a string.`):A(l.source,`${r}.${p}.source`),typeof l.lightness!="string")t.push(`${r}.${p}.lightness must be one of: ${U.join(", ")}, or a declared tone:<name>.`);else if(!te(l.lightness)){const h=Oe(l.lightness);if(h===null)t.push(`${r}.${p}.lightness must be one of: ${U.join(", ")}, or a declared tone:<name>.`);else if(!c.has(h)){const k=[...c].sort();t.push(`${r}.${p}.lightness references undeclared tone "${h}". Declared tones: ${k.length>0?k.join(", "):"(none)"}.`)}}}}if("semanticMappings"in e&&L(e.semanticMappings,"semanticMappings",x),"explicitMappingTokens"in e)if(!Array.isArray(e.explicitMappingTokens))t.push("explicitMappingTokens must be an array of semantic token names.");else{const s=new Set,r=I(e.semanticMappings)?e.semanticMappings:void 0;for(const c of e.explicitMappingTokens){if(typeof c!="string"||!z.includes(c)){t.push(`explicitMappingTokens entries must be one of: ${z.join(", ")}.`);continue}s.has(c)&&t.push(`explicitMappingTokens contains duplicate token "${c}".`),s.add(c),(!r||!Object.prototype.hasOwnProperty.call(r,c))&&t.push(`explicitMappingTokens names "${c}" without a semanticMappings entry.`)}}for(const s of["pageBackgroundImage","boxBackgroundImage","vellumBackgroundImage"])s in e&&typeof e[s]!="string"&&t.push(`${s} must be a string.`);for(const s of["pageBackgroundImageOpacity","boxBackgroundImageOpacity","vellumOpacity","vellumBackgroundImageOpacity"])if(s in e)if(typeof e[s]!="number"||!isFinite(e[s]))t.push(`${s} must be a finite number.`);else{const r=e[s];(r<0||r>1)&&t.push(`${s} must be 0\u20131 (got ${r}).`)}return o.push(...nn(e,n)),{valid:t.length===0,errors:t,warnings:o}}const B=.045;function nn(e,n){try{return on(e,n)}catch{return[]}}function on(e,n){const t=he(n,e),o=dt(t),i=[...o],a=new Set(o);for(const u of Object.keys(t.contexts)){const d=ft(t,u);if(d)for(const m of dt(d))a.has(m)||i.push(`contexts.${u}: ${m}`)}return i}function sn(e){const n=kt($e(e)),t=St(n);return $t({r:be(t.r),g:be(t.g),b:be(t.b)})}function Z(e,n){return Math.hypot(e.L-n.L,e.a-n.a,e.b-n.b)}function X(e){return sn(W(fe($e(e))))}function lt(e){return(Math.floor(e*1e4)/1e4).toFixed(4)}const Q=2,pt=1e-4;function dt(e){const n=W(e.seedColor);if(!n)return[];const t=le(n,e),o=e.semanticMappings.actionBackground,i=e.chroma.actionBackground,a=Te(e.lightness,e.tones,o.lightness),u=(l,h,k,$)=>$e(re(l,h,k,$)),d=ee.map(l=>({name:l,base:t[l]})),m=[];if(ee.includes(o.source))m.push(`actionBackground is sourced from the "${o.source}" status family: ordinary and ${o.source}-intent action surfaces render identically (their labels may still differ). Remap the action to a non-status source \u2014 retuning "${o.source}" via intents moves both colors together.`);else{const l=ie(o.source,t,e.anchors);l&&d.push({name:"action",base:l})}const x=Fe(d.map(({name:l,base:h})=>[l,fe(u(h,a,i.min,i.max))]),B,["normal"]);if(x.length===0)return m;const b=new Map,S=(l,h)=>{const k=`${l}:${h}`;let $=b.get(k);if(!$){$=[];for(let R=0;R<360;R+=Q)$.push(X({l,c:h,h:R}));b.set(k,$)}return $},A=B-.002,D=(l,h,k,$)=>{const R=Math.hypot(l.a,l.b),O=Math.atan2(l.b,l.a)*180/Math.PI+180;let v=0;for(const E of k===$?[$]:[k,$]){if(E+R<B-1e-4)continue;let T=O,y=Z(X({l:h,c:E,h:O}),l);if(y>=B)return y;const _=S(h,E);for(let w=0;w<_.length;w+=1){const C=Z(_[w],l);if(C>=B)return C;C>y&&(y=C,T=w*Q)}let H=T;for(let w=T-Q;w<=T+Q;w+=.1){const C=Z(X({l:h,c:E,h:w}),l);if(C>=B)return C;C>y&&(y=C,H=w)}if(y>=A)for(let w=H-.1;w<=H+.1;w+=.001){const C=Z(X({l:h,c:E,h:w}),l);if(C>=B)return C;C>y&&(y=C)}y>v&&(v=y)}return v},F=(l,h,k)=>{const $=h===k?[k]:[h,k];let R=0;for(const O of $)for(const v of $){if(O+v<B-1e-4)continue;const E=S(l,O),T=S(l,v);let y=0,_=0,H=-1;for(let P=0;P<E.length;P+=1)for(let G=0;G<T.length;G+=1){const V=Z(E[P],T[G]);if(V>=B)return V;V>H&&(H=V,y=P*Q,_=G*Q)}const w=(P,G,V,Le)=>{const Ie=[];for(let J=G-V;J<=G+V;J+=Le)Ie.push({h:J,lab:X({l,c:v,h:J})});let ye=-1,Ne=P,Pe=G;for(let J=P-V;J<=P+V;J+=Le){const ht=X({l,c:O,h:J});for(const He of Ie){const De=Z(ht,He.lab);De>ye&&(ye=De,Ne=J,Pe=He.h)}}return{distance:ye,hueA:Ne,hueB:Pe}},C=w(y,_,Q,.1);if(C.distance>=B)return C.distance;let N=Math.max(H,C.distance);if(N>=A){const P=w(C.hueA,C.hueB,.1,.001);if(P.distance>N&&(N=P.distance),N>=B)return N}N>R&&(R=N)}return R},L=l=>ee.includes(l),s=(l,h,k,$,R)=>{const O=X(u(l.base,k,$,R)),v=X(u(h.base,k,$,R));if(Z(O,v)>=B)return{outcome:"direct"};const E=L(l.name)&&L(h.name),T=[l,h].filter(H=>L(H.name)),y=E?"one of them":`"${L(l.name)?l.name:h.name}"`;let _;for(const H of T){const w=D(H===l?v:O,k,$,R);if(w>=B)return{outcome:"retune",target:y};w>=B-pt&&(_=_??y)}if(E){const H=F(k,$,R);if(H>=B)return{outcome:"retune",target:"both"};H>=B-pt&&(_=_??"both")}return _!==void 0?{outcome:"near",target:_}:{outcome:"no"}},r=l=>l.outcome==="direct"?4:l.outcome==="retune"?l.target==="both"?2:3:l.outcome==="near"?1:0,c=l=>[...l].sort().join("|"),f=new Set(Fe(d.map(({name:l,base:h})=>[l,fe(u(h,a,0,q))]),B,["normal"]).map(l=>c(l.pair))),p=new Map(d.map(l=>[l.name,l])),g=new Map;for(const{pair:l,distance:h}of x){const k=p.get(l[0]),$=p.get(l[1]),R=L(k.name)&&L($.name),O=s(k,$,a,i.min,i.max);if(O.outcome==="direct"||O.outcome==="retune"){const N=O.target??(R?"one of them":`"${L(k.name)?k.name:$.name}"`);f.has(c(l))?m.push(`Status colors "${l[0]}" and "${l[1]}" are hard to distinguish under normal vision (distance ${lt(h)} < ${B}); status meanings must stay distinguishable \u2014 retune ${N} via intents.`):m.push(`Status colors "${l[0]}" and "${l[1]}" are hard to distinguish as rendered (distance ${lt(h)} < ${B}); the actionBackground chroma band ({ min: ${i.min}, max: ${i.max} }) pushes them together \u2014 widen the band, or retune ${N} via intents.`);continue}const v=s(k,$,a,0,q);let E={outcome:"no"};for(let N=1;N<=19&&E.outcome!=="direct";N+=1){const P=N*.05;if(Math.abs(P-a)<.001)continue;const G=s(k,$,P,i.min,i.max);r(G)>r(E)&&(E=G)}let T={outcome:"no"};const y=v.outcome==="direct"||v.outcome==="retune",_=E.outcome==="direct"||E.outcome==="retune";if(!y&&!_)for(let N=1;N<=19&&T.outcome!=="direct";N+=1){const P=s(k,$,N*.05,0,q);r(P)>r(T)&&(T=P)}const H=rn(v,E,T),w=`${O.outcome}|${H}`;let C=g.get(w);C||(C=[],g.set(w,C)),C.push(l)}for(const[l,h]of g){const k=l.indexOf("|"),$=l.slice(0,k),R=l.slice(k+1),O=h.map(([T,y])=>`"${T}"/"${y}"`),v=O.length>1?`${O.slice(0,-1).join(", ")} and ${O[O.length-1]}`:O[0],E=$==="near"?`Status colors ${v} may not separate by retuning as rendered: at the action stop's lightness (${a}) with the actionBackground chroma band ({ min: ${i.min}, max: ${i.max} }), the closest reachable retune found comes within the audit's search margin of the ${B} threshold`:`Status colors ${v} cannot be separated as rendered: at the action stop's lightness (${a}) with the actionBackground chroma band ({ min: ${i.min}, max: ${i.max} }), no intent retuning can pull ${h.length>1?"these pairs":"the pair"} ${B} apart`;m.push(E+R)}return m}function rn(e,n,t){if(e.outcome==="direct"&&n.outcome==="direct")return" \u2014 widen the chroma band or move the action lightness stop.";if(e.outcome==="direct")return n.outcome==="no"?"; no other action lightness stop can help while the band holds \u2014 widen the chroma band.":" \u2014 widen the chroma band.";if(n.outcome==="direct")return e.outcome==="no"?"; no wider chroma band can help at this lightness \u2014 move the action lightness stop.":" \u2014 move the action lightness stop.";if(e.outcome==="retune"&&n.outcome==="retune")return` \u2014 widen the chroma band or move the action lightness stop, then retune ${e.target} via intents.`;if(e.outcome==="retune")return n.outcome==="no"?`; no other action lightness stop can help while the band holds \u2014 widen the chroma band, then retune ${e.target} via intents.`:` \u2014 widen the chroma band, then retune ${e.target} via intents.`;if(n.outcome==="retune")return e.outcome==="no"?`; no wider chroma band can help at this lightness \u2014 move the action lightness stop, then retune ${n.target} via intents.`:` \u2014 move the action lightness stop, then retune ${n.target} via intents.`;const o=e.outcome==="no"&&n.outcome==="no"?"; neither a wider chroma band alone nor another stop alone can help":"; neither a wider chroma band alone nor another stop alone provably helps";return t.outcome==="direct"?`${o} \u2014 change the band and the stop together.`:t.outcome==="retune"?`${o} \u2014 change the band and the stop together, then retune ${t.target} via intents.`:"; no explored band or stop change provably separates this pair."}function yn(e,n){const t=Be(e),o=Be(n),i=t.error!==void 0?{valid:!1,errors:[t.error],warnings:[]}:_e(t.value),a=o.error!==void 0?{valid:!1,errors:[o.error],warnings:[]}:_e(o.value,Qe),u=[...i.errors.map(m=>`light: ${m}`),...a.errors.map(m=>`dark: ${m}`)],d=[...i.warnings.map(m=>`light: ${m}`),...a.warnings.map(m=>`dark: ${m}`)];if(i.valid&&a.valid){const m=new Set(Object.keys(t.value?.contexts??{})),x=new Set(Object.keys(o.value?.contexts??{})),b=[...x].filter(A=>!m.has(A)).sort(),S=[...m].filter(A=>!x.has(A)).sort();(b.length>0||S.length>0)&&u.push(`contexts must declare the same names in both schemes. Missing from light: ${b.join(", ")||"(none)"}. Missing from dark: ${S.join(", ")||"(none)"}.`)}return{valid:u.length===0,errors:u,warnings:d}}const an=["anchors","angles","contexts","dataPalette","dataRamps","intents","roles","chroma","lightness","tones","semanticHues","semanticMappings","variantChroma"];function cn(e,n){const t={};for(const[a,u]of Object.entries(e))M(a)&&(t[a]=u);for(const[a,u]of Object.entries(n))u!==void 0&&M(a)&&(t[a]=u);for(const a of an){const u=e[a],d=n[a];if(u&&typeof u=="object"&&!Array.isArray(u)&&d&&typeof d=="object"&&!Array.isArray(d)){if(a==="anchors"){t[a]=nt(u,d);continue}if(a==="contexts"){t[a]=qt(u,d);continue}if(a==="dataRamps"){t[a]=rt(u,d);continue}const m={};for(const[x,b]of Object.entries(u))M(x)&&(m[x]=b);for(const[x,b]of Object.entries(d))b!==void 0&&M(x)&&(m[x]=b);t[a]=m}}const o=ge(e),i=ge(n);if(o!==void 0||i!==void 0){const a=o??new Set(Object.keys(e.semanticMappings??{}).filter(u=>z.includes(u)));for(const u of Object.keys(n.semanticMappings??{}))i===void 0||i.has(u)?a.add(u):a.delete(u);t.explicitMappingTokens=et(a)}return t}function bn(...e){let n={};for(const t of e){if(!t)continue;const o=zt(t);o&&(n=cn(n,o))}return Ee(n)}function mt(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")}const gt={borderRadius:.1,fontBody:'"Noto Sans", sans-serif',fontWeightBody:"normal",fontHeadings:'"Inika", serif',fontWeightHeadings:"normal",fontBrand:'"Inika", serif',fontWeightBrand:"normal",fontMonospace:'"JetBrains Mono", monospace',fontWeightMonospace:"normal",seedColor:"oklch(.07 0.15 216)"};function $n(e){return Ee({...gt,pageBackgroundImage:`url("${mt(e)}")`,pageBackgroundImageOpacity:.5})}function kn(e){return Ee({...gt,pageBackgroundImage:`url("${mt(e)}")`,pageBackgroundImageOpacity:.55})}export{K as ANCHOR_SLUG_PATTERN,Me as COLOR_SOURCES,qe as DEFAULT_BODY_FONT_FAMILY,Wt as DEFAULT_DARK_LIGHTNESS,Qe as DEFAULT_DARK_THEME,Ft as DEFAULT_LIGHT_LIGHTNESS,Re as DEFAULT_LIGHT_THEME,Xe as DEFAULT_MONOSPACE_FONT_FAMILY,Je as DEFAULT_SEMANTIC_MAPPINGS,U as LIGHTNESS_KEYS,an as NESTED_THEME_KEYS,Et as ROLE_DERIVED_INK,ae as ROLE_NAMES,Ke as ROLE_PAIRED_INK,de as ROLE_TOKEN_PLAN,z as SEMANTIC_COLOR_NAMES,ee as STATUS_COLOR_SOURCES,Ge as TOKEN_PAIRINGS,Dt as VARIANT_COLOR_SOURCES,kn as buildTaprootDarkTheme,$n as buildTaprootLightTheme,Ue as compileRoles,Ee as encodeTheme,tn as explicitMappingTokens,te as isLightnessKey,I as isObjectRecord,mn as isSemanticColorName,bn as layerThemes,cn as mergePartials,he as mergeTheme,Ae as parseAnchorSource,zt as parseTheme,je as resolveAnchorColor,ft as resolveContextTheme,Rt as resolveDataColorSource,Te as resolveLightnessReference,dn as roleInkProvenance,gn as semanticToCSS,Oe as toneReferenceName,hn as validateTheme,yn as validateThemePair};
@@ -1635,7 +1635,7 @@
1635
1635
  },
1636
1636
  {
1637
1637
  "name": "--esp-section-decoration-image",
1638
- "description": "Raster alpha mask painted behind the well. Defaults to `none`."
1638
+ "description": "Raster alpha mask painted behind the well when `decoration` is set. Defaults to `none`."
1639
1639
  },
1640
1640
  {
1641
1641
  "name": "--esp-section-decoration-opacity",
@@ -2352,7 +2352,7 @@
2352
2352
  "name": "--esp-section-decoration-image",
2353
2353
  "category": "component",
2354
2354
  "component": "esp-section",
2355
- "description": "Raster alpha mask painted behind the well. Defaults to `none`."
2355
+ "description": "Raster alpha mask painted behind the well when `decoration` is set. Defaults to `none`."
2356
2356
  },
2357
2357
  {
2358
2358
  "name": "--esp-section-decoration-opacity",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taprootio/espalier",
3
- "version": "4.18.0",
3
+ "version": "4.20.0",
4
4
  "packageManager": "bun@1.3.12",
5
5
  "description": "Espalier — a themeable, accessible, framework-agnostic, enterprise-grade design system built on web standards and love.",
6
6
  "customElements": "custom-elements.json",