@taprootio/espalier 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +21963 -21562
- package/dist/cli/theme-check.js +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/shared/data-colors.d.ts +14 -0
- package/dist/shared/data-colors.js +1 -1
- package/dist/shared/theme-fit-report.d.ts +59 -0
- package/dist/shared/theme-fit-report.js +1 -1
- package/dist/shared/theme.d.ts +4 -0
- package/dist/shared/theme.js +1 -1
- package/package.json +1 -1
package/dist/cli/theme-check.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{encodeTheme as
|
|
2
|
-
`)}catch(s){return e.error(`Cannot write ${t.updateExpect}: ${s instanceof Error?s.message:String(s)}`),2}return i(`Wrote fit tables to ${t.updateExpect}.`),t.json&&e.log(JSON.stringify(r,null,2)),0}if(t.expect!==void 0){let s;try{s=e.readFile(t.expect)}catch{return e.error(`Expected fit tables not found at ${t.expect} \u2014 create them with --update-expect ${t.expect}.`),2}let f;try{f=JSON.parse(s)}catch{return e.error(`${t.expect} is not JSON.`),2}if(!y(f))return e.error(`${t.expect} is not a fit-table suite \u2014 regenerate it with --update-expect ${t.expect}.`),2;const a=x(f,r);if(a.length>0){for(const l of a)e.error(`drift: ${l}`);return e.error(`Fit tables drifted from ${t.expect} (${a.length} difference(s)). Review, then refresh deliberately with --update-expect.`),1}i(`Fit tables match ${t.expect}.`)}return t.json?(e.log(JSON.stringify(r,null,2)),0):(b(r,e),0)}function y(t){if(typeof t!="object"||t===null||Array.isArray(t))return!1;const e=t;if(!Array.isArray(e.surfaces)||!e.surfaces.every(n=>typeof n=="string"))return!1;for(const n of["light","dark"]){const o=e[n];if(!Array.isArray(o))return!1;for(const r of o){if(typeof r!="object"||r===null||Array.isArray(r))return!1;const i=r;if(typeof i.surface!="string"||!Array.isArray(i.tokens))return!1;for(const s of i.tokens){if(typeof s!="object"||s===null||Array.isArray(s))return!1;const f=s;if(typeof f.token!="string"||typeof f.resolved!="string")return!1}}}return!0}function x(t,e){const n=[];if(JSON.stringify(t)===JSON.stringify(e))return n;for(const o of["light","dark"]){const r=new Map((t[o]??[]).map(s=>[s.surface,s])),i=new Map((e[o]??[]).map(s=>[s.surface,s]));for(const s of new Set([...r.keys(),...i.keys()])){const f=r.get(s),a=i.get(s);if(!f||!a){n.push(`${o}/${s}: surface ${f?"removed":"added"}`);continue}const l=new Map(f.tokens.map(c=>[c.token,c]));for(const c of a.tokens){const d=l.get(c.token);d?d.resolved!==c.resolved&&n.push(`${o}/${s}/${c.token}: ${d.resolved} \u2192 ${c.resolved}`):n.push(`${o}/${s}/${c.token}: token added`),l.delete(c.token)}for(const c of l.keys())n.push(`${o}/${s}/${c}: token removed`)}}return n.length===0&&n.push("fit-table metadata changed (lints or provenance marks)"),n}function b(t,e){for(const o of["light","dark"])for(const r of t[o]){e.log(j(o,r));for(const i of r.lints)e.log(` lint(${i.id}): ${i.message}`)}const n=[...t.light,...t.dark].reduce((o,r)=>o+r.lints.length,0);e.log(`Checked ${t.surfaces.length} surface(s) \xD7 2 schemes \u2014 `+(n===0?"no lints.":`${n} lint(s), listed above.`))}function j(t,e){const n=e.adjustedTokens.length===0?"contrast enforcement moved nothing":`contrast enforcement moved ${e.adjustedTokens.join(", ")}`,o=e.tokens.filter(i=>i.explicit==="inherited").length,r=o===0?"":`; ${o} inherited explicit pin(s) \u2014 see the fit tables`;return`${t}/${e.surface}: ${e.tokens.length} tokens, ${n}${r}.`}export{S as runEspalierCli};
|
|
1
|
+
import{encodeTheme as D,isObjectRecord as p,isSemanticColorName as P,validateThemePair as G}from"../shared/theme.js";import{THEME_FIT_ANCHOR_FIELDS as C,THEME_FIT_APCA_FIELDS as N,THEME_FIT_DATA_PALETTE_LINT_FIELDS as M,THEME_FIT_DATA_PALETTE_LINT_IDS as X,THEME_FIT_EXPLICIT_VALUES as Y,THEME_FIT_LINT_FIELDS as R,THEME_FIT_LINT_IDS as B,THEME_FIT_LINT_SEVERITIES as Q,THEME_FIT_REPORT_FIELDS as _,THEME_FIT_SUITE_FIELDS as k,THEME_FIT_TOKEN_FIELDS as x,themeFitReportSuite as Z}from"../shared/theme-fit-report.js";import{COLOR_VISION_SIMULATIONS as v,DATA_SERIES_KEYS as w,isPaletteCollisionDescription as ee}from"../shared/data-colors.js";import{isSafeKey as te}from"../shared/unsafe-keys.js";const A="usage: espalier theme check <theme.json> [--json] [--expect <fit.json>] [--update-expect <fit.json>]";function Me(e,t){const[r,i,...n]=e;if(r!=="theme"||i!=="check")return t.error(A),2;const s=re(n,t);return s?ie(s,t):2}function re(e,t){const r={file:"",json:!1};for(let i=0;i<e.length;i+=1){const n=e[i];if(n==="--json")r.json=!0;else if(n==="--expect"||n==="--update-expect"){const s=e[i+1];if(s===void 0)return t.error(`${n} requires a file path. ${A}`),null;n==="--expect"?r.expect=s:r.updateExpect=s,i+=1}else if(!n.startsWith("--")&&r.file==="")r.file=n;else return t.error(`Unknown argument "${n}". ${A}`),null}return r.file===""?(t.error(A),null):r.expect!==void 0&&r.updateExpect!==void 0?(t.error(`--expect checks the committed fit tables and --update-expect rewrites them \u2014 pick one. ${A}`),null):r}function ne(e,t){let r;try{r=t.readFile(e)}catch(s){return t.error(`Cannot read ${e}: ${s instanceof Error?s.message:String(s)}`),null}let i;try{i=JSON.parse(r)}catch(s){return t.error(`${e} is not JSON: ${s instanceof Error?s.message:String(s)}`),null}if(typeof i!="object"||i===null||Array.isArray(i))return t.error(`${e} must contain a theme object.`),null;const n=i;if("light"in n||"dark"in n){for(const s of["light","dark"]){const o=n[s];if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))return t.error(`${e}: "${s}" must be a theme object.`),null}return{light:n.light??{},dark:n.dark??{}}}return{light:n,dark:n}}function ie(e,t){const r=ne(e.file,t);if(!r)return 2;const i=G(D(r.light),D(r.dark));if(!i.valid){for(const c of i.warnings)t.error(`warning: ${c}`);for(const c of i.errors)t.error(`error: ${c}`);return t.error(`${e.file}: ${i.errors.length} validation error(s).`),1}const n=Z(r.light,r.dark);for(const c of i.warnings)Ie(c,n)||t.error(`warning: ${c}`);const s=Ae(n),o=e.json?t.error:t.log;if(e.updateExpect!==void 0){try{t.writeFile(e.updateExpect,`${JSON.stringify(n,null,2)}
|
|
2
|
+
`)}catch(c){return t.error(`Cannot write ${e.updateExpect}: ${c instanceof Error?c.message:String(c)}`),2}o(`Wrote fit tables to ${e.updateExpect}.`)}if(e.expect!==void 0){let c;try{c=t.readFile(e.expect)}catch{return t.error(`Expected fit tables not found at ${e.expect} \u2014 create them with --update-expect ${e.expect}.`),2}let a;try{a=JSON.parse(c)}catch{return t.error(`${e.expect} is not JSON.`),2}if(se(a))return t.error(`${e.expect} was written by espalier \u22644.2.0 \u2014 regenerate it with --update-expect ${e.expect}.`),2;if(!oe(a))return t.error(`${e.expect} is not a fit-table suite \u2014 regenerate it with --update-expect ${e.expect}.`),2;const f=le(a,n);if(f.length>0){s>0&&we(n,s,t);for(const u of f)t.error(`drift: ${u}`);return t.error(`Fit tables drifted from ${e.expect} (${f.length} difference(s)). Review, then refresh deliberately with --update-expect.`),1}o(`Fit tables match ${e.expect}.`)}return e.json?(t.log(JSON.stringify(n,null,2)),s>0?1:0):(xe(n,s,t),s>0?1:0)}function oe(e){if(!p(e)||!k.every(({field:r,kind:i})=>T(e[String(r)],i)))return!1;const t=e;if(!I(t.surfaces))return!1;for(const r of["light","dark"]){const n=t.paletteLints[r].map(g);if(!I(n))return!1;const s=t[r],o=new Set;for(const c of s){if(!pe(c,r)||!t.surfaces.includes(c.surface)||o.has(c.surface))return!1;o.add(c.surface)}}return!0}function se(e){return p(e)&&H(e.surfaces)&&Array.isArray(e.light)&&Array.isArray(e.dark)&&!("dataPalette"in e)&&!("paletteLints"in e)}function ce(e){return typeof e=="number"&&Number.isFinite(e)}function H(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")}function I(e){return new Set(e).size===e.length}function ae(e){return p(e)&&M.every(({field:t,kind:r})=>T(e[String(t)],r))}function fe(e){return p(e)&&R.every(({field:t,kind:r})=>T(e[String(t)],r))}function ue(e){return p(e)&&x.every(({field:t,kind:r})=>T(e[String(t)],r))}function T(e,t){switch(t){case"anchor":return e===void 0||V(e,C);case"anchor-record":return p(e)&&Object.keys(e).every(te)&&Object.values(e).every(r=>typeof r=="string");case"apca":return e===void 0||V(e,N);case"boolean":return typeof e=="boolean";case"data-palette-record":return p(e)?["light","dark"].every(r=>{const i=e[r];return p(i)&&w.every(n=>typeof i[n]=="string")}):!1;case"explicit":return e===void 0||Y.includes(e);case"fit-lint-id":return B.includes(e);case"lint-array":return Array.isArray(e)&&e.every(fe);case"message":case"string":return typeof e=="string";case"number":return ce(e);case"palette-lint-id":return X.includes(e);case"palette-lint-record":return p(e)&&["light","dark"].every(r=>Array.isArray(e[r])&&e[r].every(ae));case"report-array":return Array.isArray(e);case"scheme":return e==="light"||e==="dark";case"semantic":return P(e);case"semantic-array":return Array.isArray(e)&&e.every(P);case"series-pair":return de(e);case"simulation":return v.includes(e);case"string-array":return H(e);case"token-array":return Array.isArray(e)&&e.every(ue);case"warning":return Q.includes(e);default:{const r=t;return!1}}}function V(e,t){return p(e)&&t.every(({field:r,kind:i})=>T(e[String(r)],i))}function de(e){if(!Array.isArray(e)||e.length!==2)return!1;const t=w.indexOf(e[0]),r=w.indexOf(e[1]);return t>=0&&r>t}function pe(e,t){if(!p(e)||!_.every(({field:i,kind:n})=>T(e[String(i)],n)))return!1;const r=e;return r.scheme!==t?!1:I(r.tokens.map(i=>i.token))&&I(r.adjustedTokens)&&I(r.lints.map(i=>i.id))}function le(e,t){const r=[];for(const n of k)n.compared&&me(r,n,e,t);return(h(z(e))!==h(z(t))||r.length===0&&h(e)!==h(t))&&r.push("fit tables differ outside compared fields"),r}function me(e,t,r,i){const{field:n,kind:s}=t;if(s==="string-array"){const o=r[n],c=i[n];U(e,String(n),o,c),E(e,String(n),o,c);return}if(s==="data-palette-record"){const o=r[n],c=i[n];for(const a of["light","dark"])for(const f of w)K(e,`${a}/${String(n)}/${f}`,o[a][f],c[a][f]);return}if(s==="palette-lint-record"){const o=r[n],c=i[n];for(const a of["light","dark"])ke(e,a,String(n),o[a],c[a]),E(e,`${a}/${String(n)}`,o[a].map(g),c[a].map(g));return}if(s==="report-array"&&(n==="light"||n==="dark")){he(e,n,r[n],i[n]);return}F(e,"fit tables",String(n),r[n],i[n],s)}function he(e,t,r,i){const n=new Map(r.map(o=>[o.surface,o])),s=new Map(i.map(o=>[o.surface,o]));E(e,`${t}/reports`,r.map(o=>o.surface),i.map(o=>o.surface));for(const o of L(n.keys(),s.keys())){const c=n.get(o),a=s.get(o),f=`${t}/${o}`;if(!c||!a){e.push(`${f}: surface ${c?"removed":"added"}`);continue}ge(e,f,c,a)}}function ge(e,t,r,i){for(const n of _){const{compared:s,field:o,kind:c}=n;if(!(!s||o==="scheme"||o==="surface")){if(c==="anchor-record"){Te(e,`${t}/${String(o)}`,r[o],i[o]);continue}if(c==="semantic-array"){const a=r[o],f=i[o];U(e,`${t}/${String(o)}`,a,f),E(e,`${t}/${String(o)}`,a,f);continue}if(c==="lint-array"){const a=r[o],f=i[o];Se(e,t,String(o),a,f),E(e,`${t}/${String(o)}`,a.map(u=>u.id),f.map(u=>u.id));continue}if(c==="token-array"){$e(e,t,String(o),r[o],i[o]);continue}F(e,t,String(o),r[o],i[o],c)}}}function $e(e,t,r,i,n){const s=new Map(i.map(a=>[a.token,a])),o=new Map(n.map(a=>[a.token,a]));E(e,`${t}/${r}`,i.map(a=>a.token),n.map(a=>a.token));const c=r==="tokens"?t:`${t}/${r}`;for(const a of L(s.keys(),o.keys())){const f=s.get(a),u=o.get(a),S=`${c}/${a}`;if(!f||!u){e.push(`${S}: token ${f?"removed":"added"}`);continue}ye(e,S,f,u)}}function ye(e,t,r,i){for(const{compared:n,field:s,kind:o}of x)if(!(!n||s==="token")){if(o==="anchor"){J(e,t,"anchor",r.anchor,i.anchor,C);continue}if(o==="apca"){J(e,t,"apca",r.apca,i.apca,N);continue}F(e,t,String(s),r[s],i[s],o)}}function J(e,t,r,i,n,s){const o=i,c=n;for(const{compared:a,field:f,kind:u}of s)a&&F(e,t,`${r}.${String(f)}`,o?.[f],c?.[f],u)}function Se(e,t,r,i,n){const s=new Map(i.map(c=>[c.id,c])),o=new Map(n.map(c=>[c.id,c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of R)if(!(!S||d==="id")){if(b==="semantic-array"){Ee(e,u,String(d),a[d],f[d]);continue}F(e,u,String(d),a[d],f[d],b)}}}function ke(e,t,r,i,n){const s=new Map(i.map(c=>[g(c),c])),o=new Map(n.map(c=>[g(c),c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of M)!S||d==="id"||d==="series"||d==="simulation"||F(e,u,String(d),a[d],f[d],b)}}function g(e){return`${e.id}/${e.series[0]}+${e.series[1]}/${e.simulation}`}function Te(e,t,r,i){for(const n of L(Object.keys(r),Object.keys(i)))K(e,`${t}/${n}`,r[n],i[n])}function U(e,t,r,i){const n=new Set(r),s=new Set(i);for(const o of L(n,s))n.has(o)!==s.has(o)&&e.push(`${t}/${o}: ${n.has(o)?"removed":"added"}`)}function E(e,t,r,i){const n=new Set(r),s=new Set(i),o=r.filter(a=>s.has(a)),c=i.filter(a=>n.has(a));o.some((a,f)=>a!==c[f])&&e.push(`${t}: order changed`)}function Ee(e,t,r,i,n){const s=Math.max(i.length,n.length);for(let o=0;o<s;o+=1)W(e,t,`${r}[${o}]`,i[o],n[o])}function K(e,t,r,i){r!==i&&e.push(`${t}: ${j(r)} \u2192 ${j(i)}`)}function W(e,t,r,i,n,s){if(!Object.is(i,n)){if(s==="message"){e.push(`${t}: message changed`);return}e.push(`${t}: ${r} ${j(i)} \u2192 ${j(n)}`)}}function Fe(e,t,r,i,n){h(i)!==h(n)&&e.push(`${t}: ${r} changed`)}function F(e,t,r,i,n,s){if(_e(s)){W(e,t,r,i,n,s);return}Fe(e,t,r,i,n)}const Le={anchor:!1,"anchor-record":!1,apca:!1,boolean:!0,"data-palette-record":!1,explicit:!0,"fit-lint-id":!0,"lint-array":!1,message:!0,number:!0,"palette-lint-id":!0,"palette-lint-record":!1,"report-array":!1,scheme:!0,semantic:!0,"semantic-array":!1,"series-pair":!1,simulation:!0,string:!0,"string-array":!1,"token-array":!1,warning:!0};function _e(e){return Le[e]===!0}function j(e){return e===void 0?"(absent)":e===""?'""':String(e)}function L(e,t){return[...new Set([...e,...t])].sort()}function h(e){return Array.isArray(e)?`[${e.map(h).join(",")}]`:p(e)?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${h(e[t])}`).join(",")}}`:JSON.stringify(e)??"undefined"}function z(e){const t=m(e,$(k)),r=["light","dark"];if(y(k,"dataPalette")){const i=m(e.dataPalette,r);for(const n of r)l(i,n,m(e.dataPalette[n],w));l(t,"dataPalette",i)}if(y(k,"paletteLints")){const i=m(e.paletteLints,r);for(const n of r)l(i,n,q(e.paletteLints[n],g,$(M)));l(t,"paletteLints",i)}for(const i of r){if(!y(k,i))continue;const n=O();for(const s of e[i]){const o=m(s,$(_));if(y(_,"tokens")){const c=O();for(const a of s.tokens){const f=m(a,$(x));a.anchor&&y(x,"anchor")&&l(f,"anchor",m(a.anchor,$(C))),a.apca&&y(x,"apca")&&l(f,"apca",m(a.apca,$(N))),l(c,a.token,f)}l(o,"tokens",c)}y(_,"lints")&&l(o,"lints",q(s.lints,c=>c.id,$(R))),l(n,s.surface,o)}l(t,i,n)}return t}function q(e,t,r){const i=O();for(const n of e)l(i,t(n),m(n,r));return i}function $(e){return e.filter(({compared:t})=>t).map(({field:t})=>t)}function y(e,t){return e.some(r=>r.field===t&&r.compared)}function m(e,t){const r=new Set(t.map(String)),i=O();for(const[n,s]of Object.entries(e))r.has(n)||(i[n]=s);return i}function O(){return Object.create(null)}function l(e,t,r){Object.keys(r).length>0&&(e[t]=r)}function xe(e,t,r){for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.log(` ${i} lint(${n.id}): ${n.message}`);for(const n of e[i]){r.log(be(i,n));for(const s of n.lints)r.log(` lint(${s.id}): ${s.message}`)}}r.log(`Checked ${e.surfaces.length} surface(s) \xD7 2 schemes \u2014 `+(t===0?"no lints.":`${t} lint(s), listed above.`))}function we(e,t,r){r.error(`${t} theme lint(s) are standing while fit-table drift is present:`);for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.error(`lint: ${i}/paletteLints/${g(n)}: ${n.message}`);for(const n of e[i])for(const s of n.lints)r.error(`lint: ${i}/${n.surface}/lints/${s.id}: ${s.message}`)}}function Ae(e){return[...e.light,...e.dark].reduce((r,i)=>r+i.lints.length,0)+e.paletteLints.light.length+e.paletteLints.dark.length}function Ie(e,t){return["light","dark"].some(r=>{const i=`${r}: `;if(!e.startsWith(i))return!1;const n=e.slice(i.length);return t.paletteLints[r].some(s=>ee(n,s))})}function be(e,t){const r=t.adjustedTokens.length===0?"contrast enforcement moved nothing":`contrast enforcement moved ${t.adjustedTokens.join(", ")}`,i=t.tokens.filter(s=>s.explicit==="inherited").length,n=i===0?"":`; ${i} inherited explicit pin(s) \u2014 see the fit tables`;return`${e}/${t.surface}: ${t.tokens.length} tokens, ${r}${n}.`}export{Me as runEspalierCli};
|
package/dist/index.d.ts
CHANGED
|
@@ -73,10 +73,10 @@ export * from "./shared/events.js";
|
|
|
73
73
|
export { getImageDetails, releasePreviewUrl, type EspalierUploadImage, type ImageDetailsOptions, type SelectedUploadImage, type ExistingUploadImage, type ExistingImage, type ResponsiveImageUrl, type UploadCallbacks, type UploadEventDetail, } from "./image-upload/image-helpers.js";
|
|
74
74
|
export { calculatePhotoLayout, type LayoutImage, type PhotoRow, } from "./shared/justified-layout.js";
|
|
75
75
|
export { type TypeaheadFetchItems } from "./pickers/types.js";
|
|
76
|
-
export { type EspalierTheme, type LightnessKey, type LightnessReference, type PartialTheme, type PartialThemeContexts, type PartialThemeTones, type ThemeContext, type ThemeContexts, type ThemeTones, type ToneReference, type VariantColorSource, encodeTheme, parseTheme, mergePartials, layerThemes, validateThemePair, resolveContextTheme, buildTaprootLightTheme, buildTaprootDarkTheme, NESTED_THEME_KEYS, } from "./shared/theme.js";
|
|
77
|
-
export { auditDataPalette, generateSequentialRamp, generateDivergingRamp, COLOR_VISION_SIMULATIONS, DATA_SERIES_KEYS, DEFAULT_DATA_PALETTE, DEFAULT_DATA_RAMP_STEPS, DEFAULT_DIVERGING_NEUTRAL, MAX_DATA_RAMP_STEPS, MIN_DATA_COLOR_DISTANCE, MIN_DATA_RAMP_LIGHTNESS_STEP, MIN_DATA_RAMP_STEPS, type ColorVisionSimulation, type DataPalette, type DataPaletteIssue, type DataRamp, type DataRamps, type DataSeriesKey, type DivergingDataRamp, type DivergingRampOptions, type PartialDataRamp, type PartialDataRamps, type SequentialDataRamp, type SequentialRampOptions, } from "./shared/data-colors.js";
|
|
76
|
+
export { type EspalierTheme, type LightnessKey, type LightnessReference, type PartialTheme, type PartialThemeContexts, type PartialThemeTones, type ThemeContext, type ThemeContexts, type ThemeTones, type ToneReference, type VariantColorSource, encodeTheme, parseTheme, mergePartials, layerThemes, validateThemePair, resolveContextTheme, isObjectRecord, isSemanticColorName, buildTaprootLightTheme, buildTaprootDarkTheme, NESTED_THEME_KEYS, } from "./shared/theme.js";
|
|
77
|
+
export { auditDataPalette, describePaletteCollision, generateSequentialRamp, generateDivergingRamp, COLOR_VISION_SIMULATIONS, DATA_SERIES_KEYS, DEFAULT_DATA_PALETTE, DEFAULT_DATA_RAMP_STEPS, DEFAULT_DIVERGING_NEUTRAL, MAX_DATA_RAMP_STEPS, MIN_DATA_COLOR_DISTANCE, MIN_DATA_RAMP_LIGHTNESS_STEP, MIN_DATA_RAMP_STEPS, type ColorVisionSimulation, type DataPalette, type DataPaletteIssue, type DataRamp, type DataRamps, type DataSeriesKey, type DivergingDataRamp, type DivergingRampOptions, type PartialDataRamp, type PartialDataRamps, type SequentialDataRamp, type SequentialRampOptions, } from "./shared/data-colors.js";
|
|
78
78
|
export { WEIGHT_LABELS, extractWeights, normalizeWeight, bestAvailableWeight, extractFamily, getFallbackFont, } from "./shared/font-helpers.js";
|
|
79
79
|
export { getGoogleFonts } from "./font-picker/esp-font-picker.js";
|
|
80
|
-
export { ROOT_SURFACE, themeFitReport, themeFitRows, themeFitLints, themeFitReportSuite, printThemeFitReport, type ThemeFitReport, type ThemeFitReportOptions, type ThemeFitToken, type ThemeFitApcaAction, type ThemeFitAnchor, type ThemeFitRow, type ThemeFitLint, type ThemeFitSurfaceReport, type ThemeFitSuite, } from "./shared/theme-fit-report.js";
|
|
80
|
+
export { ROOT_SURFACE, THEME_FIT_ANCHOR_FIELDS, THEME_FIT_APCA_FIELDS, THEME_FIT_DATA_PALETTE_LINT_FIELDS, THEME_FIT_DATA_PALETTE_LINT_IDS, THEME_FIT_EXPLICIT_VALUES, THEME_FIT_LINT_FIELDS, THEME_FIT_LINT_IDS, THEME_FIT_LINT_SEVERITIES, THEME_FIT_REPORT_FIELDS, THEME_FIT_SUITE_FIELDS, THEME_FIT_TOKEN_FIELDS, themeFitReport, themeFitRows, themeFitLints, themeFitReportSuite, printThemeFitReport, type ThemeFitReport, type ThemeFitReportOptions, type ThemeFitToken, type ThemeFitApcaAction, type ThemeFitAnchor, type ThemeFitRow, type ThemeFitLint, type ThemeFitDataPaletteLint, type ThemeFitFieldDescriptor, type ThemeFitFieldKind, type ThemeFitSurfaceReport, type ThemeFitSuite, } from "./shared/theme-fit-report.js";
|
|
81
81
|
export { ICON_SPRITE, ICON_SPRITE_ID, installIconSprite } from "./icons/index.js";
|
|
82
82
|
export { deriveLightnessRamp, themeFromSwatches, type ThemeFromSwatchesOptions, type ThemeFromSwatchesResult, } from "./shared/theme-swatches.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as
|
|
1
|
+
export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as _o,DEFAULT_ICON_VIEW_BOX as Io,INTENT_VARIANTS as ao,normalizeIntentVariant as Ao,getIconHrefForHost as So,getIconSpriteUrl as io,getIconSpriteReference as Fo}from"./shared/intent-values.js";import{EspalierElementBase as Lo}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as so}from"./shared/validation.js";import{FormFieldController as No}from"./shared/form-field-controller.js";import{traverseToClosest as Po}from"./shared/utilities.js";import{showToast as Mo}from"./shared/toast-events.js";import{showFlyout as Ho,closeFlyout as co}from"./shared/flyout-events.js";import{requestHelp as Oo}from"./shared/help-events.js";import{getEspBus as uo}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as vo,releasePreviewUrl as Go}from"./image-upload/image-helpers.js";import{calculatePhotoLayout as yo}from"./shared/justified-layout.js";import{encodeTheme as Bo,parseTheme as Ko,mergePartials as Xo,layerThemes as Yo,validateThemePair as ko,resolveContextTheme as qo,isObjectRecord as zo,isSemanticColorName as jo,buildTaprootLightTheme as Jo,buildTaprootDarkTheme as Qo,NESTED_THEME_KEYS as Zo}from"./shared/theme.js";import{auditDataPalette as or,describePaletteCollision as rr,generateSequentialRamp as er,generateDivergingRamp as tr,COLOR_VISION_SIMULATIONS as mr,DATA_SERIES_KEYS as pr,DEFAULT_DATA_PALETTE as xr,DEFAULT_DATA_RAMP_STEPS as Tr,DEFAULT_DIVERGING_NEUTRAL as fr,MAX_DATA_RAMP_STEPS as Er,MIN_DATA_COLOR_DISTANCE as _r,MIN_DATA_RAMP_LIGHTNESS_STEP as Ir,MIN_DATA_RAMP_STEPS as ar}from"./shared/data-colors.js";import{WEIGHT_LABELS as Sr,extractWeights as ir,normalizeWeight as Fr,bestAvailableWeight as lr,extractFamily as Lr,getFallbackFont as Dr}from"./shared/font-helpers.js";import{getGoogleFonts as Rr}from"./font-picker/esp-font-picker.js";import{ROOT_SURFACE as nr,THEME_FIT_ANCHOR_FIELDS as Pr,THEME_FIT_APCA_FIELDS as hr,THEME_FIT_DATA_PALETTE_LINT_FIELDS as Mr,THEME_FIT_DATA_PALETTE_LINT_IDS as gr,THEME_FIT_EXPLICIT_VALUES as Hr,THEME_FIT_LINT_FIELDS as cr,THEME_FIT_LINT_IDS as Cr,THEME_FIT_LINT_SEVERITIES as Or,THEME_FIT_REPORT_FIELDS as Ur,THEME_FIT_SUITE_FIELDS as ur,THEME_FIT_TOKEN_FIELDS as dr,themeFitReport as Vr,themeFitRows as br,themeFitLints as vr,themeFitReportSuite as Gr,printThemeFitReport as wr}from"./shared/theme-fit-report.js";import{ICON_SPRITE as Wr,ICON_SPRITE_ID as Br,installIconSprite as Kr}from"./icons/index.js";import{deriveLightnessRamp as Yr,themeFromSwatches as kr}from"./shared/theme-swatches.js";export{mr as COLOR_VISION_SIMULATIONS,pr as DATA_SERIES_KEYS,xr as DEFAULT_DATA_PALETTE,Tr as DEFAULT_DATA_RAMP_STEPS,fr as DEFAULT_DIVERGING_NEUTRAL,_o as DEFAULT_ICON_SPRITE_URL,Io as DEFAULT_ICON_VIEW_BOX,Lo as EspalierElementBase,No as FormFieldController,Wr as ICON_SPRITE,Br as ICON_SPRITE_ID,ao as INTENT_VARIANTS,Er as MAX_DATA_RAMP_STEPS,_r as MIN_DATA_COLOR_DISTANCE,Ir as MIN_DATA_RAMP_LIGHTNESS_STEP,ar as MIN_DATA_RAMP_STEPS,Zo as NESTED_THEME_KEYS,nr as ROOT_SURFACE,Pr as THEME_FIT_ANCHOR_FIELDS,hr as THEME_FIT_APCA_FIELDS,Mr as THEME_FIT_DATA_PALETTE_LINT_FIELDS,gr as THEME_FIT_DATA_PALETTE_LINT_IDS,Hr as THEME_FIT_EXPLICIT_VALUES,cr as THEME_FIT_LINT_FIELDS,Cr as THEME_FIT_LINT_IDS,Or as THEME_FIT_LINT_SEVERITIES,Ur as THEME_FIT_REPORT_FIELDS,ur as THEME_FIT_SUITE_FIELDS,dr as THEME_FIT_TOKEN_FIELDS,so as VALIDITY_CHANGED_EVENT,Sr as WEIGHT_LABELS,or as auditDataPalette,lr as bestAvailableWeight,Qo as buildTaprootDarkTheme,Jo as buildTaprootLightTheme,yo as calculatePhotoLayout,co as closeFlyout,Yr as deriveLightnessRamp,rr as describePaletteCollision,Bo as encodeTheme,Lr as extractFamily,ir as extractWeights,tr as generateDivergingRamp,er as generateSequentialRamp,uo as getEspBus,Dr as getFallbackFont,Rr as getGoogleFonts,So as getIconHrefForHost,Fo as getIconSpriteReference,io as getIconSpriteUrl,vo as getImageDetails,Kr as installIconSprite,zo as isObjectRecord,jo as isSemanticColorName,Yo as layerThemes,Xo as mergePartials,Ao as normalizeIntentVariant,Fr as normalizeWeight,Ko as parseTheme,wr as printThemeFitReport,Go as releasePreviewUrl,Oo as requestHelp,qo as resolveContextTheme,Ho as showFlyout,Mo as showToast,vr as themeFitLints,Vr as themeFitReport,Gr as themeFitReportSuite,br as themeFitRows,kr as themeFromSwatches,Po as traverseToClosest,ko as validateThemePair};
|
|
@@ -44,6 +44,20 @@ export interface DataPaletteIssue {
|
|
|
44
44
|
/** The threshold the pair was checked against. */
|
|
45
45
|
threshold: number;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Describe one categorical-palette collision in the shared validation
|
|
49
|
+
* vocabulary. Runtime validation and fit-table lints both use this formatter;
|
|
50
|
+
* the co-located matcher below deliberately ignores numeric measurements while
|
|
51
|
+
* preserving the pair and simulation identity.
|
|
52
|
+
*/
|
|
53
|
+
export declare function describePaletteCollision(issue: DataPaletteIssue): string;
|
|
54
|
+
/**
|
|
55
|
+
* Match a formatted collision by its stable pair and simulation, deliberately
|
|
56
|
+
* ignoring the displayed measurement. Validation audits authored colors while
|
|
57
|
+
* fit tables audit emitted gamut-mapped colors, so their rounded distances can
|
|
58
|
+
* differ without representing two findings.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isPaletteCollisionDescription(description: string, issue: Pick<DataPaletteIssue, "series" | "simulation">): boolean;
|
|
47
61
|
/**
|
|
48
62
|
* Audit every categorical pair after full CVD simulation.
|
|
49
63
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{clampChannel as
|
|
1
|
+
import{clampChannel as N,gamutMapToSRGB as m,linearRgbToOklab as E,oklabToOklch as $,oklchToOklab as f,oklchToSRGB as O,parseCssColor as k,serializeOklch as b,srgbToLinearRGB as F}from"./color-engine.js";const p=["series1","series2","series3","series4","series5","series6","series7","series8"],G={series1:"#000000",series2:"#E69F00",series3:"#56B4E9",series4:"#009E73",series5:"#F0E442",series6:"#0072B2",series7:"#D55E00",series8:"#CC79A7"},S=["deuteranopia","protanopia","tritanopia"],A=.07;function U(t){return`dataPalette.${t.series[0]} and dataPalette.${t.series[1]} are only ${t.distance.toFixed(4)} apart under ${t.simulation} simulation (minimum ${t.threshold.toFixed(4)}); also distinguish the series with labels, shapes, or patterns.`}function B(t,e){return t.startsWith(`dataPalette.${e.series[0]} and dataPalette.${e.series[1]} are only `)&&t.includes(` apart under ${e.simulation} simulation `)}const T={protanopia:[[.152286,1.052583,-.204868],[.114503,.786281,.099216],[-.003882,-.048116,1.051998]],deuteranopia:[[.367322,.860646,-.227968],[.280085,.672501,.047413],[-.01182,.04294,.968881]],tritanopia:[[1.255528,-.076749,-.178779],[-.078411,.930809,.147602],[.004733,.691367,.3039]]};function _(t,e){const s=O(m(t)),o=F(s),n=a=>N(a[0]*o.r+a[1]*o.g+a[2]*o.b);return{r:n(e[0]),g:n(e[1]),b:n(e[2])}}function R(t,e){return Math.hypot(t.L-e.L,t.a-e.a,t.b-e.b)}function g(t,e){const s=k(t);if(!s)throw new TypeError(`${e} is not a valid opaque CSS color: "${t}".`);return s}function V(t,e=A){if(!Number.isFinite(e)||e<0)throw new RangeError("Data-palette distance threshold must be a finite number \u2265 0.");const s=new Map;for(const n of p)s.set(n,g(t[n],`dataPalette.${n}`));const o=[];for(const n of S){const a=new Map;for(const r of p)a.set(r,E(_(s.get(r),T[n])));for(let r=0;r<p.length;r+=1)for(let i=r+1;i<p.length;i+=1){const c=p[r],l=p[i],u=R(a.get(c),a.get(l));u<e&&o.push({series:[c,l],simulation:n,distance:u,threshold:e})}}return o}const y=[[1,0,0],[0,1,0],[0,0,1]];function z(t,e=A,s=["normal",...S]){if(!Number.isFinite(e)||e<0)throw new RangeError("Color distance threshold must be a finite number \u2265 0.");const o=t.map(([r,i])=>[r,g(i,r)]),n=[],a=s.map(r=>[r,r==="normal"?y:T[r]]);for(const[r,i]of a){const c=o.map(([,l])=>E(_(l,i)));for(let l=0;l<t.length;l+=1)for(let u=l+1;u<t.length;u+=1){const d=R(c[l],c[u]);d<e&&n.push({pair:[t[l][0],t[u][0]],simulation:r,distance:d,threshold:e})}}return n}const D=3,I=11,L=7,C=1e-6,q="oklch(0.96 0 0)";function w(t,e){if(!Number.isInteger(t)||t<D||t>I)throw new RangeError(`Data-ramp steps must be an integer from ${D} through ${I}.`);if(e&&t%2===0)throw new RangeError("Diverging data-ramp steps must be odd so the neutral is the midpoint.")}function M(t,e){if(!Number.isFinite(t)||t<0||t>1)throw new RangeError(`${e} must be a finite number from 0 through 1.`)}function X(t,e={}){const s=g(t,"Sequential ramp source"),o=e.steps??L,n=e.lightnessStart??.95,a=e.lightnessEnd??.25;if(w(o,!1),M(n,"Sequential ramp lightnessStart"),M(a,"Sequential ramp lightnessEnd"),n<=a)throw new RangeError("Sequential ramp lightnessStart must be greater than lightnessEnd.");if((n-a)/(o-1)<=C)throw new RangeError(`Sequential ramp lightness bounds must leave more than ${C} lightness between serialized stops.`);return Array.from({length:o},(r,i)=>{const c=i/(o-1),l=n+(a-n)*c;return b(m({l,c:s.c,h:s.h}))})}function x(t,e,s){return{L:t.L+(e.L-t.L)*s,a:t.a+(e.a-t.a)*s,b:t.b+(e.b-t.b)*s}}function H(t,e,s={}){const o=g(t,"Diverging ramp start"),n=g(e,"Diverging ramp end"),a=g(s.neutral??q,"Diverging ramp neutral"),r=s.steps??L;w(r,!0);const i=(r-1)/2,c=f(o),l=f(a),u=f(n);return Array.from({length:r},(d,h)=>{if(h===i)return b(m(a));const P=h<i?x(c,l,h/i):x(l,u,(h-i)/i);return b(m($(P)))})}export{S as COLOR_VISION_SIMULATIONS,p as DATA_SERIES_KEYS,G as DEFAULT_DATA_PALETTE,L as DEFAULT_DATA_RAMP_STEPS,q as DEFAULT_DIVERGING_NEUTRAL,I as MAX_DATA_RAMP_STEPS,A as MIN_DATA_COLOR_DISTANCE,C as MIN_DATA_RAMP_LIGHTNESS_STEP,D as MIN_DATA_RAMP_STEPS,z as auditColorDistances,V as auditDataPalette,U as describePaletteCollision,H as generateDivergingRamp,X as generateSequentialRamp,B as isPaletteCollisionDescription};
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
* report.adjustedTokens; // ['linkHover']
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
|
+
import { type ColorVisionSimulation, type DataPalette, type DataSeriesKey } from "./data-colors.js";
|
|
51
52
|
import { type EspalierTheme, type LightnessReference, type MappingSource, type PartialTheme, type SemanticColorName } from "./theme.js";
|
|
52
53
|
/** What APCA enforcement did to one token. */
|
|
53
54
|
export interface ThemeFitApcaAction {
|
|
@@ -193,6 +194,51 @@ export interface ThemeFitLint {
|
|
|
193
194
|
/** Human-readable finding, with the remedy phrased as a retune. */
|
|
194
195
|
message: string;
|
|
195
196
|
}
|
|
197
|
+
/** One scheme-level categorical-palette collision. */
|
|
198
|
+
export interface ThemeFitDataPaletteLint {
|
|
199
|
+
/** Stable lint identifier. */
|
|
200
|
+
id: "data-palette-cvd-collision";
|
|
201
|
+
/** The metric is advisory, but the named theme-check lint is gated. */
|
|
202
|
+
severity: "warning";
|
|
203
|
+
/** The two stable palette slots whose simulated colors are too close. */
|
|
204
|
+
series: readonly [DataSeriesKey, DataSeriesKey];
|
|
205
|
+
/** The simulated color-vision deficiency under which they collide. */
|
|
206
|
+
simulation: ColorVisionSimulation;
|
|
207
|
+
/** The measured OKLab distance, rounded for stable JSON. */
|
|
208
|
+
measured: number;
|
|
209
|
+
/** The minimum distance the pair was checked against. */
|
|
210
|
+
threshold: number;
|
|
211
|
+
/** Human-readable finding with the redundant-coding remedy. */
|
|
212
|
+
message: string;
|
|
213
|
+
}
|
|
214
|
+
/** 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";
|
|
216
|
+
/** One runtime field descriptor used by fit-suite validation and comparison. */
|
|
217
|
+
export interface ThemeFitFieldDescriptor<Field extends PropertyKey = PropertyKey> {
|
|
218
|
+
readonly field: Field;
|
|
219
|
+
readonly kind: ThemeFitFieldKind;
|
|
220
|
+
/** Whether drift is already reported by comparison, validation, or an identity key. */
|
|
221
|
+
readonly compared: boolean;
|
|
222
|
+
}
|
|
223
|
+
/** Every stable surface-lint id, exhaustively checked against {@link ThemeFitLint}. */
|
|
224
|
+
export declare const THEME_FIT_LINT_IDS: readonly ThemeFitLint["id"][];
|
|
225
|
+
/** Every stable palette-lint id, exhaustively checked against the lint interface. */
|
|
226
|
+
export declare const THEME_FIT_DATA_PALETTE_LINT_IDS: readonly ThemeFitDataPaletteLint["id"][];
|
|
227
|
+
/** Every stable explicit-pin provenance value. */
|
|
228
|
+
export declare const THEME_FIT_EXPLICIT_VALUES: readonly NonNullable<ThemeFitToken["explicit"]>[];
|
|
229
|
+
type ThemeFitLintSeverity = ThemeFitLint["severity"] | ThemeFitDataPaletteLint["severity"];
|
|
230
|
+
/** Every stable fit-suite lint severity. */
|
|
231
|
+
export declare const THEME_FIT_LINT_SEVERITIES: readonly ThemeFitLintSeverity[];
|
|
232
|
+
/** Runtime schema for every token field; adding an interface field requires a descriptor. */
|
|
233
|
+
export declare const THEME_FIT_TOKEN_FIELDS: readonly ThemeFitFieldDescriptor<keyof ThemeFitToken>[];
|
|
234
|
+
/** Runtime schema for every anchor-detail field. */
|
|
235
|
+
export declare const THEME_FIT_ANCHOR_FIELDS: readonly ThemeFitFieldDescriptor<keyof ThemeFitAnchor>[];
|
|
236
|
+
/** Runtime schema for every APCA-detail field. */
|
|
237
|
+
export declare const THEME_FIT_APCA_FIELDS: readonly ThemeFitFieldDescriptor<keyof ThemeFitApcaAction>[];
|
|
238
|
+
/** Runtime schema for every surface-lint field. */
|
|
239
|
+
export declare const THEME_FIT_LINT_FIELDS: readonly ThemeFitFieldDescriptor<keyof ThemeFitLint>[];
|
|
240
|
+
/** Runtime schema for every categorical-palette lint field. */
|
|
241
|
+
export declare const THEME_FIT_DATA_PALETTE_LINT_FIELDS: readonly ThemeFitFieldDescriptor<keyof ThemeFitDataPaletteLint>[];
|
|
196
242
|
/**
|
|
197
243
|
* Cross-token lints over one surface's report (ESP0175).
|
|
198
244
|
*
|
|
@@ -232,11 +278,19 @@ export interface ThemeFitSurfaceReport extends ThemeFitReport {
|
|
|
232
278
|
export interface ThemeFitSuite {
|
|
233
279
|
/** Surface names in report order: {@link ROOT_SURFACE}, then contexts, sorted. */
|
|
234
280
|
surfaces: string[];
|
|
281
|
+
/** Fully resolved categorical slots, once per scheme rather than per context. */
|
|
282
|
+
dataPalette: Record<"light" | "dark", DataPalette>;
|
|
283
|
+
/** Scheme-level CVD findings over {@link dataPalette}. */
|
|
284
|
+
paletteLints: Record<"light" | "dark", ThemeFitDataPaletteLint[]>;
|
|
235
285
|
/** One report per surface the light theme defines. */
|
|
236
286
|
light: ThemeFitSurfaceReport[];
|
|
237
287
|
/** One report per surface the dark theme defines. */
|
|
238
288
|
dark: ThemeFitSurfaceReport[];
|
|
239
289
|
}
|
|
290
|
+
/** Runtime schema for every surface-report field. */
|
|
291
|
+
export declare const THEME_FIT_REPORT_FIELDS: readonly ThemeFitFieldDescriptor<keyof ThemeFitSurfaceReport>[];
|
|
292
|
+
/** Runtime schema for every fit-suite field. */
|
|
293
|
+
export declare const THEME_FIT_SUITE_FIELDS: readonly ThemeFitFieldDescriptor<keyof ThemeFitSuite>[];
|
|
240
294
|
/**
|
|
241
295
|
* Fit-report every surface a themed site has (ESP0175): for each scheme,
|
|
242
296
|
* the root plus every declared context, each with its cross-token lints.
|
|
@@ -248,5 +302,10 @@ export interface ThemeFitSuite {
|
|
|
248
302
|
* schemes' context names so an asymmetric pair still reports every
|
|
249
303
|
* surface it can; `validateThemePair` is the gate that rejects the
|
|
250
304
|
* asymmetry itself.
|
|
305
|
+
*
|
|
306
|
+
* @throws When a merged scheme emits no root properties (for example, its
|
|
307
|
+
* seed color is unparseable), because the required palette snapshot cannot be
|
|
308
|
+
* produced. {@link themeFitReport} retains its narrower empty-report behavior.
|
|
251
309
|
*/
|
|
252
310
|
export declare function themeFitReportSuite(lightPartial: PartialTheme, darkPartial: PartialTheme): ThemeFitSuite;
|
|
311
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{apcaContrast as
|
|
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};
|
package/dist/shared/theme.d.ts
CHANGED
|
@@ -582,6 +582,8 @@ type TokenPairing = Readonly<{
|
|
|
582
582
|
export declare const TOKEN_PAIRINGS: Readonly<Record<"actionText", TokenPairing> & Partial<Record<SemanticColorName, TokenPairing>>>;
|
|
583
583
|
/** Ordered list of all semantic color token names. */
|
|
584
584
|
export declare const SEMANTIC_COLOR_NAMES: readonly SemanticColorName[];
|
|
585
|
+
/** `true` when `value` is one of the stable semantic color token names. */
|
|
586
|
+
export declare function isSemanticColorName(value: unknown): value is SemanticColorName;
|
|
585
587
|
/** Valid color-source identifiers for {@link SemanticMapping.source}. */
|
|
586
588
|
export declare const COLOR_SOURCES: readonly ColorSource[];
|
|
587
589
|
/** The four fixed status families, matching {@link StatusColorSource}. */
|
|
@@ -685,6 +687,8 @@ export declare function parseTheme(base64: string): PartialTheme | null;
|
|
|
685
687
|
* @returns A Base64-encoded JSON string.
|
|
686
688
|
*/
|
|
687
689
|
export declare function encodeTheme(partial: PartialTheme): string;
|
|
690
|
+
/** True for an ordinary record whose entries can be merged by key. */
|
|
691
|
+
export declare function isObjectRecord(value: unknown): value is Record<string, unknown>;
|
|
688
692
|
/**
|
|
689
693
|
* Recover explicit mapping provenance from a resolved theme.
|
|
690
694
|
*
|
package/dist/shared/theme.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{UNSAFE_KEYS as lt,isSafeKey as M}from"./unsafe-keys.js";import{ACCEPTED_COLOR_FORMS as oe,apcaContrast as pt,clampChannel as ge,deltaEOK as dt,deriveSemantic as ae,gamutMapToSRGB as he,linearRgbToOklab as mt,oklchToSRGB as gt,parseCssColor as W,parseOklch as ht,serializeOklch as ce,srgbToLinearRGB as yt}from"./color-engine.js";import{computeVariants as ye,parseAnchorSource as bt,resolveAnchorColor as $t,resolveMappingSource as ue}from"./variant-engine.js";import{auditColorDistances as Fe,auditDataPalette as xt,DATA_SERIES_KEYS as fe,DEFAULT_DATA_PALETTE as be,DEFAULT_DATA_RAMP_STEPS as kt,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 bt(e)}function je(e,n){return $t(e,n)}function St(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"]]}},At=new Set(["action.color"]),Mt={canvas:"background",ink:"text",accent:"link",action:"actionBackground",structure:"border"},Ot={"action.ink":{role:"canvas",slot:"color"}},Tt=.45,Ct=.045;function ze(e,n,t){const o=Ue.actionText,i=[...K].sort((y,T)=>e[y]-e[T]||K.indexOf(y)-K.indexOf(T)),a=n?i.filter(y=>n(y)>=o.targetLc):i,u=t?a.filter(y=>t(y)>=Ct):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]-Tt);T<k&&(k=T,A=y)}return A??"muted"}function Rt(e,n,t){const o=Oe(n,t,e)>.5;let i=K[0];for(const a of K)(o?n[a]<n[i]:n[a]>n[i])&&(i=a);return i}const vt={"accent.hover":"text"};function wt(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=st(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=Ot[`${u}.${m}`];let y=X(d,m),T=!1;if(y===void 0){k&&(y=X(e[k.role],k.slot),y??=t[Mt[k.role]]?.source,T=y!==void 0);const _=vt[`${u}.${m}`];_!==void 0&&(y??=X(d,_)),y??=X(d,"color")}if(y!==void 0)for(const[_,z]of A){let N=z;if(At.has(`${u}.${m}`))N=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);N=Rt(r,n,o.tones??{})}i[_]={source:y,lightness:N}}}}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}},G=["background","layer1","layer2","layer3","layer4","actionBackground","actionText","border","shadow","text","typeOverline","typeLabel","typeLead","typeCaption","dangerText","headings","headingsHover","link","linkHover","linkHoverBg","inputCaret","inputSelection","inputSelectionBg"],Et=["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"],Bt=["analogous-left","analogous-right","complementary","split-complementary-left","split-complementary-right","triadic-left","triadic-right","danger","success","warning","info"],K=["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:K.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 _t={surface:.99,raised1:.97,raised2:.9,raised3:.8,raised4:.72,accent:.5,muted:.45,text:.35,border:.3,ink:.25,shadow:.2},Lt={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 G)e[n]={min:0,max:Y};return e}const Ve={seedColor:"oklch(0.7 0.125 216)",fontBody:"",fontHeadings:"",fontBrand:"",fontMonospace:"",fontWeightBody:"normal",fontWeightHeadings:"bold",fontWeightBrand:"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={...Ve,chroma:Ce(),semanticMappings:{...Te},anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...be},dataRamps:{},lightness:{..._t}},Je={...Ve,chroma:Ce(),semanticMappings:{...Te},anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...be},dataRamps:{},lightness:{...Lt}},le=new WeakMap;le.set(Re,new Set),le.set(Je,new Set);function It(e,n){return lt.has(e)?void 0:n}function pe(e){const n=e.explicitMappingTokens;if(!Array.isArray(n)||n.some(o=>typeof o!="string"||!G.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 Ye(e){return G.filter(n=>e.has(n))}function sn(e){return`--esp-color-${e.replace(/([A-Z])/g,"-$1").replace(/(\d)/g,"-$1").toLowerCase()}`}function Ht(e){try{const n=qe(e),t=JSON.parse(n,It);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}const ve="\xEF\xBB\xBF";function Nt(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 qe(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 we(e){return Nt(JSON.stringify(e))}function Pt(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(ht(e))return e;const n=W(e);return n?ce(n):e}function Xe(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 Ee(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 Dt(e,n){return{...Ee(e),...Ee(n)}}function Ft(e,n){const t={...e};if(!L(n))return t;for(const o of K){const i=n[o];typeof i=="number"&&Number.isFinite(i)&&i>=0&&i<=1&&(t[o]=i)}return t}function Ze(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 K){const a=n.lightness[i];a!==void 0&&(o[i]=a)}t.lightness=o}if(n.tones!==void 0){const o=Ee(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)||!G.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 Wt(e,n){const t={};for(const[o,i]of Object.entries(e)){if(!M(o)||!j.test(o))continue;const a=Ze(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=Ze(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 Qe(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 jt(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&(t[o]=Qe(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]=Qe(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 zt(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 Kt(e){const n={};for(const t of fe)n[t]=ie(e[t]);return n}function et(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 Ut(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 tt(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(pt(m,d))}}function Gt(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 nt(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 dt(y,u)}}function Vt(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:tt(e),actionSurfaceSeparation:nt(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=Wt(e.contexts,n.contexts),i=Ft(e.lightness,n.lightness),a=Dt(e.tones,n.tones),u=zt(Xe(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=Pt({...e.intents,...n.intents}),_=n.chroma,z=ne(e.chroma,_),N=Kt(ne(e.dataPalette,n.dataPalette)),s=Ut(et(e.dataRamps,n.dataRamps)),r=Vt(e),c=new Set(r),f=pe(n),p={};for(const x of r)p[x]=e.semanticMappings[x];for(const[x,O]of Object.entries(m??{}))O!==void 0&&(f===void 0||f.has(x)?(c.add(x),p[x]=O):(c.delete(x),delete p[x]));const g=ne(e.semanticMappings,m),l={angles:A,anchors:u,chroma:z,intents:T,lightness:i,tones:a,seedColor:d,semanticHues:k,variantChroma:y},h=tt(l),$=nt(l,Gt(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 Et)!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 E=ne(ne(ne(e.semanticMappings,C),R),m),S={...e,seedColor:d,fontBody:n.fontBody??e.fontBody,fontHeadings:n.fontHeadings??e.fontHeadings,fontBrand:n.fontBrand??e.fontBrand,fontMonospace:n.fontMonospace??e.fontMonospace,fontWeightBody:String(n.fontWeightBody??e.fontWeightBody),fontWeightHeadings:String(n.fontWeightHeadings??e.fontWeightHeadings),fontWeightBrand:String(n.fontWeightBrand??e.fontWeightBrand),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:E,explicitMappingTokens:Ye(c),anchors:u,roles:t,contexts:o,dataPalette:N,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 ot=new WeakMap;function st(e,n){const t=e.contexts&&Object.prototype.hasOwnProperty.call(e.contexts,n)?e.contexts[n]:void 0;if(!t)return null;let o=ot.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,ot.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=qe(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 rn(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","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","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 Bt)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 f of Object.keys(c))(!M(f)||!te(f))&&t.push(`${r}.${f} is not a built-in lightness stop; expected one of: ${K.join(", ")}.`);for(const f of K)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(!L(s))return t.push(`${r} must be an object.`),c;for(const[f,p]of Object.entries(s)){if(!M(f)||!j.test(f)){t.push(`${r}.${f} must be a lowercase slug matching ${j.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 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=wt(e,n);for(const c of G)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>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[f,p]of Object.entries(c))M(f)?f!=="color"&&!j.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 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 f=[...k.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=k.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 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,f=c.steps??kt;if((typeof f!="number"||!Number.isInteger(f)||f<xe||f>$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[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>=xe&&f<=$e&&(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.`):_(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 f of fe){const p=St(s.dataPalette[f],s.anchors);if(!p){c=!1;break}r[f]=p}if(c)for(const f of xt(r))o.push(`dataPalette.${f.series[0]} and dataPalette.${f.series[1]} are only ${f.distance.toFixed(4)} apart under ${f.simulation} simulation (minimum ${f.threshold.toFixed(4)}); also distinguish the series with labels, shapes, or patterns.`)}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[f,p]of Object.entries(c)){const g=`${r}.${f}`;if(!se.includes(f)){t.push(`${g} is not a role; expected one of: ${se.join(", ")}. (The status family is reserved and is not a role.)`);continue}const l=f,h=Se[l];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(E=>E!=="color");t.push(`${g}.${b} is not a slot of the ${l} 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,f=Object.fromEntries(Object.entries(c).filter(([g])=>g!=="lightness"&&g!=="tones"&&g!=="semanticMappings"));z(f,`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&&N(c.semanticMappings,`contexts.${s}.semanticMappings`,p)}function N(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))G.includes(p)||t.push(`${r}.${p} is not a semantic token; expected one of: ${G.join(", ")}.`);for(const p of G)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.`):T(l.source,`${r}.${p}.source`),typeof l.lightness!="string")t.push(`${r}.${p}.lightness must be one of: ${K.join(", ")}, or a declared tone:<name>.`);else if(!te(l.lightness)){const h=Me(l.lightness);if(h===null)t.push(`${r}.${p}.lightness must be one of: ${K.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&&N(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"||!G.includes(c)){t.push(`explicitMappingTokens entries must be one of: ${G.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(...Jt(e,n)),{valid:t.length===0,errors:t,warnings:o}}const B=.045;function Jt(e,n){try{return Yt(e,n)}catch{return[]}}function Yt(e,n){const t=de(n,e),o=at(t),i=[...o],a=new Set(o);for(const u of Object.keys(t.contexts)){const d=st(t,u);if(d)for(const m of at(d))a.has(m)||i.push(`contexts.${u}: ${m}`)}return i}function qt(e){const n=gt(he(e)),t=yt(n);return mt({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 rt(e){return(Math.floor(e*1e4)/1e4).toFixed(4)}const Q=2,it=1e-4;function at(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=(l,h,$,b)=>he(ae(l,h,$,b)),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=ue(o.source,t,e.anchors);l&&d.push({name:"action",base:l})}const A=Fe(d.map(({name:l,base:h})=>[l,ce(u(h,a,i.min,i.max))]),B,["normal"]);if(A.length===0)return m;const k=new Map,y=(l,h)=>{const $=`${l}:${h}`;let b=k.get($);if(!b){b=[];for(let R=0;R<360;R+=Q)b.push(q({l,c:h,h:R}));k.set($,b)}return b},T=B-.002,_=(l,h,$,b)=>{const R=Math.hypot(l.a,l.b),C=Math.atan2(l.b,l.a)*180/Math.PI+180;let E=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}),l);if(O>=B)return O;const D=y(h,S);for(let w=0;w<D.length;w+=1){const v=Z(D[w],l);if(v>=B)return v;v>O&&(O=v,x=w*Q)}let P=x;for(let w=x-Q;w<=x+Q;w+=.1){const v=Z(q({l:h,c:S,h:w}),l);if(v>=B)return v;v>O&&(O=v,P=w)}if(O>=T)for(let w=P-.1;w<=P+.1;w+=.001){const v=Z(q({l:h,c:S,h:w}),l);if(v>=B)return v;v>O&&(O=v)}O>E&&(E=O)}return E},z=(l,h,$)=>{const b=h===$?[$]:[h,$];let R=0;for(const C of b)for(const E of b){if(C+E<B-1e-4)continue;const S=y(l,C),x=y(l,E);let O=0,D=0,P=-1;for(let H=0;H<S.length;H+=1)for(let U=0;U<x.length;U+=1){const V=Z(S[H],x[U]);if(V>=B)return V;V>P&&(P=V,O=H*Q,D=U*Q)}const w=(H,U,V,Le)=>{const Ie=[];for(let J=U-V;J<=U+V;J+=Le)Ie.push({h:J,lab:q({l,c:E,h:J})});let me=-1,He=H,Ne=U;for(let J=H-V;J<=H+V;J+=Le){const ft=q({l,c:C,h:J});for(const Pe of Ie){const De=Z(ft,Pe.lab);De>me&&(me=De,He=J,Ne=Pe.h)}}return{distance:me,hueA:He,hueB:Ne}},v=w(O,D,Q,.1);if(v.distance>=B)return v.distance;let I=Math.max(P,v.distance);if(I>=T){const H=w(v.hueA,v.hueB,.1,.001);if(H.distance>I&&(I=H.distance),I>=B)return I}I>R&&(R=I)}return R},N=l=>ee.includes(l),s=(l,h,$,b,R)=>{const C=q(u(l.base,$,b,R)),E=q(u(h.base,$,b,R));if(Z(C,E)>=B)return{outcome:"direct"};const S=N(l.name)&&N(h.name),x=[l,h].filter(P=>N(P.name)),O=S?"one of them":`"${N(l.name)?l.name:h.name}"`;let D;for(const P of x){const w=_(P===l?E:C,$,b,R);if(w>=B)return{outcome:"retune",target:O};w>=B-it&&(D=D??O)}if(S){const P=z($,b,R);if(P>=B)return{outcome:"retune",target:"both"};P>=B-it&&(D=D??"both")}return D!==void 0?{outcome:"near",target:D}:{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,ce(u(h,a,0,Y))]),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 A){const $=p.get(l[0]),b=p.get(l[1]),R=N($.name)&&N(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":`"${N($.name)?$.name:b.name}"`);f.has(c(l))?m.push(`Status colors "${l[0]}" and "${l[1]}" are hard to distinguish under normal vision (distance ${rt(h)} < ${B}); status meanings must stay distinguishable \u2014 retune ${I} via intents.`):m.push(`Status colors "${l[0]}" and "${l[1]}" are hard to distinguish as rendered (distance ${rt(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 E=s($,b,a,0,Y);let S={outcome:"no"};for(let I=1;I<=19&&S.outcome!=="direct";I+=1){const H=I*.05;if(Math.abs(H-a)<.001)continue;const U=s($,b,H,i.min,i.max);r(U)>r(S)&&(S=U)}let x={outcome:"no"};const O=E.outcome==="direct"||E.outcome==="retune",D=S.outcome==="direct"||S.outcome==="retune";if(!O&&!D)for(let I=1;I<=19&&x.outcome!=="direct";I+=1){const H=s($,b,I*.05,0,Y);r(H)>r(x)&&(x=H)}const P=Xt(E,S,x),w=`${C.outcome}|${P}`;let v=g.get(w);v||(v=[],g.set(w,v)),v.push(l)}for(const[l,h]of g){const $=l.indexOf("|"),b=l.slice(0,$),R=l.slice($+1),C=h.map(([x,O])=>`"${x}"/"${O}"`),E=C.length>1?`${C.slice(0,-1).join(", ")} and ${C[C.length-1]}`:C[0],S=b==="near"?`Status colors ${E} 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 ${E} 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 Xt(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 an(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,Je),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 Zt=["anchors","angles","contexts","dataPalette","dataRamps","intents","roles","chroma","lightness","tones","semanticHues","semanticMappings","variantChroma"];function Qt(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 Zt){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]=Xe(u,d);continue}if(a==="contexts"){t[a]=jt(u,d);continue}if(a==="dataRamps"){t[a]=et(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=>G.includes(u)));for(const u of Object.keys(n.semanticMappings??{}))i===void 0||i.has(u)?a.add(u):a.delete(u);t.explicitMappingTokens=Ye(a)}return t}function cn(...e){let n={};for(const t of e){if(!t)continue;const o=Ht(t);o&&(n=Qt(n,o))}return we(n)}function ct(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")}const ut={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 un(e){return we({...ut,pageBackgroundImage:`url("${ct(e)}")`,pageBackgroundImageOpacity:.5})}function fn(e){return we({...ut,pageBackgroundImage:`url("${ct(e)}")`,pageBackgroundImageOpacity:.55})}export{j as ANCHOR_SLUG_PATTERN,Ae as COLOR_SOURCES,Lt as DEFAULT_DARK_LIGHTNESS,Je as DEFAULT_DARK_THEME,_t as DEFAULT_LIGHT_LIGHTNESS,Re as DEFAULT_LIGHT_THEME,Te as DEFAULT_SEMANTIC_MAPPINGS,K as LIGHTNESS_KEYS,Zt as NESTED_THEME_KEYS,se as ROLE_NAMES,Ot as ROLE_PAIRED_INK,Se as ROLE_TOKEN_PLAN,G as SEMANTIC_COLOR_NAMES,ee as STATUS_COLOR_SOURCES,Ue as TOKEN_PAIRINGS,Bt as VARIANT_COLOR_SOURCES,fn as buildTaprootDarkTheme,un as buildTaprootLightTheme,Ke as compileRoles,we as encodeTheme,Vt as explicitMappingTokens,te as isLightnessKey,cn as layerThemes,Qt as mergePartials,de as mergeTheme,ke as parseAnchorSource,Ht as parseTheme,je as resolveAnchorColor,st as resolveContextTheme,St as resolveDataColorSource,Oe as resolveLightnessReference,sn as semanticToCSS,Me as toneReferenceName,rn as validateTheme,an as validateThemePair};
|
|
1
|
+
import{UNSAFE_KEYS as lt,isSafeKey as M}from"./unsafe-keys.js";import{ACCEPTED_COLOR_FORMS as oe,apcaContrast as pt,clampChannel as ge,deltaEOK as dt,deriveSemantic as ae,gamutMapToSRGB as he,linearRgbToOklab as mt,oklchToSRGB as gt,parseCssColor as W,parseOklch as ht,serializeOklch as ce,srgbToLinearRGB as yt}from"./color-engine.js";import{computeVariants as ye,parseAnchorSource as bt,resolveAnchorColor as $t,resolveMappingSource as ue}from"./variant-engine.js";import{auditColorDistances as Fe,auditDataPalette as xt,describePaletteCollision as kt,DATA_SERIES_KEYS as fe,DEFAULT_DATA_PALETTE as be,DEFAULT_DATA_RAMP_STEPS as St,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 bt(e)}function je(e,n){return $t(e,n)}function At(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"]]}},Mt=new Set(["action.color"]),Ot={canvas:"background",ink:"text",accent:"link",action:"actionBackground",structure:"border"},Tt={"action.ink":{role:"canvas",slot:"color"}},Ct=.45,Rt=.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)>=Rt):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]-Ct);T<k&&(k=T,A=y)}return A??"muted"}function vt(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 wt={"accent.hover":"text"};function Et(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=st(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=Tt[`${u}.${m}`];let y=X(d,m),T=!1;if(y===void 0){k&&(y=X(e[k.role],k.slot),y??=t[Ot[k.role]]?.source,T=y!==void 0);const _=wt[`${u}.${m}`];_!==void 0&&(y??=X(d,_)),y??=X(d,"color")}if(y!==void 0)for(const[_,z]of A){let H=z;if(Mt.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=vt(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 rn(e){return typeof e=="string"&&K.includes(e)}const Bt=["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"],_t=["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 Lt={surface:.99,raised1:.97,raised2:.9,raised3:.8,raised4:.72,accent:.5,muted:.45,text:.35,border:.3,ink:.25,shadow:.2},It={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={seedColor:"oklch(0.7 0.125 216)",fontBody:"",fontHeadings:"",fontBrand:"",fontMonospace:"",fontWeightBody:"normal",fontWeightHeadings:"bold",fontWeightBrand:"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={...Ve,chroma:Ce(),semanticMappings:{...Te},anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...be},dataRamps:{},lightness:{...Lt}},Je={...Ve,chroma:Ce(),semanticMappings:{...Te},anchors:{},roles:{},contexts:{},tones:{},dataPalette:{...be},dataRamps:{},lightness:{...It}},le=new WeakMap;le.set(Re,new Set),le.set(Je,new Set);function Nt(e,n){return lt.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 Ye(e){return K.filter(n=>e.has(n))}function an(e){return`--esp-color-${e.replace(/([A-Z])/g,"-$1").replace(/(\d)/g,"-$1").toLowerCase()}`}function Ht(e){try{const n=qe(e),t=JSON.parse(n,Nt);return typeof t!="object"||t===null||Array.isArray(t)?null:t}catch{return null}}const ve="\xEF\xBB\xBF";function Pt(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 qe(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 we(e){return Pt(JSON.stringify(e))}function Dt(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(ht(e))return e;const n=W(e);return n?ce(n):e}function Xe(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 Ee(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 Ft(e,n){return{...Ee(e),...Ee(n)}}function Wt(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 Ze(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=Ee(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 jt(e,n){const t={};for(const[o,i]of Object.entries(e)){if(!M(o)||!j.test(o))continue;const a=Ze(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=Ze(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 Qe(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 zt(e,n){const t={};for(const[o,i]of Object.entries(e))M(o)&&(t[o]=Qe(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]=Qe(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 Kt(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 Ut(e){const n={};for(const t of fe)n[t]=ie(e[t]);return n}function et(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 Gt(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 tt(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(pt(m,d))}}function Vt(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 nt(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 dt(y,u)}}function Jt(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:tt(e),actionSurfaceSeparation:nt(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=jt(e.contexts,n.contexts),i=Wt(e.lightness,n.lightness),a=Ft(e.tones,n.tones),u=Kt(Xe(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=Dt({...e.intents,...n.intents}),_=n.chroma,z=ne(e.chroma,_),H=Ut(ne(e.dataPalette,n.dataPalette)),s=Gt(et(e.dataRamps,n.dataRamps)),r=Jt(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,m),f={angles:A,anchors:u,chroma:z,intents:T,lightness:i,tones:a,seedColor:d,semanticHues:k,variantChroma:y},h=tt(f),$=nt(f,Vt(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 Bt)!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 E=ne(ne(ne(e.semanticMappings,C),R),m),S={...e,seedColor:d,fontBody:n.fontBody??e.fontBody,fontHeadings:n.fontHeadings??e.fontHeadings,fontBrand:n.fontBrand??e.fontBrand,fontMonospace:n.fontMonospace??e.fontMonospace,fontWeightBody:String(n.fontWeightBody??e.fontWeightBody),fontWeightHeadings:String(n.fontWeightHeadings??e.fontWeightHeadings),fontWeightBrand:String(n.fontWeightBrand??e.fontWeightBrand),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:E,explicitMappingTokens:Ye(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 ot=new WeakMap;function st(e,n){const t=e.contexts&&Object.prototype.hasOwnProperty.call(e.contexts,n)?e.contexts[n]:void 0;if(!t)return null;let o=ot.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,ot.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=qe(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 cn(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","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","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 _t)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=Et(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??St;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=At(s.dataPalette[l],s.anchors);if(!p){c=!1;break}r[l]=p}if(c)for(const l of xt(r))o.push(kt(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(E=>E!=="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(...Yt(e,n)),{valid:t.length===0,errors:t,warnings:o}}const B=.045;function Yt(e,n){try{return qt(e,n)}catch{return[]}}function qt(e,n){const t=de(n,e),o=at(t),i=[...o],a=new Set(o);for(const u of Object.keys(t.contexts)){const d=st(t,u);if(d)for(const m of at(d))a.has(m)||i.push(`contexts.${u}: ${m}`)}return i}function Xt(e){const n=gt(he(e)),t=yt(n);return mt({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 Xt(W(ce(he(e))))}function rt(e){return(Math.floor(e*1e4)/1e4).toFixed(4)}const Q=2,it=1e-4;function at(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 E=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 w=0;w<D.length;w+=1){const v=Z(D[w],f);if(v>=B)return v;v>O&&(O=v,x=w*Q)}let P=x;for(let w=x-Q;w<=x+Q;w+=.1){const v=Z(q({l:h,c:S,h:w}),f);if(v>=B)return v;v>O&&(O=v,P=w)}if(O>=T)for(let w=P-.1;w<=P+.1;w+=.001){const v=Z(q({l:h,c:S,h:w}),f);if(v>=B)return v;v>O&&(O=v)}O>E&&(E=O)}return E},z=(f,h,$)=>{const b=h===$?[$]:[h,$];let R=0;for(const C of b)for(const E of b){if(C+E<B-1e-4)continue;const S=y(f,C),x=y(f,E);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 w=(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:E,h:J})});let me=-1,Ne=N,He=G;for(let J=N-V;J<=N+V;J+=Le){const ft=q({l:f,c:C,h:J});for(const Pe of Ie){const De=Z(ft,Pe.lab);De>me&&(me=De,Ne=J,He=Pe.h)}}return{distance:me,hueA:Ne,hueB:He}},v=w(O,D,Q,.1);if(v.distance>=B)return v.distance;let I=Math.max(P,v.distance);if(I>=T){const N=w(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)),E=q(u(h.base,$,b,R));if(Z(C,E)>=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 w=_(P===f?E:C,$,b,R);if(w>=B)return{outcome:"retune",target:O};w>=B-it&&(D=D??O)}if(S){const P=z($,b,R);if(P>=B)return{outcome:"retune",target:"both"};P>=B-it&&(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 ${rt(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 ${rt(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 E=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=E.outcome==="direct"||E.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=Zt(E,S,x),w=`${C.outcome}|${P}`;let v=g.get(w);v||(v=[],g.set(w,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}"`),E=C.length>1?`${C.slice(0,-1).join(", ")} and ${C[C.length-1]}`:C[0],S=b==="near"?`Status colors ${E} 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 ${E} 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 Zt(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 un(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,Je),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 Qt=["anchors","angles","contexts","dataPalette","dataRamps","intents","roles","chroma","lightness","tones","semanticHues","semanticMappings","variantChroma"];function en(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 Qt){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]=Xe(u,d);continue}if(a==="contexts"){t[a]=zt(u,d);continue}if(a==="dataRamps"){t[a]=et(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=Ye(a)}return t}function fn(...e){let n={};for(const t of e){if(!t)continue;const o=Ht(t);o&&(n=en(n,o))}return we(n)}function ct(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")}const ut={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 ln(e){return we({...ut,pageBackgroundImage:`url("${ct(e)}")`,pageBackgroundImageOpacity:.5})}function pn(e){return we({...ut,pageBackgroundImage:`url("${ct(e)}")`,pageBackgroundImageOpacity:.55})}export{j as ANCHOR_SLUG_PATTERN,Ae as COLOR_SOURCES,It as DEFAULT_DARK_LIGHTNESS,Je as DEFAULT_DARK_THEME,Lt as DEFAULT_LIGHT_LIGHTNESS,Re as DEFAULT_LIGHT_THEME,Te as DEFAULT_SEMANTIC_MAPPINGS,U as LIGHTNESS_KEYS,Qt as NESTED_THEME_KEYS,se as ROLE_NAMES,Tt as ROLE_PAIRED_INK,Se as ROLE_TOKEN_PLAN,K as SEMANTIC_COLOR_NAMES,ee as STATUS_COLOR_SOURCES,Ue as TOKEN_PAIRINGS,_t as VARIANT_COLOR_SOURCES,pn as buildTaprootDarkTheme,ln as buildTaprootLightTheme,Ke as compileRoles,we as encodeTheme,Jt as explicitMappingTokens,te as isLightnessKey,L as isObjectRecord,rn as isSemanticColorName,fn as layerThemes,en as mergePartials,de as mergeTheme,ke as parseAnchorSource,Ht as parseTheme,je as resolveAnchorColor,st as resolveContextTheme,At as resolveDataColorSource,Oe as resolveLightnessReference,an as semanticToCSS,Me as toneReferenceName,cn as validateTheme,un as validateThemePair};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.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",
|