@apollion-dsi/tokens 4.4.0 → 4.5.1

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Framework-agnostic design tokens for Apollion Design System v4+.
4
4
 
5
- **Status:** ✅ **GA @ 4.2.0** — v4 epic shipped 2026-05-25 (ADR-006). Lockstep com `@apollion-dsi/core@4.2.0`.
5
+ **Status:** ✅ **GA desde 4.2.0** — v4 epic shipped 2026-05-25 (ADR-006). Atual **4.5.0**, lockstep com `@apollion-dsi/core@4.5.0`.
6
6
 
7
7
  ## Versioned API
8
8
 
package/lib/build.cjs CHANGED
@@ -1,6 +1,6 @@
1
- "use strict";var j=Object.defineProperty;var Ue=Object.getOwnPropertyDescriptor;var ze=Object.getOwnPropertyNames;var Xe=Object.prototype.hasOwnProperty;var s=(e,n)=>j(e,"name",{value:n,configurable:!0});var Ye=(e,n)=>{for(var o in n)j(e,o,{get:n[o],enumerable:!0})},qe=(e,n,o,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let i of ze(n))!Xe.call(e,i)&&i!==o&&j(e,i,{get:()=>n[i],enumerable:!(r=Ue(n,i))||r.enumerable});return e};var Ke=e=>qe(j({},"__esModule",{value:!0}),e);var wn={};Ye(wn,{build:()=>Sn,check:()=>xn});module.exports=Ke(wn);var f=require("node:fs/promises"),Je=require("node:os"),x=require("node:path");var C=require("@apollion-dsi/core/themes/border"),L=require("@apollion-dsi/core/themes/depth"),S=require("@apollion-dsi/core/themes/font"),z=require("@apollion-dsi/core/themes/spacing"),v=require("culori");var te=require("@apollion-dsi/core/themes/dimension");function M({multiplier:e=.25,alias:n},o){let r=o!==void 0?te.DIMENSION_MULTIPLIERS[o]:e;return(...i)=>i.map(t=>{let a=typeof t=="string"?n[t]:t;return`${r*a}rem`}).join(" ")}s(M,"createSpacing");var J={"bg.primary":{description:"Primary action surface \u2014 the brand\u2019s dominant call-to-action background."},"bg.secondary":{description:"Secondary action surface \u2014 supporting actions paired with the primary."},"bg.danger":{description:"Destructive / error surface \u2014 irreversible or failing actions."},"bg.success":{description:"Positive confirmation surface \u2014 completed or healthy states."},"bg.info":{description:"Informational surface \u2014 neutral, non-blocking notices.",deprecated:"Use bg.information once the foundation role is renamed (tracked for S6)."},"text.on-primary":{description:"Text/icon colour with guaranteed contrast over bg.primary."},"text.on-danger":{description:"Text/icon colour with guaranteed contrast over bg.danger."},"space.medium":{description:"Base spacing step (1rem at normal density) \u2014 the layout rhythm unit."},"space.large":{description:"Comfortable spacing step \u2014 section padding and card gutters."},"spacing.md":{description:"Medium foundation spacing alias \u2014 references the space.medium primitive."},"spacing.lg":{description:"Large foundation spacing alias \u2014 references the space.large primitive."},"border.radius.md":{description:"Default card corner radius."},"border.width.thin":{description:"Hairline border \u2014 dividers and default input outlines."},"border.width.regular":{description:"Standard emphasis border \u2014 focused/active controls."}};function U(e){let n=Object.keys(J).filter(o=>!e.has(o));if(n.length>0)throw new Error(`token-meta: ${n.length} stale TOKEN_META key(s) resolve to no IR node: ${n.join(", ")}. Update src/token-meta.ts to match the current IR paths.`)}s(U,"assertTokenMetaResolves");var Ze=(0,v.converter)("oklch");function h(e){return typeof e.type=="string"&&"value"in e}s(h,"isToken");function R(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}s(R,"kebab");function se(e){return e.split(".").map(R).join(".")}s(se,"kebabPath");function V(e){return e.kind==="ref"?e.resolved.raw:e.raw}s(V,"rawValue");function F(e,n){return Number(e.toFixed(n))||0}s(F,"round");function X(e){let n=Ze((0,v.parse)(e));if(!n)return{kind:"color",raw:e,components:[0,0,0],hex:"#000000"};let o=[F(n.l,4),F(n.c,4),F(n.h??0,2)],r=(0,v.formatHex)(n)??"#000000";return n.alpha!==void 0&&n.alpha!==1?{kind:"color",raw:e,components:o,alpha:F(n.alpha,4),hex:r}:{kind:"color",raw:e,components:o,hex:r}}s(X,"toColorValue");var ae=/^(-?(?:\d+\.?\d*|\.\d+))(px|rem)$/;function T(e){let n=ae.exec(e.trim());if(n)return{kind:"dimension",raw:e,value:Number(n[1]),unit:n[2]};let o=Number.parseFloat(e);return{kind:"dimension",raw:e,value:Number.isFinite(o)?o:0,unit:"rem"}}s(T,"toDimensionValue");function y(e){return{type:"color",value:X(e)}}s(y,"colorToken");function ie(e){let n={};for(let[o,r]of Object.entries(e))n[o]=y(r);return n}s(ie,"recordColorGroup");var Qe=["main","opposite","complementary","primary","secondary","tertiary","success","danger","warning","information"];function ce(e){let n={};for(let o of Qe){let r=e[o];n[o]={base:y(r.base),dark:y(r.dark),action:y(r.action),active:y(r.active),light:y(r.light)}}return n.grayscale=ie(e.grayscale),n.neutral=ie(e.neutral),n.baseDark=y(e.baseDark??"#000000"),n.baseLight=y(e.baseLight??"#ffffff"),n.deepDark=y(e.deepDark??"#000000"),n.deepLight=y(e.deepLight??"#ffffff"),n}s(ce,"buildColorPrimitives");function le(e){let n=M(z.defaultInputSpacing,e),o={};for(let r of Object.keys(z.defaultInputSpacing.alias))o[r]={type:"dimension",value:T(n(r))};return o}s(le,"buildSpacePrimitives");function de(){let e={};for(let[n,o]of Object.entries(C.defaultInputBorder.borderWidth))e[n]={type:"dimension",value:T(o)};return e}s(de,"buildBorderWidthPrimitives");function en(e,n){return{color:ce(e),space:le(n),borderWidth:de()}}s(en,"buildPrimitives");var ue={primary:"color.primary.base",secondary:"color.secondary.base",tertiary:"color.tertiary.base",success:"color.success.base",danger:"color.danger.base",warning:"color.warning.base",info:"color.information.base"},pe={onPrimary:"color.baseLight",onSecondary:"color.baseLight",onTertiary:"color.baseDark",onSuccess:"color.baseLight",onDanger:"color.baseLight",onWarning:"color.baseDark",onInfo:"color.baseLight"};function nn(e,n){let o=e;for(let r of n.split(".").slice(1))if(o&&typeof o=="object"&&r in o)o=o[r];else return;return typeof o=="string"?o:void 0}s(nn,"lookupPrimitive");function A(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=o[i],l=a?nn(n,a):void 0;r[i]=a&&l===t?{type:"color",value:{kind:"ref",path:a,resolved:X(t)}}:y(t)}return r}s(A,"colorRefGroup");var fe={xs:"space.xs",sm:"space.small",md:"space.medium",lg:"space.large",xl:"space.xl",xxl:"space.xxl"},on={none:"border-width.none",thin:"border-width.thin",regular:"border-width.regular",great:"border-width.great",bold:"border-width.bold"};function rn(e,n){let o=n.split("."),r=o[0]==="border-width"?"borderWidth":o[0],i=e[r];for(let t of o.slice(1))if(i&&!h(i)&&t in i)i=i[t];else return;return i&&h(i)&&i.value.kind==="dimension"?i.value.raw:void 0}s(rn,"lookupDimensionPrimitive");function Y(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=o[i],l=a?rn(n,a):void 0;r[i]=a&&l===t?{type:"dimension",value:{kind:"ref",path:a,resolved:T(t)}}:{type:"dimension",value:T(t)}}return r}s(Y,"dimensionRefGroup");function me(e){let n={},o={};for(let[t,a]of Object.entries(C.defaultInputBorder.borderRadius))ae.test(a)?n[t]={type:"dimension",value:T(a)}:o[t]=a;let r=Y(C.defaultInputBorder.borderWidth,e,on),i={};for(let[t,a]of Object.entries(C.defaultInputBorder.borderStyle))i[t]={type:"strokeStyle",value:{kind:"strokeStyle",raw:a,style:a}};return{group:{radius:n,width:r,style:i},extensions:o}}s(me,"buildBorder");function ge(){let e={};for(let[t,a]of Object.entries(S.defaultInputFont.fontFamily)){let l=a.replace(/;\s*$/,"").trim();e[t]={type:"fontFamily",value:{kind:"fontFamily",raw:l,family:l}}}let n={};for(let[t,a]of Object.entries(S.defaultInputFont.fontSize))n[t]={type:"dimension",value:{kind:"dimension",raw:`${a}px`,value:a,unit:"px"}};let o={};for(let[t,a]of Object.entries(S.defaultInputFont.fontWeight))o[t]={type:"fontWeight",value:{kind:"fontWeight",raw:`${a}`,weight:a}};let r={};for(let[t,a]of Object.entries(S.defaultInputFont.lineHeight))r[t]={type:"number",value:{kind:"number",raw:`${a}`,number:a}};let i={letterSpacing:S.defaultInputFont.letterSpacing,textTransform:S.defaultInputFont.textTransform,fontStyle:S.defaultInputFont.fontStyle};return{group:{family:e,size:n,weight:o,lineHeight:r},extensions:i}}s(ge,"buildFont");var tn=/rgba?\([^)]*\)|#[0-9a-fA-F]+|[a-zA-Z]+$/;function sn(e){let n=e.trim(),o=n.startsWith("inset");o&&(n=n.slice(5).trim());let r=n.match(tn),i=r?r[0]:"#000000",a=(r?n.slice(0,r.index).trim():n).split(/\s+/).filter(Boolean),l=s(m=>T(a[m]??"0px"),"dim");return{kind:"shadow",raw:e,shadow:{color:X(i),offsetX:l(0),offsetY:l(1),blur:l(2),spread:l(3),inset:o}}}s(sn,"parseShadow");function ye(e){let n=(0,L.createDeth)(e),o={};for(let r of Object.keys(L.levelValues))o[r]={type:"shadow",value:sn(n(r))};return o}s(ye,"buildShadow");function N(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=n?`${n}.${R(i)}`:R(i);if(h(t)){o.add(a);let l=J[a];r[i]=l&&(l.description!==void 0||l.deprecated!==void 0)?{...t,...l.description!==void 0?{description:l.description}:{},...l.deprecated!==void 0?{deprecated:l.deprecated}:{}}:t}else r[i]=N(t,a,o)}return r}s(N,"decorateGroup");function an(e){let n=new Set,o=N(e.primitives,"",n),r=N(e.groups,"",n);return U(n),{...e,primitives:o,groups:r}}s(an,"decorateMeta");function q(e,n){return N(e,"",n)}s(q,"decorateSlice");function he(e,n,o){for(let[r,i]of Object.entries(e)){let t=n?`${n}.${R(r)}`:R(r);h(i)?o.add(t):he(i,t,o)}}s(he,"collectPaths");function be(e){let n=new Set;for(let o of e)he(o.groups,"",n);U(n)}s(be,"assertSlicesMetaComplete");function Re(){let e=de(),o=me({borderWidth:e}),r=ge(),i={"com.apollion.font":r.extensions};Object.keys(o.extensions).length>0&&(i["com.apollion.border"]={radius:o.extensions});let t=new Set;return{groups:q({"border-width":e,border:o.group,font:r.group},t),extensions:i}}s(Re,"buildBaseIR");function Ie(e,n){let o=ce(n),r=new Set;return{groups:q({color:o,bg:A(e.bg,n,ue),text:A(e.text,n,pe),shadow:ye(n)},r),extensions:{}}}s(Ie,"buildColorIR");function ke(e,n){let o=le(n),r={space:o},i=new Set;return{groups:q({space:o,spacing:Y(e.spacing,r,fe)},i),extensions:{}}}s(ke,"buildSpacingIR");function cn(e,n,o){let r={brand:o.brand,mode:o.mode,surface:o.surface,dimension:o.dimension},i=en(n,o.dimension),t=me(i),a=ge(),l={"com.apollion.variant":r,"com.apollion.font":a.extensions};Object.keys(t.extensions).length>0&&(l["com.apollion.border"]={radius:t.extensions});let m={description:`Apollion DS tokens \u2014 DTCG 2025.10. Variant: ${r.brand}/${r.mode}/${r.surface}/${r.dimension}.`,meta:r,primitives:i,groups:{bg:A(e.bg,n,ue),text:A(e.text,n,pe),spacing:Y(e.spacing,i,fe),border:t.group,font:a.group,shadow:ye(n)},extensions:l};return an(m)}s(cn,"buildIR");var Se=cn;var ln="/* Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs. */";function xe(e,n,o){for(let[r,i]of Object.entries(e)){let t=[...n,R(r)];h(i)?o.push(` --apollion-${t.join("-")}: ${V(i.value)};`):xe(i,t,o)}}s(xe,"emitVars");function De(e,n,o){for(let[r,i]of Object.entries(e)){let t=[...n,R(r)];h(i)?i.type==="color"&&o.push(` @property --apollion-${t.join("-")} { syntax: '<color>'; inherits: true; initial-value: ${V(i.value)}; }`):De(i,t,o)}}s(De,"emitProperties");function we(e){let{brand:n,mode:o,surface:r,dimension:i}=e.meta,t=[ln,""];return t.push(`/* Variant: brand=${n} mode=${o} surface=${r} dimension=${i} */`,"",":root {"),xe(e.groups,[],t),t.push("}",""),t.push("@supports (background: paint(squircle)) or (color: oklch(0% 0 0)) {"),De(e.groups,[],t),t.push("}",""),t.join(`
2
- `)}s(we,"renderCss");function Te(e){return e.alpha!==void 0?{colorSpace:"oklch",components:[...e.components],alpha:e.alpha,hex:e.hex}:{colorSpace:"oklch",components:[...e.components],hex:e.hex}}s(Te,"colorValue");function $(e){return{value:e.value,unit:e.unit}}s($,"dimensionValue");function dn(e){let n=e.shadow,o={color:Te(n.color),offsetX:$(n.offsetX),offsetY:$(n.offsetY),blur:$(n.blur),spread:$(n.spread)};return n.inset&&(o.inset=!0),o}s(dn,"shadowValue");function un(e){switch(e.kind){case"ref":return`{${se(e.path)}}`;case"color":return Te(e);case"dimension":return $(e);case"fontFamily":return e.family;case"fontWeight":return e.weight;case"number":return e.number;case"strokeStyle":return e.style;case"shadow":return dn(e)}}s(un,"projectValue");function pn(e){let n={$value:un(e.value),$type:e.type};return e.description!==void 0&&(n.$description=e.description),e.deprecated!==void 0&&(n.$deprecated=e.deprecated),n}s(pn,"projectToken");function K(e){let n={};for(let[o,r]of Object.entries(e))n[R(o)]=h(r)?pn(r):K(r);return n}s(K,"projectGroup");function Z(e,n){let o={$description:n,...K(e.groups)};return Object.keys(e.extensions).length>0&&(o.$extensions=e.extensions),`${JSON.stringify(o,null,2)}
3
- `}s(Z,"renderSet");function ve(e){return Z(e,"Apollion DS \u2014 base set (axis-invariant: border + font). DTCG 2025.10.")}s(ve,"renderBaseSet");function Ce(e,n,o,r){return Z(e,`Apollion DS \u2014 colour set. brand=${n} mode=${o} surface=${r}. DTCG 2025.10.`)}s(Ce,"renderColorSet");function Ve(e,n){return Z(e,`Apollion DS \u2014 spacing set. dimension=${n}. DTCG 2025.10.`)}s(Ve,"renderSpacingSet");function $e(e,n){let{modifiers:o}=n,r=[{name:"brand",values:[...o.brand],default:o.brand[0]},{name:"mode",values:[...o.mode],default:o.mode[0]},{name:"surface",values:[...o.surface],default:o.surface[0]},{name:"dimension",values:[...o.dimension],default:o.dimension[0]}],t={name:"apollion-tokens",description:"Apollion DS token resolver \u2014 DTCG 2025.10. Compose the base set with the colour set for the chosen brand/mode/surface and the spacing set for the chosen dimension. NOTE: mode is a topology placeholder in this release (dark resolves identically to light until S6).",sets:[{name:n.base.name,source:n.base.file},...n.spacing.map(a=>({name:a.name,source:a.file})),...n.color.map(a=>({name:a.name,source:a.file}))],modifiers:r,$extensions:{"com.apollion.resolver":{composition:{always:[n.base.name],byModifier:{color:"${brand}.color.${mode}.${surface}",spacing:"spacing.${dimension}"}},modeIsPlaceholder:!0}}};return`${JSON.stringify(t,null,2)}
4
- `}s($e,"renderResolver");var fn="// Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs.";function Ge(e,n,o){let r=" ".repeat(n);for(let[i,t]of Object.entries(e))h(t)?o.push(`${r}${JSON.stringify(i)}: ${JSON.stringify(V(t.value))},`):(o.push(`${r}${i}: {`),Ge(t,n+1,o),o.push(`${r}},`))}s(Ge,"emitGroup");function Oe(e){let{brand:n,mode:o,surface:r,dimension:i}=e.meta,t=[fn,`// Variant: brand=${n} mode=${o} surface=${r} dimension=${i}`,"","export const tokens = {"];return Ge(e.groups,1,t),t.push("} as const;","","export type Tokens = typeof tokens;",""),t.join(`
5
- `)}s(Oe,"renderTs");var mn=["light","dark"],gn=["positive","negative"],yn=["compact","normal","spacious"];function P(e){let n=e.modes??mn,o=e.surfaces??gn,r=e.dimensions??yn,i=Object.entries(e.brands).sort(([a],[l])=>a.localeCompare(l)),t=[];for(let[a,l]of i)for(let m of n)for(let g of o)for(let d of r)t.push({brand:a,colors:l,mode:m,surface:g,dimension:d});return t}s(P,"expandVariants");function Ee(e){return`${e.brand}.${e.mode}.${e.surface}.${e.dimension}`}s(Ee,"variantName");var je=require("node:crypto");function ee(e){return(0,je.createHash)("sha256").update(e).digest("hex")}s(ee,"sha256");function ne(e){return ee(Q(e))}s(ne,"hashConfig");function Q(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(Q).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${Q(e[r])}`).join(",")}}`}s(Q,"stableStringify");function Me(e){try{let{execSync:n}=require("node:child_process");return n("git rev-parse --short HEAD",{cwd:e,stdio:["ignore","pipe","ignore"],encoding:"utf8"}).trim()}catch{return""}}s(Me,"detectGitCommit");function Fe(){return{node:process.version,platform:`${process.platform}-${process.arch}`}}s(Fe,"buildEnv");function Ae(e){let n=[...e.files].sort((r,i)=>r.path.localeCompare(i.path)),o={configHash:e.configHash,files:n,gitCommit:e.gitCommit,buildEnv:e.buildEnv};return`${JSON.stringify(o,null,2)}
6
- `}s(Ae,"serializeManifest");var hn="json/sets",Ne="json/resolver.json";function oe(e){return`${hn}/${e}.json`}s(oe,"setFile");function bn(e,n,o){return`${e}.color.${n}.${o}`}s(bn,"colorSetName");function Rn(e){return`spacing.${e}`}s(Rn,"spacingSetName");function B(e,n){e.includes(n)||e.push(n)}s(B,"pushUnique");function Le(e){let n=P(e),o=[],r=[],i=[],t=[],a=new Set,l=[],m=new Set,g=[];for(let d of n){B(o,d.brand),B(r,d.mode),B(i,d.surface),B(t,d.dimension);let D=bn(d.brand,d.mode,d.surface);a.has(D)||(a.add(D),l.push({kind:"color",name:D,file:oe(D),brand:d.brand,mode:d.mode,surface:d.surface}));let u=Rn(d.dimension);m.has(u)||(m.add(u),g.push({kind:"spacing",name:u,file:oe(u),dimension:d.dimension}))}return{base:{kind:"base",name:"base",file:oe("base")},spacing:g,color:l,modifiers:{brand:o,mode:r,surface:i,dimension:t}}}s(Le,"planSets");var re=require("@apollion-dsi/core/themes/foundation"),_e=require("@apollion-dsi/core/themes/semantic"),He=require("@apollion-dsi/core/themes/spacing"),We=require("@apollion-dsi/core/themes/surface");var k=require("culori");var eo=(0,k.converter)("oklch");function c(e,n,o){let r=(0,k.parse)(e),i=(0,k.parse)(n);if(!r||!i)return e;let t=(0,k.interpolate)([r,i],"oklch");return(0,k.formatHex)(t(o))??e}s(c,"mixOklch");function In(e){return e?typeof e=="string"?e:e.base:"#000"}s(In,"coerceToHex");function b(e,n){let o=In(e),r=n.deepDark,i=n.deepLight;return{base:o,dark:c(o,r,.6),action:c(o,r,.2),active:c(o,i,.6),light:c(o,i,.9)}}s(b,"mountSingleColor");function Pe(e){let n=e.deepLight,o=e.deepDark;return{0:n,5:c(n,o,.05),10:c(n,o,.1),20:c(n,o,.2),30:c(n,o,.3),40:c(n,o,.4),50:c(n,o,.5),60:c(n,o,.6),70:c(n,o,.7),80:c(n,o,.8),90:c(n,o,.9),100:c(n,o,1)}}s(Pe,"mountGreyscaleColors");function Be(e){let n=e.deepLight,o=e.deepDark,r=e.primary,i=s(a=>1/17*(a-1),"interpolation"),t=c(r,o,.5);return{0:c(t,n,i(18)),5:c(t,n,i(17.5)),10:c(t,n,i(17)),20:c(t,n,i(16)),30:c(t,n,i(15)),40:c(t,n,i(14)),50:c(t,n,i(13)),60:c(t,n,i(12)),70:c(t,n,i(11)),80:c(t,n,i(10)),90:c(t,n,i(9)),100:c(t,n,i(8)),110:c(t,n,i(7)),120:c(t,n,i(6)),130:c(t,n,i(5)),140:c(t,n,i(4)),150:c(t,n,i(3)),160:c(t,n,i(2)),170:t,180:c(t,o,.25)}}s(Be,"mountNeutralColors");function kn(e){return{baseDark:e.baseDark,baseLight:e.baseLight,deepDark:e.deepDark,deepLight:e.deepLight,transparent:e.transparent??"transparent",neutral:Be(e),grayscale:Pe(e),main:b(e.main,e),opposite:b(e.opposite,e),complementary:b(e.complementary,e),danger:b(e.danger,e),information:b(e.information,e),success:b(e.success,e),warning:b(e.warning,e),primary:b(e.primary,e),secondary:b(e.secondary,e),tertiary:b(e.tertiary,e)}}s(kn,"composeColors");function _(e,n=He.defaultInputSpacing){let o=kn(e.colors),r=M(n,e.dimension),i=(0,_e.createSemantic)({colors:o,spacing:r}),t=(0,re.createFoundation)(i);return e.surface==="negative"&&(t=(0,re.createFoundation)((0,We.invertForSurface)({semantic:i,colors:o},"negative").semantic)),{foundation:t,colors:o}}s(_,"buildVariantThemes");async function Sn(e){let{config:n,outDir:o,cwd:r=process.cwd(),verbose:i=!1}=e,t=P(n),a=n.output??{};if(t.length===0)throw new Error("apollion-tokens build: no variants (config.brands is empty)");let l=await(0,f.mkdtemp)((0,x.join)((0,Je.tmpdir)(),"apollion-tokens-"));try{let m=[],g=s(async(u,I)=>{await Dn(l,u,I),m.push({path:u,sha256:ee(I)}),i&&console.log(` \u2713 ${u}`)},"emit");if(a.json){let u=Le(n),I=[],G=Re();I.push(G),await g(u.base.file,ve(G));for(let p of u.spacing){let w=t.find(E=>E.dimension===p.dimension),{foundation:H}=_(w),O=ke(H,p.dimension);I.push(O),await g(p.file,Ve(O,p.dimension))}for(let p of u.color){let w=t.find(W=>W.brand===p.brand&&W.mode===p.mode&&W.surface===p.surface),{foundation:H,colors:O}=_(w),E=Ie(H,O);I.push(E),await g(p.file,Ce(E,p.brand,p.mode,p.surface))}be(I),await g(Ne,$e(n,u))}if(a.css||a.ts)for(let u of t){let{foundation:I,colors:G}=_(u),p=Se(I,G,u),w=Ee(u);a.css&&await g(`css/${w}.css`,we(p)),a.ts&&await g(`ts/${w}.d.ts`,Oe(p))}let d={configHash:ne(n),files:m,gitCommit:Me(r),buildEnv:Fe()},D=Ae(d);return await(0,f.writeFile)((0,x.join)(l,"manifest.json"),D),await(0,f.rm)(o,{recursive:!0,force:!0}),await(0,f.mkdir)((0,x.dirname)(o),{recursive:!0}),await(0,f.rename)(l,o),i&&console.log(`\u2713 ${m.length} files \u2192 ${o}`),{manifest:d,outDir:o}}catch(m){throw await(0,f.rm)(l,{recursive:!0,force:!0}).catch(()=>{}),m}}s(Sn,"build");async function xn(e){let{config:n,outDir:o}=e,r;try{r=JSON.parse(await(0,f.readFile)((0,x.join)(o,"manifest.json"),"utf8"))}catch{return!1}return r.configHash===ne(n)}s(xn,"check");async function Dn(e,n,o){let r=(0,x.join)(e,n);await(0,f.mkdir)((0,x.dirname)(r),{recursive:!0}),await(0,f.writeFile)(r,o)}s(Dn,"writeAt");0&&(module.exports={build,check});
1
+ "use strict";var F=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Ye=Object.getOwnPropertyNames;var qe=Object.prototype.hasOwnProperty;var s=(e,n)=>F(e,"name",{value:n,configurable:!0});var Ke=(e,n)=>{for(var o in n)F(e,o,{get:n[o],enumerable:!0})},Ze=(e,n,o,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of Ye(n))!qe.call(e,t)&&t!==o&&F(e,t,{get:()=>n[t],enumerable:!(r=Xe(n,t))||r.enumerable});return e};var Qe=e=>Ze(F({},"__esModule",{value:!0}),e);var Cn={};Ke(Cn,{build:()=>wn,check:()=>Tn});module.exports=Qe(Cn);var g=require("node:fs/promises"),ze=require("node:os"),D=require("node:path");var C=require("@apollion-dsi/core/themes/border"),P=require("@apollion-dsi/core/themes/depth"),R=require("@apollion-dsi/core/themes/font"),q=require("@apollion-dsi/core/themes/spacing"),v=require("culori");var te=require("@apollion-dsi/core/themes/dimension");function j({multiplier:e=.25,alias:n},o){let r=o!==void 0?te.DIMENSION_MULTIPLIERS[o]:e;return(...t)=>t.map(i=>{let a=typeof i=="string"?n[i]:i;return`${r*a}rem`}).join(" ")}s(j,"createSpacing");var X={"bg.primary":{description:"Primary action surface \u2014 the brand\u2019s dominant call-to-action background."},"bg.secondary":{description:"Secondary action surface \u2014 supporting actions paired with the primary."},"bg.danger":{description:"Destructive / error surface \u2014 irreversible or failing actions."},"bg.success":{description:"Positive confirmation surface \u2014 completed or healthy states."},"bg.info":{description:"Informational surface \u2014 neutral, non-blocking notices.",deprecated:"Use bg.information once the foundation role is renamed (tracked for S6)."},"text.on-primary":{description:"Text/icon colour with guaranteed contrast over bg.primary."},"text.on-danger":{description:"Text/icon colour with guaranteed contrast over bg.danger."},"space.medium":{description:"Base spacing step (1rem at normal density) \u2014 the layout rhythm unit."},"space.large":{description:"Comfortable spacing step \u2014 section padding and card gutters."},"spacing.md":{description:"Medium foundation spacing alias \u2014 references the space.medium primitive."},"spacing.lg":{description:"Large foundation spacing alias \u2014 references the space.large primitive."},"border.radius.md":{description:"Default card corner radius."},"border.width.thin":{description:"Hairline border \u2014 dividers and default input outlines."},"border.width.regular":{description:"Standard emphasis border \u2014 focused/active controls."}};function Y(e){let n=Object.keys(X).filter(o=>!e.has(o));if(n.length>0)throw new Error(`token-meta: ${n.length} stale TOKEN_META key(s) resolve to no IR node: ${n.join(", ")}. Update src/token-meta.ts to match the current IR paths.`)}s(Y,"assertTokenMetaResolves");var en=(0,v.converter)("oklch");function h(e){return typeof e.type=="string"&&"value"in e}s(h,"isToken");function I(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}s(I,"kebab");function se(e){return e.split(".").map(I).join(".")}s(se,"kebabPath");function V(e){return e.kind==="ref"?e.resolved.raw:e.raw}s(V,"rawValue");function M(e,n){return Number(e.toFixed(n))||0}s(M,"round");function K(e){let n=en((0,v.parse)(e));if(!n)return{kind:"color",raw:e,components:[0,0,0],hex:"#000000"};let o=[M(n.l,4),M(n.c,4),M(n.h??0,2)],r=(0,v.formatHex)(n)??"#000000";return n.alpha!==void 0&&n.alpha!==1?{kind:"color",raw:e,components:o,alpha:M(n.alpha,4),hex:r}:{kind:"color",raw:e,components:o,hex:r}}s(K,"toColorValue");var ae=/^(-?(?:\d+\.?\d*|\.\d+))(px|rem)$/;function T(e){let n=ae.exec(e.trim());if(n)return{kind:"dimension",raw:e,value:Number(n[1]),unit:n[2]};let o=Number.parseFloat(e);return{kind:"dimension",raw:e,value:Number.isFinite(o)?o:0,unit:"rem"}}s(T,"toDimensionValue");function y(e){return{type:"color",value:K(e)}}s(y,"colorToken");function ie(e){let n={};for(let[o,r]of Object.entries(e))n[o]=y(r);return n}s(ie,"recordColorGroup");var nn=["main","opposite","complementary","primary","secondary","tertiary","success","danger","warning","information"];function ce(e){let n={};for(let o of nn){let r=e[o];n[o]={base:y(r.base),dark:y(r.dark),action:y(r.action),active:y(r.active),light:y(r.light)}}return n.grayscale=ie(e.grayscale),n.neutral=ie(e.neutral),n.baseDark=y(e.baseDark??"#000000"),n.baseLight=y(e.baseLight??"#ffffff"),n.deepDark=y(e.deepDark??"#000000"),n.deepLight=y(e.deepLight??"#ffffff"),n}s(ce,"buildColorPrimitives");function le(e){let n=j(q.defaultInputSpacing,e),o={};for(let r of Object.keys(q.defaultInputSpacing.alias))o[r]={type:"dimension",value:T(n(r))};return o}s(le,"buildSpacePrimitives");function de(){let e={};for(let[n,o]of Object.entries(C.defaultInputBorder.borderWidth))e[n]={type:"dimension",value:T(o)};return e}s(de,"buildBorderWidthPrimitives");function on(e,n){return{color:ce(e),space:le(n),borderWidth:de()}}s(on,"buildPrimitives");var ue={primary:"color.primary.base",secondary:"color.secondary.base",tertiary:"color.tertiary.base",success:"color.success.base",danger:"color.danger.base",warning:"color.warning.base",info:"color.information.base"},pe={onPrimary:"color.baseLight",onSecondary:"color.baseLight",onTertiary:"color.baseDark",onSuccess:"color.baseLight",onDanger:"color.baseLight",onWarning:"color.baseDark",onInfo:"color.baseLight"};function rn(e,n){let o=e;for(let r of n.split(".").slice(1))if(o&&typeof o=="object"&&r in o)o=o[r];else return;return typeof o=="string"?o:void 0}s(rn,"lookupPrimitive");function A(e,n,o){let r={};for(let[t,i]of Object.entries(e)){let a=o[t],c=a?rn(n,a):void 0;r[t]=a&&c===i?{type:"color",value:{kind:"ref",path:a,resolved:K(i)}}:y(i)}return r}s(A,"colorRefGroup");var fe={xs:"space.xs",sm:"space.small",md:"space.medium",lg:"space.large",xl:"space.xl",xxl:"space.xxl"},tn={none:"border-width.none",thin:"border-width.thin",regular:"border-width.regular",great:"border-width.great",bold:"border-width.bold"};function sn(e,n){let o=n.split("."),r=o[0]==="border-width"?"borderWidth":o[0],t=e[r];for(let i of o.slice(1))if(t&&!h(t)&&i in t)t=t[i];else return;return t&&h(t)&&t.value.kind==="dimension"?t.value.raw:void 0}s(sn,"lookupDimensionPrimitive");function Z(e,n,o){let r={};for(let[t,i]of Object.entries(e)){let a=o[t],c=a?sn(n,a):void 0;r[t]=a&&c===i?{type:"dimension",value:{kind:"ref",path:a,resolved:T(i)}}:{type:"dimension",value:T(i)}}return r}s(Z,"dimensionRefGroup");function me(e){let n={},o={};for(let[i,a]of Object.entries(C.defaultInputBorder.borderRadius))ae.test(a)?n[i]={type:"dimension",value:T(a)}:o[i]=a;let r=Z(C.defaultInputBorder.borderWidth,e,tn),t={};for(let[i,a]of Object.entries(C.defaultInputBorder.borderStyle))t[i]={type:"strokeStyle",value:{kind:"strokeStyle",raw:a,style:a}};return{group:{radius:n,width:r,style:t},extensions:o}}s(me,"buildBorder");function ge(e){let n=(0,R.createFont)(R.defaultInputFont,e),o={};for(let[c,u]of Object.entries(R.defaultInputFont.fontFamily)){let f=u.replace(/;\s*$/,"").trim();o[c]={type:"fontFamily",value:{kind:"fontFamily",raw:f,family:f}}}let r={};for(let[c,u]of Object.entries(n.fontSize))r[c]={type:"dimension",value:T(u)};let t={};for(let[c,u]of Object.entries(R.defaultInputFont.fontWeight))t[c]={type:"fontWeight",value:{kind:"fontWeight",raw:`${u}`,weight:u}};let i={};for(let[c,u]of Object.entries(R.defaultInputFont.lineHeight))i[c]={type:"number",value:{kind:"number",raw:`${u}`,number:u}};let a={letterSpacing:R.defaultInputFont.letterSpacing,textTransform:R.defaultInputFont.textTransform,fontStyle:R.defaultInputFont.fontStyle};return{group:{family:o,size:r,weight:t,lineHeight:i},extensions:a}}s(ge,"buildFont");var an=/rgba?\([^)]*\)|#[0-9a-fA-F]+|[a-zA-Z]+$/;function cn(e){let n=e.trim(),o=n.startsWith("inset");o&&(n=n.slice(5).trim());let r=n.match(an),t=r?r[0]:"#000000",a=(r?n.slice(0,r.index).trim():n).split(/\s+/).filter(Boolean),c=s(u=>T(a[u]??"0px"),"dim");return{kind:"shadow",raw:e,shadow:{color:K(t),offsetX:c(0),offsetY:c(1),blur:c(2),spread:c(3),inset:o}}}s(cn,"parseShadow");function ye(e){let n=(0,P.createDeth)(e),o={};for(let r of Object.keys(P.levelValues))o[r]={type:"shadow",value:cn(n(r))};return o}s(ye,"buildShadow");function N(e,n,o){let r={};for(let[t,i]of Object.entries(e)){let a=n?`${n}.${I(t)}`:I(t);if(h(i)){o.add(a);let c=X[a];r[t]=c&&(c.description!==void 0||c.deprecated!==void 0)?{...i,...c.description!==void 0?{description:c.description}:{},...c.deprecated!==void 0?{deprecated:c.deprecated}:{}}:i}else r[t]=N(i,a,o)}return r}s(N,"decorateGroup");function ln(e){let n=new Set,o=N(e.primitives,"",n),r=N(e.groups,"",n);return Y(n),{...e,primitives:o,groups:r}}s(ln,"decorateMeta");function L(e,n){return N(e,"",n)}s(L,"decorateSlice");function he(e,n,o){for(let[r,t]of Object.entries(e)){let i=n?`${n}.${I(r)}`:I(r);h(t)?o.add(i):he(t,i,o)}}s(he,"collectPaths");function be(e){let n=new Set;for(let o of e)he(o.groups,"",n);Y(n)}s(be,"assertSlicesMetaComplete");function Re(){let e=de(),o=me({borderWidth:e}),r={};Object.keys(o.extensions).length>0&&(r["com.apollion.border"]={radius:o.extensions});let t=new Set;return{groups:L({"border-width":e,border:o.group},t),extensions:r}}s(Re,"buildBaseIR");function Ie(e){let n=ge(e),o=new Set;return{groups:L({font:n.group},o),extensions:{"com.apollion.font":n.extensions}}}s(Ie,"buildFontIR");function ke(e,n){let o=ce(n),r=new Set;return{groups:L({color:o,bg:A(e.bg,n,ue),text:A(e.text,n,pe),shadow:ye(n)},r),extensions:{}}}s(ke,"buildColorIR");function Se(e,n){let o=le(n),r={space:o},t=new Set;return{groups:L({space:o,spacing:Z(e.spacing,r,fe)},t),extensions:{}}}s(Se,"buildSpacingIR");function dn(e,n,o){let r={brand:o.brand,mode:o.mode,surface:o.surface,dimension:o.dimension},t=on(n,o.dimension),i=me(t),a=ge(o.dimension),c={"com.apollion.variant":r,"com.apollion.font":a.extensions};Object.keys(i.extensions).length>0&&(c["com.apollion.border"]={radius:i.extensions});let u={description:`Apollion DS tokens \u2014 DTCG 2025.10. Variant: ${r.brand}/${r.mode}/${r.surface}/${r.dimension}.`,meta:r,primitives:t,groups:{bg:A(e.bg,n,ue),text:A(e.text,n,pe),spacing:Z(e.spacing,t,fe),border:i.group,font:a.group,shadow:ye(n)},extensions:c};return ln(u)}s(dn,"buildIR");var xe=dn;var un="/* Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs. */";function De(e,n,o){for(let[r,t]of Object.entries(e)){let i=[...n,I(r)];h(t)?o.push(` --apollion-${i.join("-")}: ${V(t.value)};`):De(t,i,o)}}s(De,"emitVars");function we(e,n,o){for(let[r,t]of Object.entries(e)){let i=[...n,I(r)];h(t)?t.type==="color"&&o.push(` @property --apollion-${i.join("-")} { syntax: '<color>'; inherits: true; initial-value: ${V(t.value)}; }`):we(t,i,o)}}s(we,"emitProperties");function Te(e){let{brand:n,mode:o,surface:r,dimension:t}=e.meta,i=[un,""];return i.push(`/* Variant: brand=${n} mode=${o} surface=${r} dimension=${t} */`,"",":root {"),De(e.groups,[],i),i.push("}",""),i.push("@supports (background: paint(squircle)) or (color: oklch(0% 0 0)) {"),we(e.groups,[],i),i.push("}",""),i.join(`
2
+ `)}s(Te,"renderCss");function ve(e){return e.alpha!==void 0?{colorSpace:"oklch",components:[...e.components],alpha:e.alpha,hex:e.hex}:{colorSpace:"oklch",components:[...e.components],hex:e.hex}}s(ve,"colorValue");function $(e){return{value:e.value,unit:e.unit}}s($,"dimensionValue");function pn(e){let n=e.shadow,o={color:ve(n.color),offsetX:$(n.offsetX),offsetY:$(n.offsetY),blur:$(n.blur),spread:$(n.spread)};return n.inset&&(o.inset=!0),o}s(pn,"shadowValue");function fn(e){switch(e.kind){case"ref":return`{${se(e.path)}}`;case"color":return ve(e);case"dimension":return $(e);case"fontFamily":return e.family;case"fontWeight":return e.weight;case"number":return e.number;case"strokeStyle":return e.style;case"shadow":return pn(e)}}s(fn,"projectValue");function mn(e){let n={$value:fn(e.value),$type:e.type};return e.description!==void 0&&(n.$description=e.description),e.deprecated!==void 0&&(n.$deprecated=e.deprecated),n}s(mn,"projectToken");function Q(e){let n={};for(let[o,r]of Object.entries(e))n[I(o)]=h(r)?mn(r):Q(r);return n}s(Q,"projectGroup");function B(e,n){let o={$description:n,...Q(e.groups)};return Object.keys(e.extensions).length>0&&(o.$extensions=e.extensions),`${JSON.stringify(o,null,2)}
3
+ `}s(B,"renderSet");function Ce(e){return B(e,"Apollion DS \u2014 base set (axis-invariant: border). DTCG 2025.10.")}s(Ce,"renderBaseSet");function Ve(e,n,o,r){return B(e,`Apollion DS \u2014 colour set. brand=${n} mode=${o} surface=${r}. DTCG 2025.10.`)}s(Ve,"renderColorSet");function $e(e,n){return B(e,`Apollion DS \u2014 spacing set. dimension=${n}. DTCG 2025.10.`)}s($e,"renderSpacingSet");function Ge(e,n){return B(e,`Apollion DS \u2014 font set. dimension=${n}. DTCG 2025.10.`)}s(Ge,"renderFontSet");function Oe(e,n){let{modifiers:o}=n,r=[{name:"brand",values:[...o.brand],default:o.brand[0]},{name:"mode",values:[...o.mode],default:o.mode[0]},{name:"surface",values:[...o.surface],default:o.surface[0]},{name:"dimension",values:[...o.dimension],default:o.dimension[0]}],i={name:"apollion-tokens",description:"Apollion DS token resolver \u2014 DTCG 2025.10. Compose the base set with the colour set for the chosen brand/mode/surface and the spacing + font sets for the chosen dimension. NOTE: mode is a topology placeholder in this release (dark resolves identically to light until S6).",sets:[{name:n.base.name,source:n.base.file},...n.spacing.map(a=>({name:a.name,source:a.file})),...n.font.map(a=>({name:a.name,source:a.file})),...n.color.map(a=>({name:a.name,source:a.file}))],modifiers:r,$extensions:{"com.apollion.resolver":{composition:{always:[n.base.name],byModifier:{color:"${brand}.color.${mode}.${surface}",spacing:"spacing.${dimension}",font:"font.${dimension}"}},modeIsPlaceholder:!0}}};return`${JSON.stringify(i,null,2)}
4
+ `}s(Oe,"renderResolver");var gn="// Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs.";function Ee(e,n,o){let r=" ".repeat(n);for(let[t,i]of Object.entries(e))h(i)?o.push(`${r}${JSON.stringify(t)}: ${JSON.stringify(V(i.value))},`):(o.push(`${r}${t}: {`),Ee(i,n+1,o),o.push(`${r}},`))}s(Ee,"emitGroup");function Fe(e){let{brand:n,mode:o,surface:r,dimension:t}=e.meta,i=[gn,`// Variant: brand=${n} mode=${o} surface=${r} dimension=${t}`,"","export const tokens = {"];return Ee(e.groups,1,i),i.push("} as const;","","export type Tokens = typeof tokens;",""),i.join(`
5
+ `)}s(Fe,"renderTs");var yn=["light","dark"],hn=["positive","negative"],bn=["compact","normal","spacious"];function _(e){let n=e.modes??yn,o=e.surfaces??hn,r=e.dimensions??bn,t=Object.entries(e.brands).sort(([a],[c])=>a.localeCompare(c)),i=[];for(let[a,c]of t)for(let u of n)for(let f of o)for(let w of r)i.push({brand:a,colors:c,mode:u,surface:f,dimension:w});return i}s(_,"expandVariants");function je(e){return`${e.brand}.${e.mode}.${e.surface}.${e.dimension}`}s(je,"variantName");var Me=require("node:crypto");function ne(e){return(0,Me.createHash)("sha256").update(e).digest("hex")}s(ne,"sha256");function oe(e){return ne(ee(e))}s(oe,"hashConfig");function ee(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ee).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ee(e[r])}`).join(",")}}`}s(ee,"stableStringify");function Ae(e){try{let{execSync:n}=require("node:child_process");return n("git rev-parse --short HEAD",{cwd:e,stdio:["ignore","pipe","ignore"],encoding:"utf8"}).trim()}catch{return""}}s(Ae,"detectGitCommit");function Ne(){return{node:process.version,platform:`${process.platform}-${process.arch}`}}s(Ne,"buildEnv");function Pe(e){let n=[...e.files].sort((r,t)=>r.path.localeCompare(t.path)),o={configHash:e.configHash,files:n,gitCommit:e.gitCommit,buildEnv:e.buildEnv};return`${JSON.stringify(o,null,2)}
6
+ `}s(Pe,"serializeManifest");var Rn="json/sets",Le="json/resolver.json";function H(e){return`${Rn}/${e}.json`}s(H,"setFile");function In(e,n,o){return`${e}.color.${n}.${o}`}s(In,"colorSetName");function kn(e){return`spacing.${e}`}s(kn,"spacingSetName");function Sn(e){return`font.${e}`}s(Sn,"fontSetName");function W(e,n){e.includes(n)||e.push(n)}s(W,"pushUnique");function Be(e){let n=_(e),o=[],r=[],t=[],i=[],a=new Set,c=[],u=new Set,f=[],w=new Set,G=[];for(let d of n){W(o,d.brand),W(r,d.mode),W(t,d.surface),W(i,d.dimension);let m=In(d.brand,d.mode,d.surface);a.has(m)||(a.add(m),c.push({kind:"color",name:m,file:H(m),brand:d.brand,mode:d.mode,surface:d.surface}));let k=kn(d.dimension);u.has(k)||(u.add(k),f.push({kind:"spacing",name:k,file:H(k),dimension:d.dimension}));let p=Sn(d.dimension);w.has(p)||(w.add(p),G.push({kind:"font",name:p,file:H(p),dimension:d.dimension}))}return{base:{kind:"base",name:"base",file:H("base")},spacing:f,font:G,color:c,modifiers:{brand:o,mode:r,surface:t,dimension:i}}}s(Be,"planSets");var re=require("@apollion-dsi/core/themes/foundation"),We=require("@apollion-dsi/core/themes/semantic"),Je=require("@apollion-dsi/core/themes/spacing"),Ue=require("@apollion-dsi/core/themes/surface");var x=require("culori");var ro=(0,x.converter)("oklch");function l(e,n,o){let r=(0,x.parse)(e),t=(0,x.parse)(n);if(!r||!t)return e;let i=(0,x.interpolate)([r,t],"oklch");return(0,x.formatHex)(i(o))??e}s(l,"mixOklch");function xn(e){return e?typeof e=="string"?e:e.base:"#000"}s(xn,"coerceToHex");function b(e,n){let o=xn(e),r=n.deepDark,t=n.deepLight;return{base:o,dark:l(o,r,.6),action:l(o,r,.2),active:l(o,t,.6),light:l(o,t,.9)}}s(b,"mountSingleColor");function _e(e){let n=e.deepLight,o=e.deepDark;return{0:n,5:l(n,o,.05),10:l(n,o,.1),20:l(n,o,.2),30:l(n,o,.3),40:l(n,o,.4),50:l(n,o,.5),60:l(n,o,.6),70:l(n,o,.7),80:l(n,o,.8),90:l(n,o,.9),100:l(n,o,1)}}s(_e,"mountGreyscaleColors");function He(e){let n=e.deepLight,o=e.deepDark,r=e.primary,t=s(a=>1/17*(a-1),"interpolation"),i=l(r,o,.5);return{0:l(i,n,t(18)),5:l(i,n,t(17.5)),10:l(i,n,t(17)),20:l(i,n,t(16)),30:l(i,n,t(15)),40:l(i,n,t(14)),50:l(i,n,t(13)),60:l(i,n,t(12)),70:l(i,n,t(11)),80:l(i,n,t(10)),90:l(i,n,t(9)),100:l(i,n,t(8)),110:l(i,n,t(7)),120:l(i,n,t(6)),130:l(i,n,t(5)),140:l(i,n,t(4)),150:l(i,n,t(3)),160:l(i,n,t(2)),170:i,180:l(i,o,.25)}}s(He,"mountNeutralColors");function Dn(e){return{baseDark:e.baseDark,baseLight:e.baseLight,deepDark:e.deepDark,deepLight:e.deepLight,transparent:e.transparent??"transparent",neutral:He(e),grayscale:_e(e),main:b(e.main,e),opposite:b(e.opposite,e),complementary:b(e.complementary,e),danger:b(e.danger,e),information:b(e.information,e),success:b(e.success,e),warning:b(e.warning,e),primary:b(e.primary,e),secondary:b(e.secondary,e),tertiary:b(e.tertiary,e)}}s(Dn,"composeColors");function J(e,n=Je.defaultInputSpacing){let o=Dn(e.colors),r=j(n,e.dimension),t=(0,We.createSemantic)({colors:o,spacing:r}),i=(0,re.createFoundation)(t);return e.surface==="negative"&&(i=(0,re.createFoundation)((0,Ue.invertForSurface)({semantic:t,colors:o},"negative").semantic)),{foundation:i,colors:o}}s(J,"buildVariantThemes");async function wn(e){let{config:n,outDir:o,cwd:r=process.cwd(),verbose:t=!1}=e,i=_(n),a=n.output??{};if(i.length===0)throw new Error("apollion-tokens build: no variants (config.brands is empty)");let c=await(0,g.mkdtemp)((0,D.join)((0,ze.tmpdir)(),"apollion-tokens-"));try{let u=[],f=s(async(d,m)=>{await vn(c,d,m),u.push({path:d,sha256:ne(m)}),t&&console.log(` \u2713 ${d}`)},"emit");if(a.json){let d=Be(n),m=[],k=Re();m.push(k),await f(d.base.file,Ce(k));for(let p of d.spacing){let S=i.find(E=>E.dimension===p.dimension),{foundation:U}=J(S),O=Se(U,p.dimension);m.push(O),await f(p.file,$e(O,p.dimension))}for(let p of d.font){let S=Ie(p.dimension);m.push(S),await f(p.file,Ge(S,p.dimension))}for(let p of d.color){let S=i.find(z=>z.brand===p.brand&&z.mode===p.mode&&z.surface===p.surface),{foundation:U,colors:O}=J(S),E=ke(U,O);m.push(E),await f(p.file,Ve(E,p.brand,p.mode,p.surface))}be(m),await f(Le,Oe(n,d))}if(a.css||a.ts)for(let d of i){let{foundation:m,colors:k}=J(d),p=xe(m,k,d),S=je(d);a.css&&await f(`css/${S}.css`,Te(p)),a.ts&&await f(`ts/${S}.d.ts`,Fe(p))}let w={configHash:oe(n),files:u,gitCommit:Ae(r),buildEnv:Ne()},G=Pe(w);return await(0,g.writeFile)((0,D.join)(c,"manifest.json"),G),await(0,g.rm)(o,{recursive:!0,force:!0}),await(0,g.mkdir)((0,D.dirname)(o),{recursive:!0}),await(0,g.rename)(c,o),t&&console.log(`\u2713 ${u.length} files \u2192 ${o}`),{manifest:w,outDir:o}}catch(u){throw await(0,g.rm)(c,{recursive:!0,force:!0}).catch(()=>{}),u}}s(wn,"build");async function Tn(e){let{config:n,outDir:o}=e,r;try{r=JSON.parse(await(0,g.readFile)((0,D.join)(o,"manifest.json"),"utf8"))}catch{return!1}return r.configHash===oe(n)}s(Tn,"check");async function vn(e,n,o){let r=(0,D.join)(e,n);await(0,g.mkdir)((0,D.dirname)(r),{recursive:!0}),await(0,g.writeFile)(r,o)}s(vn,"writeAt");0&&(module.exports={build,check});
package/lib/build.esm.js CHANGED
@@ -1,6 +1,6 @@
1
- var Pe=Object.defineProperty;var s=(e,n)=>Pe(e,"name",{value:n,configurable:!0}),Be=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(n,o)=>(typeof require<"u"?require:n)[o]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});import{mkdir as Ae,mkdtemp as wn,readFile as Tn,rename as vn,rm as Fe,writeFile as Ne}from"node:fs/promises";import{tmpdir as Cn}from"node:os";import{dirname as Le,join as A}from"node:path";import{defaultInputBorder as G}from"@apollion-dsi/core/themes/border";import{createDeth as He,levelValues as We}from"@apollion-dsi/core/themes/depth";import{defaultInputFont as I}from"@apollion-dsi/core/themes/font";import{defaultInputSpacing as K}from"@apollion-dsi/core/themes/spacing";import{converter as Je,formatHex as Ue,parse as ze}from"culori";import{DIMENSION_MULTIPLIERS as _e}from"@apollion-dsi/core/themes/dimension";function V({multiplier:e=.25,alias:n},o){let r=o!==void 0?_e[o]:e;return(...i)=>i.map(t=>{let a=typeof t=="string"?n[t]:t;return`${r*a}rem`}).join(" ")}s(V,"createSpacing");var P={"bg.primary":{description:"Primary action surface \u2014 the brand\u2019s dominant call-to-action background."},"bg.secondary":{description:"Secondary action surface \u2014 supporting actions paired with the primary."},"bg.danger":{description:"Destructive / error surface \u2014 irreversible or failing actions."},"bg.success":{description:"Positive confirmation surface \u2014 completed or healthy states."},"bg.info":{description:"Informational surface \u2014 neutral, non-blocking notices.",deprecated:"Use bg.information once the foundation role is renamed (tracked for S6)."},"text.on-primary":{description:"Text/icon colour with guaranteed contrast over bg.primary."},"text.on-danger":{description:"Text/icon colour with guaranteed contrast over bg.danger."},"space.medium":{description:"Base spacing step (1rem at normal density) \u2014 the layout rhythm unit."},"space.large":{description:"Comfortable spacing step \u2014 section padding and card gutters."},"spacing.md":{description:"Medium foundation spacing alias \u2014 references the space.medium primitive."},"spacing.lg":{description:"Large foundation spacing alias \u2014 references the space.large primitive."},"border.radius.md":{description:"Default card corner radius."},"border.width.thin":{description:"Hairline border \u2014 dividers and default input outlines."},"border.width.regular":{description:"Standard emphasis border \u2014 focused/active controls."}};function B(e){let n=Object.keys(P).filter(o=>!e.has(o));if(n.length>0)throw new Error(`token-meta: ${n.length} stale TOKEN_META key(s) resolve to no IR node: ${n.join(", ")}. Update src/token-meta.ts to match the current IR paths.`)}s(B,"assertTokenMetaResolves");var Xe=Je("oklch");function y(e){return typeof e.type=="string"&&"value"in e}s(y,"isToken");function b(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}s(b,"kebab");function Q(e){return e.split(".").map(b).join(".")}s(Q,"kebabPath");function D(e){return e.kind==="ref"?e.resolved.raw:e.raw}s(D,"rawValue");function $(e,n){return Number(e.toFixed(n))||0}s($,"round");function _(e){let n=Xe(ze(e));if(!n)return{kind:"color",raw:e,components:[0,0,0],hex:"#000000"};let o=[$(n.l,4),$(n.c,4),$(n.h??0,2)],r=Ue(n)??"#000000";return n.alpha!==void 0&&n.alpha!==1?{kind:"color",raw:e,components:o,alpha:$(n.alpha,4),hex:r}:{kind:"color",raw:e,components:o,hex:r}}s(_,"toColorValue");var ee=/^(-?(?:\d+\.?\d*|\.\d+))(px|rem)$/;function x(e){let n=ee.exec(e.trim());if(n)return{kind:"dimension",raw:e,value:Number(n[1]),unit:n[2]};let o=Number.parseFloat(e);return{kind:"dimension",raw:e,value:Number.isFinite(o)?o:0,unit:"rem"}}s(x,"toDimensionValue");function g(e){return{type:"color",value:_(e)}}s(g,"colorToken");function Z(e){let n={};for(let[o,r]of Object.entries(e))n[o]=g(r);return n}s(Z,"recordColorGroup");var Ye=["main","opposite","complementary","primary","secondary","tertiary","success","danger","warning","information"];function ne(e){let n={};for(let o of Ye){let r=e[o];n[o]={base:g(r.base),dark:g(r.dark),action:g(r.action),active:g(r.active),light:g(r.light)}}return n.grayscale=Z(e.grayscale),n.neutral=Z(e.neutral),n.baseDark=g(e.baseDark??"#000000"),n.baseLight=g(e.baseLight??"#ffffff"),n.deepDark=g(e.deepDark??"#000000"),n.deepLight=g(e.deepLight??"#ffffff"),n}s(ne,"buildColorPrimitives");function oe(e){let n=V(K,e),o={};for(let r of Object.keys(K.alias))o[r]={type:"dimension",value:x(n(r))};return o}s(oe,"buildSpacePrimitives");function re(){let e={};for(let[n,o]of Object.entries(G.borderWidth))e[n]={type:"dimension",value:x(o)};return e}s(re,"buildBorderWidthPrimitives");function qe(e,n){return{color:ne(e),space:oe(n),borderWidth:re()}}s(qe,"buildPrimitives");var te={primary:"color.primary.base",secondary:"color.secondary.base",tertiary:"color.tertiary.base",success:"color.success.base",danger:"color.danger.base",warning:"color.warning.base",info:"color.information.base"},ie={onPrimary:"color.baseLight",onSecondary:"color.baseLight",onTertiary:"color.baseDark",onSuccess:"color.baseLight",onDanger:"color.baseLight",onWarning:"color.baseDark",onInfo:"color.baseLight"};function Ke(e,n){let o=e;for(let r of n.split(".").slice(1))if(o&&typeof o=="object"&&r in o)o=o[r];else return;return typeof o=="string"?o:void 0}s(Ke,"lookupPrimitive");function O(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=o[i],l=a?Ke(n,a):void 0;r[i]=a&&l===t?{type:"color",value:{kind:"ref",path:a,resolved:_(t)}}:g(t)}return r}s(O,"colorRefGroup");var se={xs:"space.xs",sm:"space.small",md:"space.medium",lg:"space.large",xl:"space.xl",xxl:"space.xxl"},Ze={none:"border-width.none",thin:"border-width.thin",regular:"border-width.regular",great:"border-width.great",bold:"border-width.bold"};function Qe(e,n){let o=n.split("."),r=o[0]==="border-width"?"borderWidth":o[0],i=e[r];for(let t of o.slice(1))if(i&&!y(i)&&t in i)i=i[t];else return;return i&&y(i)&&i.value.kind==="dimension"?i.value.raw:void 0}s(Qe,"lookupDimensionPrimitive");function H(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=o[i],l=a?Qe(n,a):void 0;r[i]=a&&l===t?{type:"dimension",value:{kind:"ref",path:a,resolved:x(t)}}:{type:"dimension",value:x(t)}}return r}s(H,"dimensionRefGroup");function ae(e){let n={},o={};for(let[t,a]of Object.entries(G.borderRadius))ee.test(a)?n[t]={type:"dimension",value:x(a)}:o[t]=a;let r=H(G.borderWidth,e,Ze),i={};for(let[t,a]of Object.entries(G.borderStyle))i[t]={type:"strokeStyle",value:{kind:"strokeStyle",raw:a,style:a}};return{group:{radius:n,width:r,style:i},extensions:o}}s(ae,"buildBorder");function ce(){let e={};for(let[t,a]of Object.entries(I.fontFamily)){let l=a.replace(/;\s*$/,"").trim();e[t]={type:"fontFamily",value:{kind:"fontFamily",raw:l,family:l}}}let n={};for(let[t,a]of Object.entries(I.fontSize))n[t]={type:"dimension",value:{kind:"dimension",raw:`${a}px`,value:a,unit:"px"}};let o={};for(let[t,a]of Object.entries(I.fontWeight))o[t]={type:"fontWeight",value:{kind:"fontWeight",raw:`${a}`,weight:a}};let r={};for(let[t,a]of Object.entries(I.lineHeight))r[t]={type:"number",value:{kind:"number",raw:`${a}`,number:a}};let i={letterSpacing:I.letterSpacing,textTransform:I.textTransform,fontStyle:I.fontStyle};return{group:{family:e,size:n,weight:o,lineHeight:r},extensions:i}}s(ce,"buildFont");var en=/rgba?\([^)]*\)|#[0-9a-fA-F]+|[a-zA-Z]+$/;function nn(e){let n=e.trim(),o=n.startsWith("inset");o&&(n=n.slice(5).trim());let r=n.match(en),i=r?r[0]:"#000000",a=(r?n.slice(0,r.index).trim():n).split(/\s+/).filter(Boolean),l=s(f=>x(a[f]??"0px"),"dim");return{kind:"shadow",raw:e,shadow:{color:_(i),offsetX:l(0),offsetY:l(1),blur:l(2),spread:l(3),inset:o}}}s(nn,"parseShadow");function le(e){let n=He(e),o={};for(let r of Object.keys(We))o[r]={type:"shadow",value:nn(n(r))};return o}s(le,"buildShadow");function E(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=n?`${n}.${b(i)}`:b(i);if(y(t)){o.add(a);let l=P[a];r[i]=l&&(l.description!==void 0||l.deprecated!==void 0)?{...t,...l.description!==void 0?{description:l.description}:{},...l.deprecated!==void 0?{deprecated:l.deprecated}:{}}:t}else r[i]=E(t,a,o)}return r}s(E,"decorateGroup");function on(e){let n=new Set,o=E(e.primitives,"",n),r=E(e.groups,"",n);return B(n),{...e,primitives:o,groups:r}}s(on,"decorateMeta");function W(e,n){return E(e,"",n)}s(W,"decorateSlice");function de(e,n,o){for(let[r,i]of Object.entries(e)){let t=n?`${n}.${b(r)}`:b(r);y(i)?o.add(t):de(i,t,o)}}s(de,"collectPaths");function ue(e){let n=new Set;for(let o of e)de(o.groups,"",n);B(n)}s(ue,"assertSlicesMetaComplete");function pe(){let e=re(),o=ae({borderWidth:e}),r=ce(),i={"com.apollion.font":r.extensions};Object.keys(o.extensions).length>0&&(i["com.apollion.border"]={radius:o.extensions});let t=new Set;return{groups:W({"border-width":e,border:o.group,font:r.group},t),extensions:i}}s(pe,"buildBaseIR");function fe(e,n){let o=ne(n),r=new Set;return{groups:W({color:o,bg:O(e.bg,n,te),text:O(e.text,n,ie),shadow:le(n)},r),extensions:{}}}s(fe,"buildColorIR");function me(e,n){let o=oe(n),r={space:o},i=new Set;return{groups:W({space:o,spacing:H(e.spacing,r,se)},i),extensions:{}}}s(me,"buildSpacingIR");function rn(e,n,o){let r={brand:o.brand,mode:o.mode,surface:o.surface,dimension:o.dimension},i=qe(n,o.dimension),t=ae(i),a=ce(),l={"com.apollion.variant":r,"com.apollion.font":a.extensions};Object.keys(t.extensions).length>0&&(l["com.apollion.border"]={radius:t.extensions});let f={description:`Apollion DS tokens \u2014 DTCG 2025.10. Variant: ${r.brand}/${r.mode}/${r.surface}/${r.dimension}.`,meta:r,primitives:i,groups:{bg:O(e.bg,n,te),text:O(e.text,n,ie),spacing:H(e.spacing,i,se),border:t.group,font:a.group,shadow:le(n)},extensions:l};return on(f)}s(rn,"buildIR");var ge=rn;var tn="/* Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs. */";function ye(e,n,o){for(let[r,i]of Object.entries(e)){let t=[...n,b(r)];y(i)?o.push(` --apollion-${t.join("-")}: ${D(i.value)};`):ye(i,t,o)}}s(ye,"emitVars");function he(e,n,o){for(let[r,i]of Object.entries(e)){let t=[...n,b(r)];y(i)?i.type==="color"&&o.push(` @property --apollion-${t.join("-")} { syntax: '<color>'; inherits: true; initial-value: ${D(i.value)}; }`):he(i,t,o)}}s(he,"emitProperties");function be(e){let{brand:n,mode:o,surface:r,dimension:i}=e.meta,t=[tn,""];return t.push(`/* Variant: brand=${n} mode=${o} surface=${r} dimension=${i} */`,"",":root {"),ye(e.groups,[],t),t.push("}",""),t.push("@supports (background: paint(squircle)) or (color: oklch(0% 0 0)) {"),he(e.groups,[],t),t.push("}",""),t.join(`
2
- `)}s(be,"renderCss");function Re(e){return e.alpha!==void 0?{colorSpace:"oklch",components:[...e.components],alpha:e.alpha,hex:e.hex}:{colorSpace:"oklch",components:[...e.components],hex:e.hex}}s(Re,"colorValue");function w(e){return{value:e.value,unit:e.unit}}s(w,"dimensionValue");function sn(e){let n=e.shadow,o={color:Re(n.color),offsetX:w(n.offsetX),offsetY:w(n.offsetY),blur:w(n.blur),spread:w(n.spread)};return n.inset&&(o.inset=!0),o}s(sn,"shadowValue");function an(e){switch(e.kind){case"ref":return`{${Q(e.path)}}`;case"color":return Re(e);case"dimension":return w(e);case"fontFamily":return e.family;case"fontWeight":return e.weight;case"number":return e.number;case"strokeStyle":return e.style;case"shadow":return sn(e)}}s(an,"projectValue");function cn(e){let n={$value:an(e.value),$type:e.type};return e.description!==void 0&&(n.$description=e.description),e.deprecated!==void 0&&(n.$deprecated=e.deprecated),n}s(cn,"projectToken");function J(e){let n={};for(let[o,r]of Object.entries(e))n[b(o)]=y(r)?cn(r):J(r);return n}s(J,"projectGroup");function U(e,n){let o={$description:n,...J(e.groups)};return Object.keys(e.extensions).length>0&&(o.$extensions=e.extensions),`${JSON.stringify(o,null,2)}
3
- `}s(U,"renderSet");function Ie(e){return U(e,"Apollion DS \u2014 base set (axis-invariant: border + font). DTCG 2025.10.")}s(Ie,"renderBaseSet");function ke(e,n,o,r){return U(e,`Apollion DS \u2014 colour set. brand=${n} mode=${o} surface=${r}. DTCG 2025.10.`)}s(ke,"renderColorSet");function Se(e,n){return U(e,`Apollion DS \u2014 spacing set. dimension=${n}. DTCG 2025.10.`)}s(Se,"renderSpacingSet");function xe(e,n){let{modifiers:o}=n,r=[{name:"brand",values:[...o.brand],default:o.brand[0]},{name:"mode",values:[...o.mode],default:o.mode[0]},{name:"surface",values:[...o.surface],default:o.surface[0]},{name:"dimension",values:[...o.dimension],default:o.dimension[0]}],t={name:"apollion-tokens",description:"Apollion DS token resolver \u2014 DTCG 2025.10. Compose the base set with the colour set for the chosen brand/mode/surface and the spacing set for the chosen dimension. NOTE: mode is a topology placeholder in this release (dark resolves identically to light until S6).",sets:[{name:n.base.name,source:n.base.file},...n.spacing.map(a=>({name:a.name,source:a.file})),...n.color.map(a=>({name:a.name,source:a.file}))],modifiers:r,$extensions:{"com.apollion.resolver":{composition:{always:[n.base.name],byModifier:{color:"${brand}.color.${mode}.${surface}",spacing:"spacing.${dimension}"}},modeIsPlaceholder:!0}}};return`${JSON.stringify(t,null,2)}
4
- `}s(xe,"renderResolver");var ln="// Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs.";function De(e,n,o){let r=" ".repeat(n);for(let[i,t]of Object.entries(e))y(t)?o.push(`${r}${JSON.stringify(i)}: ${JSON.stringify(D(t.value))},`):(o.push(`${r}${i}: {`),De(t,n+1,o),o.push(`${r}},`))}s(De,"emitGroup");function we(e){let{brand:n,mode:o,surface:r,dimension:i}=e.meta,t=[ln,`// Variant: brand=${n} mode=${o} surface=${r} dimension=${i}`,"","export const tokens = {"];return De(e.groups,1,t),t.push("} as const;","","export type Tokens = typeof tokens;",""),t.join(`
5
- `)}s(we,"renderTs");var dn=["light","dark"],un=["positive","negative"],pn=["compact","normal","spacious"];function j(e){let n=e.modes??dn,o=e.surfaces??un,r=e.dimensions??pn,i=Object.entries(e.brands).sort(([a],[l])=>a.localeCompare(l)),t=[];for(let[a,l]of i)for(let f of n)for(let m of o)for(let d of r)t.push({brand:a,colors:l,mode:f,surface:m,dimension:d});return t}s(j,"expandVariants");function Te(e){return`${e.brand}.${e.mode}.${e.surface}.${e.dimension}`}s(Te,"variantName");import{createHash as fn}from"node:crypto";function X(e){return fn("sha256").update(e).digest("hex")}s(X,"sha256");function Y(e){return X(z(e))}s(Y,"hashConfig");function z(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(z).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${z(e[r])}`).join(",")}}`}s(z,"stableStringify");function ve(e){try{let{execSync:n}=Be("node:child_process");return n("git rev-parse --short HEAD",{cwd:e,stdio:["ignore","pipe","ignore"],encoding:"utf8"}).trim()}catch{return""}}s(ve,"detectGitCommit");function Ce(){return{node:process.version,platform:`${process.platform}-${process.arch}`}}s(Ce,"buildEnv");function Ve(e){let n=[...e.files].sort((r,i)=>r.path.localeCompare(i.path)),o={configHash:e.configHash,files:n,gitCommit:e.gitCommit,buildEnv:e.buildEnv};return`${JSON.stringify(o,null,2)}
6
- `}s(Ve,"serializeManifest");var mn="json/sets",$e="json/resolver.json";function q(e){return`${mn}/${e}.json`}s(q,"setFile");function gn(e,n,o){return`${e}.color.${n}.${o}`}s(gn,"colorSetName");function yn(e){return`spacing.${e}`}s(yn,"spacingSetName");function M(e,n){e.includes(n)||e.push(n)}s(M,"pushUnique");function Ge(e){let n=j(e),o=[],r=[],i=[],t=[],a=new Set,l=[],f=new Set,m=[];for(let d of n){M(o,d.brand),M(r,d.mode),M(i,d.surface),M(t,d.dimension);let k=gn(d.brand,d.mode,d.surface);a.has(k)||(a.add(k),l.push({kind:"color",name:k,file:q(k),brand:d.brand,mode:d.mode,surface:d.surface}));let u=yn(d.dimension);f.has(u)||(f.add(u),m.push({kind:"spacing",name:u,file:q(u),dimension:d.dimension}))}return{base:{kind:"base",name:"base",file:q("base")},spacing:m,color:l,modifiers:{brand:o,mode:r,surface:i,dimension:t}}}s(Ge,"planSets");import{createFoundation as Me}from"@apollion-dsi/core/themes/foundation";import{createSemantic as kn}from"@apollion-dsi/core/themes/semantic";import{defaultInputSpacing as Sn}from"@apollion-dsi/core/themes/spacing";import{invertForSurface as xn}from"@apollion-dsi/core/themes/surface";import{converter as hn,formatHex as bn,interpolate as Rn,parse as Oe}from"culori";var fo=hn("oklch");function c(e,n,o){let r=Oe(e),i=Oe(n);if(!r||!i)return e;let t=Rn([r,i],"oklch");return bn(t(o))??e}s(c,"mixOklch");function In(e){return e?typeof e=="string"?e:e.base:"#000"}s(In,"coerceToHex");function h(e,n){let o=In(e),r=n.deepDark,i=n.deepLight;return{base:o,dark:c(o,r,.6),action:c(o,r,.2),active:c(o,i,.6),light:c(o,i,.9)}}s(h,"mountSingleColor");function Ee(e){let n=e.deepLight,o=e.deepDark;return{0:n,5:c(n,o,.05),10:c(n,o,.1),20:c(n,o,.2),30:c(n,o,.3),40:c(n,o,.4),50:c(n,o,.5),60:c(n,o,.6),70:c(n,o,.7),80:c(n,o,.8),90:c(n,o,.9),100:c(n,o,1)}}s(Ee,"mountGreyscaleColors");function je(e){let n=e.deepLight,o=e.deepDark,r=e.primary,i=s(a=>1/17*(a-1),"interpolation"),t=c(r,o,.5);return{0:c(t,n,i(18)),5:c(t,n,i(17.5)),10:c(t,n,i(17)),20:c(t,n,i(16)),30:c(t,n,i(15)),40:c(t,n,i(14)),50:c(t,n,i(13)),60:c(t,n,i(12)),70:c(t,n,i(11)),80:c(t,n,i(10)),90:c(t,n,i(9)),100:c(t,n,i(8)),110:c(t,n,i(7)),120:c(t,n,i(6)),130:c(t,n,i(5)),140:c(t,n,i(4)),150:c(t,n,i(3)),160:c(t,n,i(2)),170:t,180:c(t,o,.25)}}s(je,"mountNeutralColors");function Dn(e){return{baseDark:e.baseDark,baseLight:e.baseLight,deepDark:e.deepDark,deepLight:e.deepLight,transparent:e.transparent??"transparent",neutral:je(e),grayscale:Ee(e),main:h(e.main,e),opposite:h(e.opposite,e),complementary:h(e.complementary,e),danger:h(e.danger,e),information:h(e.information,e),success:h(e.success,e),warning:h(e.warning,e),primary:h(e.primary,e),secondary:h(e.secondary,e),tertiary:h(e.tertiary,e)}}s(Dn,"composeColors");function F(e,n=Sn){let o=Dn(e.colors),r=V(n,e.dimension),i=kn({colors:o,spacing:r}),t=Me(i);return e.surface==="negative"&&(t=Me(xn({semantic:i,colors:o},"negative").semantic)),{foundation:t,colors:o}}s(F,"buildVariantThemes");async function Mo(e){let{config:n,outDir:o,cwd:r=process.cwd(),verbose:i=!1}=e,t=j(n),a=n.output??{};if(t.length===0)throw new Error("apollion-tokens build: no variants (config.brands is empty)");let l=await wn(A(Cn(),"apollion-tokens-"));try{let f=[],m=s(async(u,R)=>{await Vn(l,u,R),f.push({path:u,sha256:X(R)}),i&&console.log(` \u2713 ${u}`)},"emit");if(a.json){let u=Ge(n),R=[],T=pe();R.push(T),await m(u.base.file,Ie(T));for(let p of u.spacing){let S=t.find(C=>C.dimension===p.dimension),{foundation:N}=F(S),v=me(N,p.dimension);R.push(v),await m(p.file,Se(v,p.dimension))}for(let p of u.color){let S=t.find(L=>L.brand===p.brand&&L.mode===p.mode&&L.surface===p.surface),{foundation:N,colors:v}=F(S),C=fe(N,v);R.push(C),await m(p.file,ke(C,p.brand,p.mode,p.surface))}ue(R),await m($e,xe(n,u))}if(a.css||a.ts)for(let u of t){let{foundation:R,colors:T}=F(u),p=ge(R,T,u),S=Te(u);a.css&&await m(`css/${S}.css`,be(p)),a.ts&&await m(`ts/${S}.d.ts`,we(p))}let d={configHash:Y(n),files:f,gitCommit:ve(r),buildEnv:Ce()},k=Ve(d);return await Ne(A(l,"manifest.json"),k),await Fe(o,{recursive:!0,force:!0}),await Ae(Le(o),{recursive:!0}),await vn(l,o),i&&console.log(`\u2713 ${f.length} files \u2192 ${o}`),{manifest:d,outDir:o}}catch(f){throw await Fe(l,{recursive:!0,force:!0}).catch(()=>{}),f}}s(Mo,"build");async function Fo(e){let{config:n,outDir:o}=e,r;try{r=JSON.parse(await Tn(A(o,"manifest.json"),"utf8"))}catch{return!1}return r.configHash===Y(n)}s(Fo,"check");async function Vn(e,n,o){let r=A(e,n);await Ae(Le(r),{recursive:!0}),await Ne(r,o)}s(Vn,"writeAt");export{Mo as build,Fo as check};
1
+ var _e=Object.defineProperty;var s=(e,n)=>_e(e,"name",{value:n,configurable:!0}),He=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(n,o)=>(typeof require<"u"?require:n)[o]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});import{mkdir as Pe,mkdtemp as Vn,readFile as $n,rename as Gn,rm as Ne,writeFile as Le}from"node:fs/promises";import{tmpdir as On}from"node:os";import{dirname as Be,join as L}from"node:path";import{defaultInputBorder as G}from"@apollion-dsi/core/themes/border";import{createDeth as Je,levelValues as Ue}from"@apollion-dsi/core/themes/depth";import{createFont as ze,defaultInputFont as S}from"@apollion-dsi/core/themes/font";import{defaultInputSpacing as K}from"@apollion-dsi/core/themes/spacing";import{converter as Xe,formatHex as Ye,parse as qe}from"culori";import{DIMENSION_MULTIPLIERS as We}from"@apollion-dsi/core/themes/dimension";function V({multiplier:e=.25,alias:n},o){let r=o!==void 0?We[o]:e;return(...i)=>i.map(t=>{let a=typeof t=="string"?n[t]:t;return`${r*a}rem`}).join(" ")}s(V,"createSpacing");var H={"bg.primary":{description:"Primary action surface \u2014 the brand\u2019s dominant call-to-action background."},"bg.secondary":{description:"Secondary action surface \u2014 supporting actions paired with the primary."},"bg.danger":{description:"Destructive / error surface \u2014 irreversible or failing actions."},"bg.success":{description:"Positive confirmation surface \u2014 completed or healthy states."},"bg.info":{description:"Informational surface \u2014 neutral, non-blocking notices.",deprecated:"Use bg.information once the foundation role is renamed (tracked for S6)."},"text.on-primary":{description:"Text/icon colour with guaranteed contrast over bg.primary."},"text.on-danger":{description:"Text/icon colour with guaranteed contrast over bg.danger."},"space.medium":{description:"Base spacing step (1rem at normal density) \u2014 the layout rhythm unit."},"space.large":{description:"Comfortable spacing step \u2014 section padding and card gutters."},"spacing.md":{description:"Medium foundation spacing alias \u2014 references the space.medium primitive."},"spacing.lg":{description:"Large foundation spacing alias \u2014 references the space.large primitive."},"border.radius.md":{description:"Default card corner radius."},"border.width.thin":{description:"Hairline border \u2014 dividers and default input outlines."},"border.width.regular":{description:"Standard emphasis border \u2014 focused/active controls."}};function W(e){let n=Object.keys(H).filter(o=>!e.has(o));if(n.length>0)throw new Error(`token-meta: ${n.length} stale TOKEN_META key(s) resolve to no IR node: ${n.join(", ")}. Update src/token-meta.ts to match the current IR paths.`)}s(W,"assertTokenMetaResolves");var Ke=Xe("oklch");function y(e){return typeof e.type=="string"&&"value"in e}s(y,"isToken");function b(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}s(b,"kebab");function Q(e){return e.split(".").map(b).join(".")}s(Q,"kebabPath");function D(e){return e.kind==="ref"?e.resolved.raw:e.raw}s(D,"rawValue");function $(e,n){return Number(e.toFixed(n))||0}s($,"round");function J(e){let n=Ke(qe(e));if(!n)return{kind:"color",raw:e,components:[0,0,0],hex:"#000000"};let o=[$(n.l,4),$(n.c,4),$(n.h??0,2)],r=Ye(n)??"#000000";return n.alpha!==void 0&&n.alpha!==1?{kind:"color",raw:e,components:o,alpha:$(n.alpha,4),hex:r}:{kind:"color",raw:e,components:o,hex:r}}s(J,"toColorValue");var ee=/^(-?(?:\d+\.?\d*|\.\d+))(px|rem)$/;function x(e){let n=ee.exec(e.trim());if(n)return{kind:"dimension",raw:e,value:Number(n[1]),unit:n[2]};let o=Number.parseFloat(e);return{kind:"dimension",raw:e,value:Number.isFinite(o)?o:0,unit:"rem"}}s(x,"toDimensionValue");function g(e){return{type:"color",value:J(e)}}s(g,"colorToken");function Z(e){let n={};for(let[o,r]of Object.entries(e))n[o]=g(r);return n}s(Z,"recordColorGroup");var Ze=["main","opposite","complementary","primary","secondary","tertiary","success","danger","warning","information"];function ne(e){let n={};for(let o of Ze){let r=e[o];n[o]={base:g(r.base),dark:g(r.dark),action:g(r.action),active:g(r.active),light:g(r.light)}}return n.grayscale=Z(e.grayscale),n.neutral=Z(e.neutral),n.baseDark=g(e.baseDark??"#000000"),n.baseLight=g(e.baseLight??"#ffffff"),n.deepDark=g(e.deepDark??"#000000"),n.deepLight=g(e.deepLight??"#ffffff"),n}s(ne,"buildColorPrimitives");function oe(e){let n=V(K,e),o={};for(let r of Object.keys(K.alias))o[r]={type:"dimension",value:x(n(r))};return o}s(oe,"buildSpacePrimitives");function re(){let e={};for(let[n,o]of Object.entries(G.borderWidth))e[n]={type:"dimension",value:x(o)};return e}s(re,"buildBorderWidthPrimitives");function Qe(e,n){return{color:ne(e),space:oe(n),borderWidth:re()}}s(Qe,"buildPrimitives");var te={primary:"color.primary.base",secondary:"color.secondary.base",tertiary:"color.tertiary.base",success:"color.success.base",danger:"color.danger.base",warning:"color.warning.base",info:"color.information.base"},ie={onPrimary:"color.baseLight",onSecondary:"color.baseLight",onTertiary:"color.baseDark",onSuccess:"color.baseLight",onDanger:"color.baseLight",onWarning:"color.baseDark",onInfo:"color.baseLight"};function en(e,n){let o=e;for(let r of n.split(".").slice(1))if(o&&typeof o=="object"&&r in o)o=o[r];else return;return typeof o=="string"?o:void 0}s(en,"lookupPrimitive");function O(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=o[i],c=a?en(n,a):void 0;r[i]=a&&c===t?{type:"color",value:{kind:"ref",path:a,resolved:J(t)}}:g(t)}return r}s(O,"colorRefGroup");var se={xs:"space.xs",sm:"space.small",md:"space.medium",lg:"space.large",xl:"space.xl",xxl:"space.xxl"},nn={none:"border-width.none",thin:"border-width.thin",regular:"border-width.regular",great:"border-width.great",bold:"border-width.bold"};function on(e,n){let o=n.split("."),r=o[0]==="border-width"?"borderWidth":o[0],i=e[r];for(let t of o.slice(1))if(i&&!y(i)&&t in i)i=i[t];else return;return i&&y(i)&&i.value.kind==="dimension"?i.value.raw:void 0}s(on,"lookupDimensionPrimitive");function U(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=o[i],c=a?on(n,a):void 0;r[i]=a&&c===t?{type:"dimension",value:{kind:"ref",path:a,resolved:x(t)}}:{type:"dimension",value:x(t)}}return r}s(U,"dimensionRefGroup");function ae(e){let n={},o={};for(let[t,a]of Object.entries(G.borderRadius))ee.test(a)?n[t]={type:"dimension",value:x(a)}:o[t]=a;let r=U(G.borderWidth,e,nn),i={};for(let[t,a]of Object.entries(G.borderStyle))i[t]={type:"strokeStyle",value:{kind:"strokeStyle",raw:a,style:a}};return{group:{radius:n,width:r,style:i},extensions:o}}s(ae,"buildBorder");function ce(e){let n=ze(S,e),o={};for(let[c,u]of Object.entries(S.fontFamily)){let f=u.replace(/;\s*$/,"").trim();o[c]={type:"fontFamily",value:{kind:"fontFamily",raw:f,family:f}}}let r={};for(let[c,u]of Object.entries(n.fontSize))r[c]={type:"dimension",value:x(u)};let i={};for(let[c,u]of Object.entries(S.fontWeight))i[c]={type:"fontWeight",value:{kind:"fontWeight",raw:`${u}`,weight:u}};let t={};for(let[c,u]of Object.entries(S.lineHeight))t[c]={type:"number",value:{kind:"number",raw:`${u}`,number:u}};let a={letterSpacing:S.letterSpacing,textTransform:S.textTransform,fontStyle:S.fontStyle};return{group:{family:o,size:r,weight:i,lineHeight:t},extensions:a}}s(ce,"buildFont");var rn=/rgba?\([^)]*\)|#[0-9a-fA-F]+|[a-zA-Z]+$/;function tn(e){let n=e.trim(),o=n.startsWith("inset");o&&(n=n.slice(5).trim());let r=n.match(rn),i=r?r[0]:"#000000",a=(r?n.slice(0,r.index).trim():n).split(/\s+/).filter(Boolean),c=s(u=>x(a[u]??"0px"),"dim");return{kind:"shadow",raw:e,shadow:{color:J(i),offsetX:c(0),offsetY:c(1),blur:c(2),spread:c(3),inset:o}}}s(tn,"parseShadow");function le(e){let n=Je(e),o={};for(let r of Object.keys(Ue))o[r]={type:"shadow",value:tn(n(r))};return o}s(le,"buildShadow");function E(e,n,o){let r={};for(let[i,t]of Object.entries(e)){let a=n?`${n}.${b(i)}`:b(i);if(y(t)){o.add(a);let c=H[a];r[i]=c&&(c.description!==void 0||c.deprecated!==void 0)?{...t,...c.description!==void 0?{description:c.description}:{},...c.deprecated!==void 0?{deprecated:c.deprecated}:{}}:t}else r[i]=E(t,a,o)}return r}s(E,"decorateGroup");function sn(e){let n=new Set,o=E(e.primitives,"",n),r=E(e.groups,"",n);return W(n),{...e,primitives:o,groups:r}}s(sn,"decorateMeta");function F(e,n){return E(e,"",n)}s(F,"decorateSlice");function de(e,n,o){for(let[r,i]of Object.entries(e)){let t=n?`${n}.${b(r)}`:b(r);y(i)?o.add(t):de(i,t,o)}}s(de,"collectPaths");function ue(e){let n=new Set;for(let o of e)de(o.groups,"",n);W(n)}s(ue,"assertSlicesMetaComplete");function pe(){let e=re(),o=ae({borderWidth:e}),r={};Object.keys(o.extensions).length>0&&(r["com.apollion.border"]={radius:o.extensions});let i=new Set;return{groups:F({"border-width":e,border:o.group},i),extensions:r}}s(pe,"buildBaseIR");function fe(e){let n=ce(e),o=new Set;return{groups:F({font:n.group},o),extensions:{"com.apollion.font":n.extensions}}}s(fe,"buildFontIR");function me(e,n){let o=ne(n),r=new Set;return{groups:F({color:o,bg:O(e.bg,n,te),text:O(e.text,n,ie),shadow:le(n)},r),extensions:{}}}s(me,"buildColorIR");function ge(e,n){let o=oe(n),r={space:o},i=new Set;return{groups:F({space:o,spacing:U(e.spacing,r,se)},i),extensions:{}}}s(ge,"buildSpacingIR");function an(e,n,o){let r={brand:o.brand,mode:o.mode,surface:o.surface,dimension:o.dimension},i=Qe(n,o.dimension),t=ae(i),a=ce(o.dimension),c={"com.apollion.variant":r,"com.apollion.font":a.extensions};Object.keys(t.extensions).length>0&&(c["com.apollion.border"]={radius:t.extensions});let u={description:`Apollion DS tokens \u2014 DTCG 2025.10. Variant: ${r.brand}/${r.mode}/${r.surface}/${r.dimension}.`,meta:r,primitives:i,groups:{bg:O(e.bg,n,te),text:O(e.text,n,ie),spacing:U(e.spacing,i,se),border:t.group,font:a.group,shadow:le(n)},extensions:c};return sn(u)}s(an,"buildIR");var ye=an;var cn="/* Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs. */";function he(e,n,o){for(let[r,i]of Object.entries(e)){let t=[...n,b(r)];y(i)?o.push(` --apollion-${t.join("-")}: ${D(i.value)};`):he(i,t,o)}}s(he,"emitVars");function be(e,n,o){for(let[r,i]of Object.entries(e)){let t=[...n,b(r)];y(i)?i.type==="color"&&o.push(` @property --apollion-${t.join("-")} { syntax: '<color>'; inherits: true; initial-value: ${D(i.value)}; }`):be(i,t,o)}}s(be,"emitProperties");function Re(e){let{brand:n,mode:o,surface:r,dimension:i}=e.meta,t=[cn,""];return t.push(`/* Variant: brand=${n} mode=${o} surface=${r} dimension=${i} */`,"",":root {"),he(e.groups,[],t),t.push("}",""),t.push("@supports (background: paint(squircle)) or (color: oklch(0% 0 0)) {"),be(e.groups,[],t),t.push("}",""),t.join(`
2
+ `)}s(Re,"renderCss");function Ie(e){return e.alpha!==void 0?{colorSpace:"oklch",components:[...e.components],alpha:e.alpha,hex:e.hex}:{colorSpace:"oklch",components:[...e.components],hex:e.hex}}s(Ie,"colorValue");function w(e){return{value:e.value,unit:e.unit}}s(w,"dimensionValue");function ln(e){let n=e.shadow,o={color:Ie(n.color),offsetX:w(n.offsetX),offsetY:w(n.offsetY),blur:w(n.blur),spread:w(n.spread)};return n.inset&&(o.inset=!0),o}s(ln,"shadowValue");function dn(e){switch(e.kind){case"ref":return`{${Q(e.path)}}`;case"color":return Ie(e);case"dimension":return w(e);case"fontFamily":return e.family;case"fontWeight":return e.weight;case"number":return e.number;case"strokeStyle":return e.style;case"shadow":return ln(e)}}s(dn,"projectValue");function un(e){let n={$value:dn(e.value),$type:e.type};return e.description!==void 0&&(n.$description=e.description),e.deprecated!==void 0&&(n.$deprecated=e.deprecated),n}s(un,"projectToken");function z(e){let n={};for(let[o,r]of Object.entries(e))n[b(o)]=y(r)?un(r):z(r);return n}s(z,"projectGroup");function j(e,n){let o={$description:n,...z(e.groups)};return Object.keys(e.extensions).length>0&&(o.$extensions=e.extensions),`${JSON.stringify(o,null,2)}
3
+ `}s(j,"renderSet");function ke(e){return j(e,"Apollion DS \u2014 base set (axis-invariant: border). DTCG 2025.10.")}s(ke,"renderBaseSet");function Se(e,n,o,r){return j(e,`Apollion DS \u2014 colour set. brand=${n} mode=${o} surface=${r}. DTCG 2025.10.`)}s(Se,"renderColorSet");function xe(e,n){return j(e,`Apollion DS \u2014 spacing set. dimension=${n}. DTCG 2025.10.`)}s(xe,"renderSpacingSet");function De(e,n){return j(e,`Apollion DS \u2014 font set. dimension=${n}. DTCG 2025.10.`)}s(De,"renderFontSet");function we(e,n){let{modifiers:o}=n,r=[{name:"brand",values:[...o.brand],default:o.brand[0]},{name:"mode",values:[...o.mode],default:o.mode[0]},{name:"surface",values:[...o.surface],default:o.surface[0]},{name:"dimension",values:[...o.dimension],default:o.dimension[0]}],t={name:"apollion-tokens",description:"Apollion DS token resolver \u2014 DTCG 2025.10. Compose the base set with the colour set for the chosen brand/mode/surface and the spacing + font sets for the chosen dimension. NOTE: mode is a topology placeholder in this release (dark resolves identically to light until S6).",sets:[{name:n.base.name,source:n.base.file},...n.spacing.map(a=>({name:a.name,source:a.file})),...n.font.map(a=>({name:a.name,source:a.file})),...n.color.map(a=>({name:a.name,source:a.file}))],modifiers:r,$extensions:{"com.apollion.resolver":{composition:{always:[n.base.name],byModifier:{color:"${brand}.color.${mode}.${surface}",spacing:"spacing.${dimension}",font:"font.${dimension}"}},modeIsPlaceholder:!0}}};return`${JSON.stringify(t,null,2)}
4
+ `}s(we,"renderResolver");var pn="// Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs.";function Te(e,n,o){let r=" ".repeat(n);for(let[i,t]of Object.entries(e))y(t)?o.push(`${r}${JSON.stringify(i)}: ${JSON.stringify(D(t.value))},`):(o.push(`${r}${i}: {`),Te(t,n+1,o),o.push(`${r}},`))}s(Te,"emitGroup");function ve(e){let{brand:n,mode:o,surface:r,dimension:i}=e.meta,t=[pn,`// Variant: brand=${n} mode=${o} surface=${r} dimension=${i}`,"","export const tokens = {"];return Te(e.groups,1,t),t.push("} as const;","","export type Tokens = typeof tokens;",""),t.join(`
5
+ `)}s(ve,"renderTs");var fn=["light","dark"],mn=["positive","negative"],gn=["compact","normal","spacious"];function M(e){let n=e.modes??fn,o=e.surfaces??mn,r=e.dimensions??gn,i=Object.entries(e.brands).sort(([a],[c])=>a.localeCompare(c)),t=[];for(let[a,c]of i)for(let u of n)for(let f of o)for(let k of r)t.push({brand:a,colors:c,mode:u,surface:f,dimension:k});return t}s(M,"expandVariants");function Ce(e){return`${e.brand}.${e.mode}.${e.surface}.${e.dimension}`}s(Ce,"variantName");import{createHash as yn}from"node:crypto";function Y(e){return yn("sha256").update(e).digest("hex")}s(Y,"sha256");function q(e){return Y(X(e))}s(q,"hashConfig");function X(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(X).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${X(e[r])}`).join(",")}}`}s(X,"stableStringify");function Ve(e){try{let{execSync:n}=He("node:child_process");return n("git rev-parse --short HEAD",{cwd:e,stdio:["ignore","pipe","ignore"],encoding:"utf8"}).trim()}catch{return""}}s(Ve,"detectGitCommit");function $e(){return{node:process.version,platform:`${process.platform}-${process.arch}`}}s($e,"buildEnv");function Ge(e){let n=[...e.files].sort((r,i)=>r.path.localeCompare(i.path)),o={configHash:e.configHash,files:n,gitCommit:e.gitCommit,buildEnv:e.buildEnv};return`${JSON.stringify(o,null,2)}
6
+ `}s(Ge,"serializeManifest");var hn="json/sets",Oe="json/resolver.json";function A(e){return`${hn}/${e}.json`}s(A,"setFile");function bn(e,n,o){return`${e}.color.${n}.${o}`}s(bn,"colorSetName");function Rn(e){return`spacing.${e}`}s(Rn,"spacingSetName");function In(e){return`font.${e}`}s(In,"fontSetName");function N(e,n){e.includes(n)||e.push(n)}s(N,"pushUnique");function Ee(e){let n=M(e),o=[],r=[],i=[],t=[],a=new Set,c=[],u=new Set,f=[],k=new Set,T=[];for(let d of n){N(o,d.brand),N(r,d.mode),N(i,d.surface),N(t,d.dimension);let m=bn(d.brand,d.mode,d.surface);a.has(m)||(a.add(m),c.push({kind:"color",name:m,file:A(m),brand:d.brand,mode:d.mode,surface:d.surface}));let R=Rn(d.dimension);u.has(R)||(u.add(R),f.push({kind:"spacing",name:R,file:A(R),dimension:d.dimension}));let p=In(d.dimension);k.has(p)||(k.add(p),T.push({kind:"font",name:p,file:A(p),dimension:d.dimension}))}return{base:{kind:"base",name:"base",file:A("base")},spacing:f,font:T,color:c,modifiers:{brand:o,mode:r,surface:i,dimension:t}}}s(Ee,"planSets");import{createFoundation as Ae}from"@apollion-dsi/core/themes/foundation";import{createSemantic as wn}from"@apollion-dsi/core/themes/semantic";import{defaultInputSpacing as Tn}from"@apollion-dsi/core/themes/spacing";import{invertForSurface as vn}from"@apollion-dsi/core/themes/surface";import{converter as kn,formatHex as Sn,interpolate as xn,parse as Fe}from"culori";var ho=kn("oklch");function l(e,n,o){let r=Fe(e),i=Fe(n);if(!r||!i)return e;let t=xn([r,i],"oklch");return Sn(t(o))??e}s(l,"mixOklch");function Dn(e){return e?typeof e=="string"?e:e.base:"#000"}s(Dn,"coerceToHex");function h(e,n){let o=Dn(e),r=n.deepDark,i=n.deepLight;return{base:o,dark:l(o,r,.6),action:l(o,r,.2),active:l(o,i,.6),light:l(o,i,.9)}}s(h,"mountSingleColor");function je(e){let n=e.deepLight,o=e.deepDark;return{0:n,5:l(n,o,.05),10:l(n,o,.1),20:l(n,o,.2),30:l(n,o,.3),40:l(n,o,.4),50:l(n,o,.5),60:l(n,o,.6),70:l(n,o,.7),80:l(n,o,.8),90:l(n,o,.9),100:l(n,o,1)}}s(je,"mountGreyscaleColors");function Me(e){let n=e.deepLight,o=e.deepDark,r=e.primary,i=s(a=>1/17*(a-1),"interpolation"),t=l(r,o,.5);return{0:l(t,n,i(18)),5:l(t,n,i(17.5)),10:l(t,n,i(17)),20:l(t,n,i(16)),30:l(t,n,i(15)),40:l(t,n,i(14)),50:l(t,n,i(13)),60:l(t,n,i(12)),70:l(t,n,i(11)),80:l(t,n,i(10)),90:l(t,n,i(9)),100:l(t,n,i(8)),110:l(t,n,i(7)),120:l(t,n,i(6)),130:l(t,n,i(5)),140:l(t,n,i(4)),150:l(t,n,i(3)),160:l(t,n,i(2)),170:t,180:l(t,o,.25)}}s(Me,"mountNeutralColors");function Cn(e){return{baseDark:e.baseDark,baseLight:e.baseLight,deepDark:e.deepDark,deepLight:e.deepLight,transparent:e.transparent??"transparent",neutral:Me(e),grayscale:je(e),main:h(e.main,e),opposite:h(e.opposite,e),complementary:h(e.complementary,e),danger:h(e.danger,e),information:h(e.information,e),success:h(e.success,e),warning:h(e.warning,e),primary:h(e.primary,e),secondary:h(e.secondary,e),tertiary:h(e.tertiary,e)}}s(Cn,"composeColors");function P(e,n=Tn){let o=Cn(e.colors),r=V(n,e.dimension),i=wn({colors:o,spacing:r}),t=Ae(i);return e.surface==="negative"&&(t=Ae(vn({semantic:i,colors:o},"negative").semantic)),{foundation:t,colors:o}}s(P,"buildVariantThemes");async function Po(e){let{config:n,outDir:o,cwd:r=process.cwd(),verbose:i=!1}=e,t=M(n),a=n.output??{};if(t.length===0)throw new Error("apollion-tokens build: no variants (config.brands is empty)");let c=await Vn(L(On(),"apollion-tokens-"));try{let u=[],f=s(async(d,m)=>{await En(c,d,m),u.push({path:d,sha256:Y(m)}),i&&console.log(` \u2713 ${d}`)},"emit");if(a.json){let d=Ee(n),m=[],R=pe();m.push(R),await f(d.base.file,ke(R));for(let p of d.spacing){let I=t.find(C=>C.dimension===p.dimension),{foundation:B}=P(I),v=ge(B,p.dimension);m.push(v),await f(p.file,xe(v,p.dimension))}for(let p of d.font){let I=fe(p.dimension);m.push(I),await f(p.file,De(I,p.dimension))}for(let p of d.color){let I=t.find(_=>_.brand===p.brand&&_.mode===p.mode&&_.surface===p.surface),{foundation:B,colors:v}=P(I),C=me(B,v);m.push(C),await f(p.file,Se(C,p.brand,p.mode,p.surface))}ue(m),await f(Oe,we(n,d))}if(a.css||a.ts)for(let d of t){let{foundation:m,colors:R}=P(d),p=ye(m,R,d),I=Ce(d);a.css&&await f(`css/${I}.css`,Re(p)),a.ts&&await f(`ts/${I}.d.ts`,ve(p))}let k={configHash:q(n),files:u,gitCommit:Ve(r),buildEnv:$e()},T=Ge(k);return await Le(L(c,"manifest.json"),T),await Ne(o,{recursive:!0,force:!0}),await Pe(Be(o),{recursive:!0}),await Gn(c,o),i&&console.log(`\u2713 ${u.length} files \u2192 ${o}`),{manifest:k,outDir:o}}catch(u){throw await Ne(c,{recursive:!0,force:!0}).catch(()=>{}),u}}s(Po,"build");async function Lo(e){let{config:n,outDir:o}=e,r;try{r=JSON.parse(await $n(L(o,"manifest.json"),"utf8"))}catch{return!1}return r.configHash===q(n)}s(Lo,"check");async function En(e,n,o){let r=L(e,n);await Pe(Be(r),{recursive:!0}),await Le(r,o)}s(En,"writeAt");export{Po as build,Lo as check};
package/lib/cli.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- var Ye=Object.defineProperty;var s=(e,o)=>Ye(e,"name",{value:o,configurable:!0}),Ke=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(o,n)=>(typeof require<"u"?require:o)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});import{readFile as Xo}from"node:fs/promises";import{resolve as ne}from"node:path";import{mkdir as He,mkdtemp as Go,readFile as Po,rename as Mo,rm as Be,writeFile as We}from"node:fs/promises";import{tmpdir as Fo}from"node:os";import{dirname as Ue,join as L}from"node:path";import{defaultInputBorder as E}from"@apollion-dsi/core/themes/border";import{createDeth as Qe,levelValues as eo}from"@apollion-dsi/core/themes/depth";import{defaultInputFont as x}from"@apollion-dsi/core/themes/font";import{defaultInputSpacing as re}from"@apollion-dsi/core/themes/spacing";import{converter as oo,formatHex as no,parse as ro}from"culori";import{DIMENSION_MULTIPLIERS as Ze}from"@apollion-dsi/core/themes/dimension";function j({multiplier:e=.25,alias:o},n){let r=n!==void 0?Ze[n]:e;return(...i)=>i.map(t=>{let a=typeof t=="string"?o[t]:t;return`${r*a}rem`}).join(" ")}s(j,"createSpacing");var W={"bg.primary":{description:"Primary action surface \u2014 the brand\u2019s dominant call-to-action background."},"bg.secondary":{description:"Secondary action surface \u2014 supporting actions paired with the primary."},"bg.danger":{description:"Destructive / error surface \u2014 irreversible or failing actions."},"bg.success":{description:"Positive confirmation surface \u2014 completed or healthy states."},"bg.info":{description:"Informational surface \u2014 neutral, non-blocking notices.",deprecated:"Use bg.information once the foundation role is renamed (tracked for S6)."},"text.on-primary":{description:"Text/icon colour with guaranteed contrast over bg.primary."},"text.on-danger":{description:"Text/icon colour with guaranteed contrast over bg.danger."},"space.medium":{description:"Base spacing step (1rem at normal density) \u2014 the layout rhythm unit."},"space.large":{description:"Comfortable spacing step \u2014 section padding and card gutters."},"spacing.md":{description:"Medium foundation spacing alias \u2014 references the space.medium primitive."},"spacing.lg":{description:"Large foundation spacing alias \u2014 references the space.large primitive."},"border.radius.md":{description:"Default card corner radius."},"border.width.thin":{description:"Hairline border \u2014 dividers and default input outlines."},"border.width.regular":{description:"Standard emphasis border \u2014 focused/active controls."}};function U(e){let o=Object.keys(W).filter(n=>!e.has(n));if(o.length>0)throw new Error(`token-meta: ${o.length} stale TOKEN_META key(s) resolve to no IR node: ${o.join(", ")}. Update src/token-meta.ts to match the current IR paths.`)}s(U,"assertTokenMetaResolves");var to=oo("oklch");function b(e){return typeof e.type=="string"&&"value"in e}s(b,"isToken");function k(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}s(k,"kebab");function ie(e){return e.split(".").map(k).join(".")}s(ie,"kebabPath");function T(e){return e.kind==="ref"?e.resolved.raw:e.raw}s(T,"rawValue");function A(e,o){return Number(e.toFixed(o))||0}s(A,"round");function J(e){let o=to(ro(e));if(!o)return{kind:"color",raw:e,components:[0,0,0],hex:"#000000"};let n=[A(o.l,4),A(o.c,4),A(o.h??0,2)],r=no(o)??"#000000";return o.alpha!==void 0&&o.alpha!==1?{kind:"color",raw:e,components:n,alpha:A(o.alpha,4),hex:r}:{kind:"color",raw:e,components:n,hex:r}}s(J,"toColorValue");var se=/^(-?(?:\d+\.?\d*|\.\d+))(px|rem)$/;function v(e){let o=se.exec(e.trim());if(o)return{kind:"dimension",raw:e,value:Number(o[1]),unit:o[2]};let n=Number.parseFloat(e);return{kind:"dimension",raw:e,value:Number.isFinite(n)?n:0,unit:"rem"}}s(v,"toDimensionValue");function h(e){return{type:"color",value:J(e)}}s(h,"colorToken");function te(e){let o={};for(let[n,r]of Object.entries(e))o[n]=h(r);return o}s(te,"recordColorGroup");var io=["main","opposite","complementary","primary","secondary","tertiary","success","danger","warning","information"];function ae(e){let o={};for(let n of io){let r=e[n];o[n]={base:h(r.base),dark:h(r.dark),action:h(r.action),active:h(r.active),light:h(r.light)}}return o.grayscale=te(e.grayscale),o.neutral=te(e.neutral),o.baseDark=h(e.baseDark??"#000000"),o.baseLight=h(e.baseLight??"#ffffff"),o.deepDark=h(e.deepDark??"#000000"),o.deepLight=h(e.deepLight??"#ffffff"),o}s(ae,"buildColorPrimitives");function ce(e){let o=j(re,e),n={};for(let r of Object.keys(re.alias))n[r]={type:"dimension",value:v(o(r))};return n}s(ce,"buildSpacePrimitives");function le(){let e={};for(let[o,n]of Object.entries(E.borderWidth))e[o]={type:"dimension",value:v(n)};return e}s(le,"buildBorderWidthPrimitives");function so(e,o){return{color:ae(e),space:ce(o),borderWidth:le()}}s(so,"buildPrimitives");var de={primary:"color.primary.base",secondary:"color.secondary.base",tertiary:"color.tertiary.base",success:"color.success.base",danger:"color.danger.base",warning:"color.warning.base",info:"color.information.base"},ue={onPrimary:"color.baseLight",onSecondary:"color.baseLight",onTertiary:"color.baseDark",onSuccess:"color.baseLight",onDanger:"color.baseLight",onWarning:"color.baseDark",onInfo:"color.baseLight"};function ao(e,o){let n=e;for(let r of o.split(".").slice(1))if(n&&typeof n=="object"&&r in n)n=n[r];else return;return typeof n=="string"?n:void 0}s(ao,"lookupPrimitive");function G(e,o,n){let r={};for(let[i,t]of Object.entries(e)){let a=n[i],c=a?ao(o,a):void 0;r[i]=a&&c===t?{type:"color",value:{kind:"ref",path:a,resolved:J(t)}}:h(t)}return r}s(G,"colorRefGroup");var pe={xs:"space.xs",sm:"space.small",md:"space.medium",lg:"space.large",xl:"space.xl",xxl:"space.xxl"},co={none:"border-width.none",thin:"border-width.thin",regular:"border-width.regular",great:"border-width.great",bold:"border-width.bold"};function lo(e,o){let n=o.split("."),r=n[0]==="border-width"?"borderWidth":n[0],i=e[r];for(let t of n.slice(1))if(i&&!b(i)&&t in i)i=i[t];else return;return i&&b(i)&&i.value.kind==="dimension"?i.value.raw:void 0}s(lo,"lookupDimensionPrimitive");function z(e,o,n){let r={};for(let[i,t]of Object.entries(e)){let a=n[i],c=a?lo(o,a):void 0;r[i]=a&&c===t?{type:"dimension",value:{kind:"ref",path:a,resolved:v(t)}}:{type:"dimension",value:v(t)}}return r}s(z,"dimensionRefGroup");function fe(e){let o={},n={};for(let[t,a]of Object.entries(E.borderRadius))se.test(a)?o[t]={type:"dimension",value:v(a)}:n[t]=a;let r=z(E.borderWidth,e,co),i={};for(let[t,a]of Object.entries(E.borderStyle))i[t]={type:"strokeStyle",value:{kind:"strokeStyle",raw:a,style:a}};return{group:{radius:o,width:r,style:i},extensions:n}}s(fe,"buildBorder");function me(){let e={};for(let[t,a]of Object.entries(x.fontFamily)){let c=a.replace(/;\s*$/,"").trim();e[t]={type:"fontFamily",value:{kind:"fontFamily",raw:c,family:c}}}let o={};for(let[t,a]of Object.entries(x.fontSize))o[t]={type:"dimension",value:{kind:"dimension",raw:`${a}px`,value:a,unit:"px"}};let n={};for(let[t,a]of Object.entries(x.fontWeight))n[t]={type:"fontWeight",value:{kind:"fontWeight",raw:`${a}`,weight:a}};let r={};for(let[t,a]of Object.entries(x.lineHeight))r[t]={type:"number",value:{kind:"number",raw:`${a}`,number:a}};let i={letterSpacing:x.letterSpacing,textTransform:x.textTransform,fontStyle:x.fontStyle};return{group:{family:e,size:o,weight:n,lineHeight:r},extensions:i}}s(me,"buildFont");var uo=/rgba?\([^)]*\)|#[0-9a-fA-F]+|[a-zA-Z]+$/;function po(e){let o=e.trim(),n=o.startsWith("inset");n&&(o=o.slice(5).trim());let r=o.match(uo),i=r?r[0]:"#000000",a=(r?o.slice(0,r.index).trim():o).split(/\s+/).filter(Boolean),c=s(d=>v(a[d]??"0px"),"dim");return{kind:"shadow",raw:e,shadow:{color:J(i),offsetX:c(0),offsetY:c(1),blur:c(2),spread:c(3),inset:n}}}s(po,"parseShadow");function ge(e){let o=Qe(e),n={};for(let r of Object.keys(eo))n[r]={type:"shadow",value:po(o(r))};return n}s(ge,"buildShadow");function P(e,o,n){let r={};for(let[i,t]of Object.entries(e)){let a=o?`${o}.${k(i)}`:k(i);if(b(t)){n.add(a);let c=W[a];r[i]=c&&(c.description!==void 0||c.deprecated!==void 0)?{...t,...c.description!==void 0?{description:c.description}:{},...c.deprecated!==void 0?{deprecated:c.deprecated}:{}}:t}else r[i]=P(t,a,n)}return r}s(P,"decorateGroup");function fo(e){let o=new Set,n=P(e.primitives,"",o),r=P(e.groups,"",o);return U(o),{...e,primitives:n,groups:r}}s(fo,"decorateMeta");function X(e,o){return P(e,"",o)}s(X,"decorateSlice");function ye(e,o,n){for(let[r,i]of Object.entries(e)){let t=o?`${o}.${k(r)}`:k(r);b(i)?n.add(t):ye(i,t,n)}}s(ye,"collectPaths");function he(e){let o=new Set;for(let n of e)ye(n.groups,"",o);U(o)}s(he,"assertSlicesMetaComplete");function be(){let e=le(),n=fe({borderWidth:e}),r=me(),i={"com.apollion.font":r.extensions};Object.keys(n.extensions).length>0&&(i["com.apollion.border"]={radius:n.extensions});let t=new Set;return{groups:X({"border-width":e,border:n.group,font:r.group},t),extensions:i}}s(be,"buildBaseIR");function Re(e,o){let n=ae(o),r=new Set;return{groups:X({color:n,bg:G(e.bg,o,de),text:G(e.text,o,ue),shadow:ge(o)},r),extensions:{}}}s(Re,"buildColorIR");function ke(e,o){let n=ce(o),r={space:n},i=new Set;return{groups:X({space:n,spacing:z(e.spacing,r,pe)},i),extensions:{}}}s(ke,"buildSpacingIR");function mo(e,o,n){let r={brand:n.brand,mode:n.mode,surface:n.surface,dimension:n.dimension},i=so(o,n.dimension),t=fe(i),a=me(),c={"com.apollion.variant":r,"com.apollion.font":a.extensions};Object.keys(t.extensions).length>0&&(c["com.apollion.border"]={radius:t.extensions});let d={description:`Apollion DS tokens \u2014 DTCG 2025.10. Variant: ${r.brand}/${r.mode}/${r.surface}/${r.dimension}.`,meta:r,primitives:i,groups:{bg:G(e.bg,o,de),text:G(e.text,o,ue),spacing:z(e.spacing,i,pe),border:t.group,font:a.group,shadow:ge(o)},extensions:c};return fo(d)}s(mo,"buildIR");var Ie=mo;var go="/* Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs. */";function xe(e,o,n){for(let[r,i]of Object.entries(e)){let t=[...o,k(r)];b(i)?n.push(` --apollion-${t.join("-")}: ${T(i.value)};`):xe(i,t,n)}}s(xe,"emitVars");function Se(e,o,n){for(let[r,i]of Object.entries(e)){let t=[...o,k(r)];b(i)?i.type==="color"&&n.push(` @property --apollion-${t.join("-")} { syntax: '<color>'; inherits: true; initial-value: ${T(i.value)}; }`):Se(i,t,n)}}s(Se,"emitProperties");function we(e){let{brand:o,mode:n,surface:r,dimension:i}=e.meta,t=[go,""];return t.push(`/* Variant: brand=${o} mode=${n} surface=${r} dimension=${i} */`,"",":root {"),xe(e.groups,[],t),t.push("}",""),t.push("@supports (background: paint(squircle)) or (color: oklch(0% 0 0)) {"),Se(e.groups,[],t),t.push("}",""),t.join(`
3
- `)}s(we,"renderCss");function De(e){return e.alpha!==void 0?{colorSpace:"oklch",components:[...e.components],alpha:e.alpha,hex:e.hex}:{colorSpace:"oklch",components:[...e.components],hex:e.hex}}s(De,"colorValue");function C(e){return{value:e.value,unit:e.unit}}s(C,"dimensionValue");function yo(e){let o=e.shadow,n={color:De(o.color),offsetX:C(o.offsetX),offsetY:C(o.offsetY),blur:C(o.blur),spread:C(o.spread)};return o.inset&&(n.inset=!0),n}s(yo,"shadowValue");function ho(e){switch(e.kind){case"ref":return`{${ie(e.path)}}`;case"color":return De(e);case"dimension":return C(e);case"fontFamily":return e.family;case"fontWeight":return e.weight;case"number":return e.number;case"strokeStyle":return e.style;case"shadow":return yo(e)}}s(ho,"projectValue");function bo(e){let o={$value:ho(e.value),$type:e.type};return e.description!==void 0&&(o.$description=e.description),e.deprecated!==void 0&&(o.$deprecated=e.deprecated),o}s(bo,"projectToken");function q(e){let o={};for(let[n,r]of Object.entries(e))o[k(n)]=b(r)?bo(r):q(r);return o}s(q,"projectGroup");function Y(e,o){let n={$description:o,...q(e.groups)};return Object.keys(e.extensions).length>0&&(n.$extensions=e.extensions),`${JSON.stringify(n,null,2)}
4
- `}s(Y,"renderSet");function ve(e){return Y(e,"Apollion DS \u2014 base set (axis-invariant: border + font). DTCG 2025.10.")}s(ve,"renderBaseSet");function Te(e,o,n,r){return Y(e,`Apollion DS \u2014 colour set. brand=${o} mode=${n} surface=${r}. DTCG 2025.10.`)}s(Te,"renderColorSet");function Ce(e,o){return Y(e,`Apollion DS \u2014 spacing set. dimension=${o}. DTCG 2025.10.`)}s(Ce,"renderSpacingSet");function $e(e,o){let{modifiers:n}=o,r=[{name:"brand",values:[...n.brand],default:n.brand[0]},{name:"mode",values:[...n.mode],default:n.mode[0]},{name:"surface",values:[...n.surface],default:n.surface[0]},{name:"dimension",values:[...n.dimension],default:n.dimension[0]}],t={name:"apollion-tokens",description:"Apollion DS token resolver \u2014 DTCG 2025.10. Compose the base set with the colour set for the chosen brand/mode/surface and the spacing set for the chosen dimension. NOTE: mode is a topology placeholder in this release (dark resolves identically to light until S6).",sets:[{name:o.base.name,source:o.base.file},...o.spacing.map(a=>({name:a.name,source:a.file})),...o.color.map(a=>({name:a.name,source:a.file}))],modifiers:r,$extensions:{"com.apollion.resolver":{composition:{always:[o.base.name],byModifier:{color:"${brand}.color.${mode}.${surface}",spacing:"spacing.${dimension}"}},modeIsPlaceholder:!0}}};return`${JSON.stringify(t,null,2)}
5
- `}s($e,"renderResolver");var Ro="// Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs.";function Ve(e,o,n){let r=" ".repeat(o);for(let[i,t]of Object.entries(e))b(t)?n.push(`${r}${JSON.stringify(i)}: ${JSON.stringify(T(t.value))},`):(n.push(`${r}${i}: {`),Ve(t,o+1,n),n.push(`${r}},`))}s(Ve,"emitGroup");function Oe(e){let{brand:o,mode:n,surface:r,dimension:i}=e.meta,t=[Ro,`// Variant: brand=${o} mode=${n} surface=${r} dimension=${i}`,"","export const tokens = {"];return Ve(e.groups,1,t),t.push("} as const;","","export type Tokens = typeof tokens;",""),t.join(`
6
- `)}s(Oe,"renderTs");var ko=["light","dark"],Io=["positive","negative"],xo=["compact","normal","spacious"];function M(e){let o=e.modes??ko,n=e.surfaces??Io,r=e.dimensions??xo,i=Object.entries(e.brands).sort(([a],[c])=>a.localeCompare(c)),t=[];for(let[a,c]of i)for(let d of o)for(let m of n)for(let p of r)t.push({brand:a,colors:c,mode:d,surface:m,dimension:p});return t}s(M,"expandVariants");function je(e){return`${e.brand}.${e.mode}.${e.surface}.${e.dimension}`}s(je,"variantName");import{createHash as So}from"node:crypto";function Z(e){return So("sha256").update(e).digest("hex")}s(Z,"sha256");function Q(e){return Z(K(e))}s(Q,"hashConfig");function K(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(K).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${K(e[r])}`).join(",")}}`}s(K,"stableStringify");function Ae(e){try{let{execSync:o}=Ke("node:child_process");return o("git rev-parse --short HEAD",{cwd:e,stdio:["ignore","pipe","ignore"],encoding:"utf8"}).trim()}catch{return""}}s(Ae,"detectGitCommit");function Ee(){return{node:process.version,platform:`${process.platform}-${process.arch}`}}s(Ee,"buildEnv");function Ge(e){let o=[...e.files].sort((r,i)=>r.path.localeCompare(i.path)),n={configHash:e.configHash,files:o,gitCommit:e.gitCommit,buildEnv:e.buildEnv};return`${JSON.stringify(n,null,2)}
7
- `}s(Ge,"serializeManifest");var wo="json/sets",Pe="json/resolver.json";function ee(e){return`${wo}/${e}.json`}s(ee,"setFile");function Do(e,o,n){return`${e}.color.${o}.${n}`}s(Do,"colorSetName");function vo(e){return`spacing.${e}`}s(vo,"spacingSetName");function F(e,o){e.includes(o)||e.push(o)}s(F,"pushUnique");function Me(e){let o=M(e),n=[],r=[],i=[],t=[],a=new Set,c=[],d=new Set,m=[];for(let p of o){F(n,p.brand),F(r,p.mode),F(i,p.surface),F(t,p.dimension);let w=Do(p.brand,p.mode,p.surface);a.has(w)||(a.add(w),c.push({kind:"color",name:w,file:ee(w),brand:p.brand,mode:p.mode,surface:p.surface}));let f=vo(p.dimension);d.has(f)||(d.add(f),m.push({kind:"spacing",name:f,file:ee(f),dimension:p.dimension}))}return{base:{kind:"base",name:"base",file:ee("base")},spacing:m,color:c,modifiers:{brand:n,mode:r,surface:i,dimension:t}}}s(Me,"planSets");import{createFoundation as _e}from"@apollion-dsi/core/themes/foundation";import{createSemantic as Oo}from"@apollion-dsi/core/themes/semantic";import{defaultInputSpacing as jo}from"@apollion-dsi/core/themes/spacing";import{invertForSurface as Ao}from"@apollion-dsi/core/themes/surface";import{converter as To,formatHex as Co,interpolate as $o,parse as Fe}from"culori";var Gn=To("oklch");function l(e,o,n){let r=Fe(e),i=Fe(o);if(!r||!i)return e;let t=$o([r,i],"oklch");return Co(t(n))??e}s(l,"mixOklch");function Vo(e){return e?typeof e=="string"?e:e.base:"#000"}s(Vo,"coerceToHex");function R(e,o){let n=Vo(e),r=o.deepDark,i=o.deepLight;return{base:n,dark:l(n,r,.6),action:l(n,r,.2),active:l(n,i,.6),light:l(n,i,.9)}}s(R,"mountSingleColor");function Ne(e){let o=e.deepLight,n=e.deepDark;return{0:o,5:l(o,n,.05),10:l(o,n,.1),20:l(o,n,.2),30:l(o,n,.3),40:l(o,n,.4),50:l(o,n,.5),60:l(o,n,.6),70:l(o,n,.7),80:l(o,n,.8),90:l(o,n,.9),100:l(o,n,1)}}s(Ne,"mountGreyscaleColors");function Le(e){let o=e.deepLight,n=e.deepDark,r=e.primary,i=s(a=>1/17*(a-1),"interpolation"),t=l(r,n,.5);return{0:l(t,o,i(18)),5:l(t,o,i(17.5)),10:l(t,o,i(17)),20:l(t,o,i(16)),30:l(t,o,i(15)),40:l(t,o,i(14)),50:l(t,o,i(13)),60:l(t,o,i(12)),70:l(t,o,i(11)),80:l(t,o,i(10)),90:l(t,o,i(9)),100:l(t,o,i(8)),110:l(t,o,i(7)),120:l(t,o,i(6)),130:l(t,o,i(5)),140:l(t,o,i(4)),150:l(t,o,i(3)),160:l(t,o,i(2)),170:t,180:l(t,n,.25)}}s(Le,"mountNeutralColors");function Eo(e){return{baseDark:e.baseDark,baseLight:e.baseLight,deepDark:e.deepDark,deepLight:e.deepLight,transparent:e.transparent??"transparent",neutral:Le(e),grayscale:Ne(e),main:R(e.main,e),opposite:R(e.opposite,e),complementary:R(e.complementary,e),danger:R(e.danger,e),information:R(e.information,e),success:R(e.success,e),warning:R(e.warning,e),primary:R(e.primary,e),secondary:R(e.secondary,e),tertiary:R(e.tertiary,e)}}s(Eo,"composeColors");function N(e,o=jo){let n=Eo(e.colors),r=j(o,e.dimension),i=Oo({colors:n,spacing:r}),t=_e(i);return e.surface==="negative"&&(t=_e(Ao({semantic:i,colors:n},"negative").semantic)),{foundation:t,colors:n}}s(N,"buildVariantThemes");async function Je(e){let{config:o,outDir:n,cwd:r=process.cwd(),verbose:i=!1}=e,t=M(o),a=o.output??{};if(t.length===0)throw new Error("apollion-tokens build: no variants (config.brands is empty)");let c=await Go(L(Fo(),"apollion-tokens-"));try{let d=[],m=s(async(f,I)=>{await No(c,f,I),d.push({path:f,sha256:Z(I)}),i&&console.log(` \u2713 ${f}`)},"emit");if(a.json){let f=Me(o),I=[],$=be();I.push($),await m(f.base.file,ve($));for(let g of f.spacing){let D=t.find(O=>O.dimension===g.dimension),{foundation:B}=N(D),V=ke(B,g.dimension);I.push(V),await m(g.file,Ce(V,g.dimension))}for(let g of f.color){let D=t.find(H=>H.brand===g.brand&&H.mode===g.mode&&H.surface===g.surface),{foundation:B,colors:V}=N(D),O=Re(B,V);I.push(O),await m(g.file,Te(O,g.brand,g.mode,g.surface))}he(I),await m(Pe,$e(o,f))}if(a.css||a.ts)for(let f of t){let{foundation:I,colors:$}=N(f),g=Ie(I,$,f),D=je(f);a.css&&await m(`css/${D}.css`,we(g)),a.ts&&await m(`ts/${D}.d.ts`,Oe(g))}let p={configHash:Q(o),files:d,gitCommit:Ae(r),buildEnv:Ee()},w=Ge(p);return await We(L(c,"manifest.json"),w),await Be(n,{recursive:!0,force:!0}),await He(Ue(n),{recursive:!0}),await Mo(c,n),i&&console.log(`\u2713 ${d.length} files \u2192 ${n}`),{manifest:p,outDir:n}}catch(d){throw await Be(c,{recursive:!0,force:!0}).catch(()=>{}),d}}s(Je,"build");async function ze(e){let{config:o,outDir:n}=e,r;try{r=JSON.parse(await Po(L(n,"manifest.json"),"utf8"))}catch{return!1}return r.configHash===Q(o)}s(ze,"check");async function No(e,o,n){let r=L(e,o);await He(Ue(r),{recursive:!0}),await We(r,n)}s(No,"writeAt");import{readFile as _o}from"node:fs/promises";import{resolve as Bo}from"node:path";import{createContext as Ho,Script as Wo}from"node:vm";import{z as u}from"zod";var y=u.string().regex(/^#([0-9a-fA-F]{3}){1,2}$|^transparent$|^rgb\(.*\)$|^oklch\(.*\)$/,{message:'Must be hex, rgb(), oklch(), or "transparent"'}),Lo=u.object({baseDark:u.string().optional(),baseLight:u.string().optional(),deepDark:y,deepLight:y,transparent:u.string().optional(),main:y.optional(),opposite:y.optional(),complementary:y.optional(),information:y.optional(),success:y.optional(),danger:y.optional(),warning:y.optional(),primary:y.optional(),secondary:y.optional(),tertiary:y.optional()}).passthrough(),Xe=u.object({brands:u.record(u.string(),Lo).refine(e=>Object.keys(e).length>0,{message:"apollion.config.mjs: brands must contain at least 1 entry"}),modes:u.array(u.enum(["light","dark"])).optional(),surfaces:u.array(u.enum(["positive","negative"])).optional(),dimensions:u.array(u.enum(["compact","normal","spacious"])).optional(),output:u.object({runtime:u.boolean().optional(),css:u.boolean().optional(),json:u.boolean().optional(),ts:u.boolean().optional()}).passthrough().optional()}).passthrough();var Uo=[/\brequire\s*\(/,/\bimport\s*\(/,/^\s*import\s+/m],Jo=1e3;var oe=class oe extends Error{constructor(n,r){super(n);this.configPath=r;this.name="ConfigLoadError"}};s(oe,"ConfigLoadError");var S=oe;async function qe(e){let o=Bo(e.configPath),n=await _o(o,"utf8");for(let d of Uo)if(d.test(n))throw new S(`apollion.config: dynamic require/import not allowed (matched ${d}). Declarative config only \u2014 see ADR-006 \xA73.8 B3.`,o);let r=n.replace(/(^|\n)\s*export\s+default\s+/,(d,m)=>`${m}__apollion_config_export = `);if(r===n)throw new S("apollion.config: missing `export default <object>;` \u2014 config must export a default object literal.",o);let i={__apollion_config_export:void 0,console:zo(),Symbol,Number,String,Boolean,Array,Object,JSON,Math,defineConfig:s(d=>d,"defineConfig")},t=Ho(i);try{new Wo(r,{filename:o}).runInContext(t,{timeout:Jo})}catch(d){throw new S(`apollion.config: evaluation failed \u2014 ${d instanceof Error?d.message:String(d)}`,o)}let a=i.__apollion_config_export;if(a===void 0)throw new S("apollion.config: `export default` produced undefined.",o);let c=Xe.safeParse(a);if(!c.success){let d=c.error.issues.map(m=>` ${m.path.join(".")||"(root)"}: ${m.message}`).join(`
8
- `);throw new S(`apollion.config: schema validation failed \u2014
9
- ${d}`,o)}return c.data}s(qe,"loadConfig");function zo(){return{log:s((...e)=>console.log("[apollion.config]",...e),"log"),warn:s((...e)=>console.warn("[apollion.config]",...e),"warn"),error:s((...e)=>console.error("[apollion.config]",...e),"error")}}s(zo,"makeReadOnlyConsole");function qo(e){let o=e.slice(2),n=o[0];n!=="build"&&_(`Unknown command "${n??""}". Usage: apollion-tokens build [--check] [--verbose] --config <path> [--out <dir>]`);let r="apollion.config.mjs",i="dist",t=!1,a=!1;for(let c=1;c<o.length;c++){let d=o[c];switch(d){case"--config":r=o[++c]??_("--config needs a path");break;case"--out":i=o[++c]??_("--out needs a path");break;case"--check":t=!0;break;case"--verbose":a=!0;break;default:_(`Unknown flag "${d}"`)}}return{command:n,configPath:r,outDir:i,check:t,verbose:a}}s(qo,"parseArgs");function _(e){console.error(`apollion-tokens: ${e}`),process.exit(2)}s(_,"fail");async function Yo(e){let o=ne(e);if(o.endsWith(".json")){let n=await Xo(o,"utf8");return JSON.parse(n)}return qe({configPath:o})}s(Yo,"loadConfigFromPath");async function Ko(){let e=qo(process.argv),o=await Yo(e.configPath);if(e.check){await ze({config:o,outDir:ne(e.outDir)})||(console.error("apollion-tokens: dist/ is stale or missing (configHash mismatch). Re-run `apollion-tokens build` without --check."),process.exit(1)),console.log("apollion-tokens: dist/ is up-to-date with config.");return}let{manifest:n}=await Je({config:o,outDir:ne(e.outDir),verbose:e.verbose});console.log(`apollion-tokens: wrote ${n.files.length} file(s) \u2014 configHash=${n.configHash.slice(0,12)}\u2026`)}s(Ko,"main");Ko().catch(e=>{console.error(`apollion-tokens: ${e instanceof Error?e.message:String(e)}`),process.exit(1)});
2
+ var Ze=Object.defineProperty;var s=(e,o)=>Ze(e,"name",{value:o,configurable:!0}),Qe=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(o,n)=>(typeof require<"u"?require:o)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});import{readFile as Zo}from"node:fs/promises";import{resolve as ne}from"node:path";import{mkdir as Ue,mkdtemp as No,readFile as Lo,rename as _o,rm as We,writeFile as Je}from"node:fs/promises";import{tmpdir as Bo}from"node:os";import{dirname as ze,join as H}from"node:path";import{defaultInputBorder as G}from"@apollion-dsi/core/themes/border";import{createDeth as oo,levelValues as no}from"@apollion-dsi/core/themes/depth";import{createFont as ro,defaultInputFont as w}from"@apollion-dsi/core/themes/font";import{defaultInputSpacing as re}from"@apollion-dsi/core/themes/spacing";import{converter as to,formatHex as io,parse as so}from"culori";import{DIMENSION_MULTIPLIERS as eo}from"@apollion-dsi/core/themes/dimension";function A({multiplier:e=.25,alias:o},n){let r=n!==void 0?eo[n]:e;return(...t)=>t.map(i=>{let a=typeof i=="string"?o[i]:i;return`${r*a}rem`}).join(" ")}s(A,"createSpacing");var z={"bg.primary":{description:"Primary action surface \u2014 the brand\u2019s dominant call-to-action background."},"bg.secondary":{description:"Secondary action surface \u2014 supporting actions paired with the primary."},"bg.danger":{description:"Destructive / error surface \u2014 irreversible or failing actions."},"bg.success":{description:"Positive confirmation surface \u2014 completed or healthy states."},"bg.info":{description:"Informational surface \u2014 neutral, non-blocking notices.",deprecated:"Use bg.information once the foundation role is renamed (tracked for S6)."},"text.on-primary":{description:"Text/icon colour with guaranteed contrast over bg.primary."},"text.on-danger":{description:"Text/icon colour with guaranteed contrast over bg.danger."},"space.medium":{description:"Base spacing step (1rem at normal density) \u2014 the layout rhythm unit."},"space.large":{description:"Comfortable spacing step \u2014 section padding and card gutters."},"spacing.md":{description:"Medium foundation spacing alias \u2014 references the space.medium primitive."},"spacing.lg":{description:"Large foundation spacing alias \u2014 references the space.large primitive."},"border.radius.md":{description:"Default card corner radius."},"border.width.thin":{description:"Hairline border \u2014 dividers and default input outlines."},"border.width.regular":{description:"Standard emphasis border \u2014 focused/active controls."}};function X(e){let o=Object.keys(z).filter(n=>!e.has(n));if(o.length>0)throw new Error(`token-meta: ${o.length} stale TOKEN_META key(s) resolve to no IR node: ${o.join(", ")}. Update src/token-meta.ts to match the current IR paths.`)}s(X,"assertTokenMetaResolves");var ao=to("oklch");function b(e){return typeof e.type=="string"&&"value"in e}s(b,"isToken");function k(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}s(k,"kebab");function ie(e){return e.split(".").map(k).join(".")}s(ie,"kebabPath");function T(e){return e.kind==="ref"?e.resolved.raw:e.raw}s(T,"rawValue");function j(e,o){return Number(e.toFixed(o))||0}s(j,"round");function q(e){let o=ao(so(e));if(!o)return{kind:"color",raw:e,components:[0,0,0],hex:"#000000"};let n=[j(o.l,4),j(o.c,4),j(o.h??0,2)],r=io(o)??"#000000";return o.alpha!==void 0&&o.alpha!==1?{kind:"color",raw:e,components:n,alpha:j(o.alpha,4),hex:r}:{kind:"color",raw:e,components:n,hex:r}}s(q,"toColorValue");var se=/^(-?(?:\d+\.?\d*|\.\d+))(px|rem)$/;function D(e){let o=se.exec(e.trim());if(o)return{kind:"dimension",raw:e,value:Number(o[1]),unit:o[2]};let n=Number.parseFloat(e);return{kind:"dimension",raw:e,value:Number.isFinite(n)?n:0,unit:"rem"}}s(D,"toDimensionValue");function h(e){return{type:"color",value:q(e)}}s(h,"colorToken");function te(e){let o={};for(let[n,r]of Object.entries(e))o[n]=h(r);return o}s(te,"recordColorGroup");var co=["main","opposite","complementary","primary","secondary","tertiary","success","danger","warning","information"];function ae(e){let o={};for(let n of co){let r=e[n];o[n]={base:h(r.base),dark:h(r.dark),action:h(r.action),active:h(r.active),light:h(r.light)}}return o.grayscale=te(e.grayscale),o.neutral=te(e.neutral),o.baseDark=h(e.baseDark??"#000000"),o.baseLight=h(e.baseLight??"#ffffff"),o.deepDark=h(e.deepDark??"#000000"),o.deepLight=h(e.deepLight??"#ffffff"),o}s(ae,"buildColorPrimitives");function ce(e){let o=A(re,e),n={};for(let r of Object.keys(re.alias))n[r]={type:"dimension",value:D(o(r))};return n}s(ce,"buildSpacePrimitives");function le(){let e={};for(let[o,n]of Object.entries(G.borderWidth))e[o]={type:"dimension",value:D(n)};return e}s(le,"buildBorderWidthPrimitives");function lo(e,o){return{color:ae(e),space:ce(o),borderWidth:le()}}s(lo,"buildPrimitives");var de={primary:"color.primary.base",secondary:"color.secondary.base",tertiary:"color.tertiary.base",success:"color.success.base",danger:"color.danger.base",warning:"color.warning.base",info:"color.information.base"},ue={onPrimary:"color.baseLight",onSecondary:"color.baseLight",onTertiary:"color.baseDark",onSuccess:"color.baseLight",onDanger:"color.baseLight",onWarning:"color.baseDark",onInfo:"color.baseLight"};function uo(e,o){let n=e;for(let r of o.split(".").slice(1))if(n&&typeof n=="object"&&r in n)n=n[r];else return;return typeof n=="string"?n:void 0}s(uo,"lookupPrimitive");function E(e,o,n){let r={};for(let[t,i]of Object.entries(e)){let a=n[t],c=a?uo(o,a):void 0;r[t]=a&&c===i?{type:"color",value:{kind:"ref",path:a,resolved:q(i)}}:h(i)}return r}s(E,"colorRefGroup");var pe={xs:"space.xs",sm:"space.small",md:"space.medium",lg:"space.large",xl:"space.xl",xxl:"space.xxl"},po={none:"border-width.none",thin:"border-width.thin",regular:"border-width.regular",great:"border-width.great",bold:"border-width.bold"};function fo(e,o){let n=o.split("."),r=n[0]==="border-width"?"borderWidth":n[0],t=e[r];for(let i of n.slice(1))if(t&&!b(t)&&i in t)t=t[i];else return;return t&&b(t)&&t.value.kind==="dimension"?t.value.raw:void 0}s(fo,"lookupDimensionPrimitive");function Y(e,o,n){let r={};for(let[t,i]of Object.entries(e)){let a=n[t],c=a?fo(o,a):void 0;r[t]=a&&c===i?{type:"dimension",value:{kind:"ref",path:a,resolved:D(i)}}:{type:"dimension",value:D(i)}}return r}s(Y,"dimensionRefGroup");function fe(e){let o={},n={};for(let[i,a]of Object.entries(G.borderRadius))se.test(a)?o[i]={type:"dimension",value:D(a)}:n[i]=a;let r=Y(G.borderWidth,e,po),t={};for(let[i,a]of Object.entries(G.borderStyle))t[i]={type:"strokeStyle",value:{kind:"strokeStyle",raw:a,style:a}};return{group:{radius:o,width:r,style:t},extensions:n}}s(fe,"buildBorder");function me(e){let o=ro(w,e),n={};for(let[c,l]of Object.entries(w.fontFamily)){let f=l.replace(/;\s*$/,"").trim();n[c]={type:"fontFamily",value:{kind:"fontFamily",raw:f,family:f}}}let r={};for(let[c,l]of Object.entries(o.fontSize))r[c]={type:"dimension",value:D(l)};let t={};for(let[c,l]of Object.entries(w.fontWeight))t[c]={type:"fontWeight",value:{kind:"fontWeight",raw:`${l}`,weight:l}};let i={};for(let[c,l]of Object.entries(w.lineHeight))i[c]={type:"number",value:{kind:"number",raw:`${l}`,number:l}};let a={letterSpacing:w.letterSpacing,textTransform:w.textTransform,fontStyle:w.fontStyle};return{group:{family:n,size:r,weight:t,lineHeight:i},extensions:a}}s(me,"buildFont");var mo=/rgba?\([^)]*\)|#[0-9a-fA-F]+|[a-zA-Z]+$/;function go(e){let o=e.trim(),n=o.startsWith("inset");n&&(o=o.slice(5).trim());let r=o.match(mo),t=r?r[0]:"#000000",a=(r?o.slice(0,r.index).trim():o).split(/\s+/).filter(Boolean),c=s(l=>D(a[l]??"0px"),"dim");return{kind:"shadow",raw:e,shadow:{color:q(t),offsetX:c(0),offsetY:c(1),blur:c(2),spread:c(3),inset:n}}}s(go,"parseShadow");function ge(e){let o=oo(e),n={};for(let r of Object.keys(no))n[r]={type:"shadow",value:go(o(r))};return n}s(ge,"buildShadow");function F(e,o,n){let r={};for(let[t,i]of Object.entries(e)){let a=o?`${o}.${k(t)}`:k(t);if(b(i)){n.add(a);let c=z[a];r[t]=c&&(c.description!==void 0||c.deprecated!==void 0)?{...i,...c.description!==void 0?{description:c.description}:{},...c.deprecated!==void 0?{deprecated:c.deprecated}:{}}:i}else r[t]=F(i,a,n)}return r}s(F,"decorateGroup");function yo(e){let o=new Set,n=F(e.primitives,"",o),r=F(e.groups,"",o);return X(o),{...e,primitives:n,groups:r}}s(yo,"decorateMeta");function P(e,o){return F(e,"",o)}s(P,"decorateSlice");function ye(e,o,n){for(let[r,t]of Object.entries(e)){let i=o?`${o}.${k(r)}`:k(r);b(t)?n.add(i):ye(t,i,n)}}s(ye,"collectPaths");function he(e){let o=new Set;for(let n of e)ye(n.groups,"",o);X(o)}s(he,"assertSlicesMetaComplete");function be(){let e=le(),n=fe({borderWidth:e}),r={};Object.keys(n.extensions).length>0&&(r["com.apollion.border"]={radius:n.extensions});let t=new Set;return{groups:P({"border-width":e,border:n.group},t),extensions:r}}s(be,"buildBaseIR");function Re(e){let o=me(e),n=new Set;return{groups:P({font:o.group},n),extensions:{"com.apollion.font":o.extensions}}}s(Re,"buildFontIR");function ke(e,o){let n=ae(o),r=new Set;return{groups:P({color:n,bg:E(e.bg,o,de),text:E(e.text,o,ue),shadow:ge(o)},r),extensions:{}}}s(ke,"buildColorIR");function Ie(e,o){let n=ce(o),r={space:n},t=new Set;return{groups:P({space:n,spacing:Y(e.spacing,r,pe)},t),extensions:{}}}s(Ie,"buildSpacingIR");function ho(e,o,n){let r={brand:n.brand,mode:n.mode,surface:n.surface,dimension:n.dimension},t=lo(o,n.dimension),i=fe(t),a=me(n.dimension),c={"com.apollion.variant":r,"com.apollion.font":a.extensions};Object.keys(i.extensions).length>0&&(c["com.apollion.border"]={radius:i.extensions});let l={description:`Apollion DS tokens \u2014 DTCG 2025.10. Variant: ${r.brand}/${r.mode}/${r.surface}/${r.dimension}.`,meta:r,primitives:t,groups:{bg:E(e.bg,o,de),text:E(e.text,o,ue),spacing:Y(e.spacing,t,pe),border:i.group,font:a.group,shadow:ge(o)},extensions:c};return yo(l)}s(ho,"buildIR");var Se=ho;var bo="/* Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs. */";function xe(e,o,n){for(let[r,t]of Object.entries(e)){let i=[...o,k(r)];b(t)?n.push(` --apollion-${i.join("-")}: ${T(t.value)};`):xe(t,i,n)}}s(xe,"emitVars");function we(e,o,n){for(let[r,t]of Object.entries(e)){let i=[...o,k(r)];b(t)?t.type==="color"&&n.push(` @property --apollion-${i.join("-")} { syntax: '<color>'; inherits: true; initial-value: ${T(t.value)}; }`):we(t,i,n)}}s(we,"emitProperties");function De(e){let{brand:o,mode:n,surface:r,dimension:t}=e.meta,i=[bo,""];return i.push(`/* Variant: brand=${o} mode=${n} surface=${r} dimension=${t} */`,"",":root {"),xe(e.groups,[],i),i.push("}",""),i.push("@supports (background: paint(squircle)) or (color: oklch(0% 0 0)) {"),we(e.groups,[],i),i.push("}",""),i.join(`
3
+ `)}s(De,"renderCss");function ve(e){return e.alpha!==void 0?{colorSpace:"oklch",components:[...e.components],alpha:e.alpha,hex:e.hex}:{colorSpace:"oklch",components:[...e.components],hex:e.hex}}s(ve,"colorValue");function C(e){return{value:e.value,unit:e.unit}}s(C,"dimensionValue");function Ro(e){let o=e.shadow,n={color:ve(o.color),offsetX:C(o.offsetX),offsetY:C(o.offsetY),blur:C(o.blur),spread:C(o.spread)};return o.inset&&(n.inset=!0),n}s(Ro,"shadowValue");function ko(e){switch(e.kind){case"ref":return`{${ie(e.path)}}`;case"color":return ve(e);case"dimension":return C(e);case"fontFamily":return e.family;case"fontWeight":return e.weight;case"number":return e.number;case"strokeStyle":return e.style;case"shadow":return Ro(e)}}s(ko,"projectValue");function Io(e){let o={$value:ko(e.value),$type:e.type};return e.description!==void 0&&(o.$description=e.description),e.deprecated!==void 0&&(o.$deprecated=e.deprecated),o}s(Io,"projectToken");function K(e){let o={};for(let[n,r]of Object.entries(e))o[k(n)]=b(r)?Io(r):K(r);return o}s(K,"projectGroup");function M(e,o){let n={$description:o,...K(e.groups)};return Object.keys(e.extensions).length>0&&(n.$extensions=e.extensions),`${JSON.stringify(n,null,2)}
4
+ `}s(M,"renderSet");function Te(e){return M(e,"Apollion DS \u2014 base set (axis-invariant: border). DTCG 2025.10.")}s(Te,"renderBaseSet");function Ce(e,o,n,r){return M(e,`Apollion DS \u2014 colour set. brand=${o} mode=${n} surface=${r}. DTCG 2025.10.`)}s(Ce,"renderColorSet");function $e(e,o){return M(e,`Apollion DS \u2014 spacing set. dimension=${o}. DTCG 2025.10.`)}s($e,"renderSpacingSet");function Ve(e,o){return M(e,`Apollion DS \u2014 font set. dimension=${o}. DTCG 2025.10.`)}s(Ve,"renderFontSet");function Oe(e,o){let{modifiers:n}=o,r=[{name:"brand",values:[...n.brand],default:n.brand[0]},{name:"mode",values:[...n.mode],default:n.mode[0]},{name:"surface",values:[...n.surface],default:n.surface[0]},{name:"dimension",values:[...n.dimension],default:n.dimension[0]}],i={name:"apollion-tokens",description:"Apollion DS token resolver \u2014 DTCG 2025.10. Compose the base set with the colour set for the chosen brand/mode/surface and the spacing + font sets for the chosen dimension. NOTE: mode is a topology placeholder in this release (dark resolves identically to light until S6).",sets:[{name:o.base.name,source:o.base.file},...o.spacing.map(a=>({name:a.name,source:a.file})),...o.font.map(a=>({name:a.name,source:a.file})),...o.color.map(a=>({name:a.name,source:a.file}))],modifiers:r,$extensions:{"com.apollion.resolver":{composition:{always:[o.base.name],byModifier:{color:"${brand}.color.${mode}.${surface}",spacing:"spacing.${dimension}",font:"font.${dimension}"}},modeIsPlaceholder:!0}}};return`${JSON.stringify(i,null,2)}
5
+ `}s(Oe,"renderResolver");var So="// Generated by apollion-tokens build \u2014 DO NOT EDIT. See apollion.config.mjs.";function Ae(e,o,n){let r=" ".repeat(o);for(let[t,i]of Object.entries(e))b(i)?n.push(`${r}${JSON.stringify(t)}: ${JSON.stringify(T(i.value))},`):(n.push(`${r}${t}: {`),Ae(i,o+1,n),n.push(`${r}},`))}s(Ae,"emitGroup");function je(e){let{brand:o,mode:n,surface:r,dimension:t}=e.meta,i=[So,`// Variant: brand=${o} mode=${n} surface=${r} dimension=${t}`,"","export const tokens = {"];return Ae(e.groups,1,i),i.push("} as const;","","export type Tokens = typeof tokens;",""),i.join(`
6
+ `)}s(je,"renderTs");var xo=["light","dark"],wo=["positive","negative"],Do=["compact","normal","spacious"];function N(e){let o=e.modes??xo,n=e.surfaces??wo,r=e.dimensions??Do,t=Object.entries(e.brands).sort(([a],[c])=>a.localeCompare(c)),i=[];for(let[a,c]of t)for(let l of o)for(let f of n)for(let x of r)i.push({brand:a,colors:c,mode:l,surface:f,dimension:x});return i}s(N,"expandVariants");function Ge(e){return`${e.brand}.${e.mode}.${e.surface}.${e.dimension}`}s(Ge,"variantName");import{createHash as vo}from"node:crypto";function Q(e){return vo("sha256").update(e).digest("hex")}s(Q,"sha256");function ee(e){return Q(Z(e))}s(ee,"hashConfig");function Z(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(Z).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${Z(e[r])}`).join(",")}}`}s(Z,"stableStringify");function Ee(e){try{let{execSync:o}=Qe("node:child_process");return o("git rev-parse --short HEAD",{cwd:e,stdio:["ignore","pipe","ignore"],encoding:"utf8"}).trim()}catch{return""}}s(Ee,"detectGitCommit");function Fe(){return{node:process.version,platform:`${process.platform}-${process.arch}`}}s(Fe,"buildEnv");function Pe(e){let o=[...e.files].sort((r,t)=>r.path.localeCompare(t.path)),n={configHash:e.configHash,files:o,gitCommit:e.gitCommit,buildEnv:e.buildEnv};return`${JSON.stringify(n,null,2)}
7
+ `}s(Pe,"serializeManifest");var To="json/sets",Me="json/resolver.json";function L(e){return`${To}/${e}.json`}s(L,"setFile");function Co(e,o,n){return`${e}.color.${o}.${n}`}s(Co,"colorSetName");function $o(e){return`spacing.${e}`}s($o,"spacingSetName");function Vo(e){return`font.${e}`}s(Vo,"fontSetName");function _(e,o){e.includes(o)||e.push(o)}s(_,"pushUnique");function Ne(e){let o=N(e),n=[],r=[],t=[],i=[],a=new Set,c=[],l=new Set,f=[],x=new Set,$=[];for(let u of o){_(n,u.brand),_(r,u.mode),_(t,u.surface),_(i,u.dimension);let g=Co(u.brand,u.mode,u.surface);a.has(g)||(a.add(g),c.push({kind:"color",name:g,file:L(g),brand:u.brand,mode:u.mode,surface:u.surface}));let I=$o(u.dimension);l.has(I)||(l.add(I),f.push({kind:"spacing",name:I,file:L(I),dimension:u.dimension}));let p=Vo(u.dimension);x.has(p)||(x.add(p),$.push({kind:"font",name:p,file:L(p),dimension:u.dimension}))}return{base:{kind:"base",name:"base",file:L("base")},spacing:f,font:$,color:c,modifiers:{brand:n,mode:r,surface:t,dimension:i}}}s(Ne,"planSets");import{createFoundation as He}from"@apollion-dsi/core/themes/foundation";import{createSemantic as Eo}from"@apollion-dsi/core/themes/semantic";import{defaultInputSpacing as Fo}from"@apollion-dsi/core/themes/spacing";import{invertForSurface as Po}from"@apollion-dsi/core/themes/surface";import{converter as Oo,formatHex as Ao,interpolate as jo,parse as Le}from"culori";var Nn=Oo("oklch");function d(e,o,n){let r=Le(e),t=Le(o);if(!r||!t)return e;let i=jo([r,t],"oklch");return Ao(i(n))??e}s(d,"mixOklch");function Go(e){return e?typeof e=="string"?e:e.base:"#000"}s(Go,"coerceToHex");function R(e,o){let n=Go(e),r=o.deepDark,t=o.deepLight;return{base:n,dark:d(n,r,.6),action:d(n,r,.2),active:d(n,t,.6),light:d(n,t,.9)}}s(R,"mountSingleColor");function _e(e){let o=e.deepLight,n=e.deepDark;return{0:o,5:d(o,n,.05),10:d(o,n,.1),20:d(o,n,.2),30:d(o,n,.3),40:d(o,n,.4),50:d(o,n,.5),60:d(o,n,.6),70:d(o,n,.7),80:d(o,n,.8),90:d(o,n,.9),100:d(o,n,1)}}s(_e,"mountGreyscaleColors");function Be(e){let o=e.deepLight,n=e.deepDark,r=e.primary,t=s(a=>1/17*(a-1),"interpolation"),i=d(r,n,.5);return{0:d(i,o,t(18)),5:d(i,o,t(17.5)),10:d(i,o,t(17)),20:d(i,o,t(16)),30:d(i,o,t(15)),40:d(i,o,t(14)),50:d(i,o,t(13)),60:d(i,o,t(12)),70:d(i,o,t(11)),80:d(i,o,t(10)),90:d(i,o,t(9)),100:d(i,o,t(8)),110:d(i,o,t(7)),120:d(i,o,t(6)),130:d(i,o,t(5)),140:d(i,o,t(4)),150:d(i,o,t(3)),160:d(i,o,t(2)),170:i,180:d(i,n,.25)}}s(Be,"mountNeutralColors");function Mo(e){return{baseDark:e.baseDark,baseLight:e.baseLight,deepDark:e.deepDark,deepLight:e.deepLight,transparent:e.transparent??"transparent",neutral:Be(e),grayscale:_e(e),main:R(e.main,e),opposite:R(e.opposite,e),complementary:R(e.complementary,e),danger:R(e.danger,e),information:R(e.information,e),success:R(e.success,e),warning:R(e.warning,e),primary:R(e.primary,e),secondary:R(e.secondary,e),tertiary:R(e.tertiary,e)}}s(Mo,"composeColors");function B(e,o=Fo){let n=Mo(e.colors),r=A(o,e.dimension),t=Eo({colors:n,spacing:r}),i=He(t);return e.surface==="negative"&&(i=He(Po({semantic:t,colors:n},"negative").semantic)),{foundation:i,colors:n}}s(B,"buildVariantThemes");async function Xe(e){let{config:o,outDir:n,cwd:r=process.cwd(),verbose:t=!1}=e,i=N(o),a=o.output??{};if(i.length===0)throw new Error("apollion-tokens build: no variants (config.brands is empty)");let c=await No(H(Bo(),"apollion-tokens-"));try{let l=[],f=s(async(u,g)=>{await Ho(c,u,g),l.push({path:u,sha256:Q(g)}),t&&console.log(` \u2713 ${u}`)},"emit");if(a.json){let u=Ne(o),g=[],I=be();g.push(I),await f(u.base.file,Te(I));for(let p of u.spacing){let S=i.find(O=>O.dimension===p.dimension),{foundation:U}=B(S),V=Ie(U,p.dimension);g.push(V),await f(p.file,$e(V,p.dimension))}for(let p of u.font){let S=Re(p.dimension);g.push(S),await f(p.file,Ve(S,p.dimension))}for(let p of u.color){let S=i.find(J=>J.brand===p.brand&&J.mode===p.mode&&J.surface===p.surface),{foundation:U,colors:V}=B(S),O=ke(U,V);g.push(O),await f(p.file,Ce(O,p.brand,p.mode,p.surface))}he(g),await f(Me,Oe(o,u))}if(a.css||a.ts)for(let u of i){let{foundation:g,colors:I}=B(u),p=Se(g,I,u),S=Ge(u);a.css&&await f(`css/${S}.css`,De(p)),a.ts&&await f(`ts/${S}.d.ts`,je(p))}let x={configHash:ee(o),files:l,gitCommit:Ee(r),buildEnv:Fe()},$=Pe(x);return await Je(H(c,"manifest.json"),$),await We(n,{recursive:!0,force:!0}),await Ue(ze(n),{recursive:!0}),await _o(c,n),t&&console.log(`\u2713 ${l.length} files \u2192 ${n}`),{manifest:x,outDir:n}}catch(l){throw await We(c,{recursive:!0,force:!0}).catch(()=>{}),l}}s(Xe,"build");async function qe(e){let{config:o,outDir:n}=e,r;try{r=JSON.parse(await Lo(H(n,"manifest.json"),"utf8"))}catch{return!1}return r.configHash===ee(o)}s(qe,"check");async function Ho(e,o,n){let r=H(e,o);await Ue(ze(r),{recursive:!0}),await Je(r,n)}s(Ho,"writeAt");import{readFile as Uo}from"node:fs/promises";import{resolve as Jo}from"node:path";import{createContext as zo,Script as Xo}from"node:vm";import{z as m}from"zod";var y=m.string().regex(/^#([0-9a-fA-F]{3}){1,2}$|^transparent$|^rgb\(.*\)$|^oklch\(.*\)$/,{message:'Must be hex, rgb(), oklch(), or "transparent"'}),Wo=m.object({baseDark:m.string().optional(),baseLight:m.string().optional(),deepDark:y,deepLight:y,transparent:m.string().optional(),main:y.optional(),opposite:y.optional(),complementary:y.optional(),information:y.optional(),success:y.optional(),danger:y.optional(),warning:y.optional(),primary:y.optional(),secondary:y.optional(),tertiary:y.optional()}).passthrough(),Ye=m.object({brands:m.record(m.string(),Wo).refine(e=>Object.keys(e).length>0,{message:"apollion.config.mjs: brands must contain at least 1 entry"}),modes:m.array(m.enum(["light","dark"])).optional(),surfaces:m.array(m.enum(["positive","negative"])).optional(),dimensions:m.array(m.enum(["compact","normal","spacious"])).optional(),output:m.object({runtime:m.boolean().optional(),css:m.boolean().optional(),json:m.boolean().optional(),ts:m.boolean().optional()}).passthrough().optional()}).passthrough();var qo=[/\brequire\s*\(/,/\bimport\s*\(/,/^\s*import\s+/m],Yo=1e3;var oe=class oe extends Error{constructor(n,r){super(n);this.configPath=r;this.name="ConfigLoadError"}};s(oe,"ConfigLoadError");var v=oe;async function Ke(e){let o=Jo(e.configPath),n=await Uo(o,"utf8");for(let l of qo)if(l.test(n))throw new v(`apollion.config: dynamic require/import not allowed (matched ${l}). Declarative config only \u2014 see ADR-006 \xA73.8 B3.`,o);let r=n.replace(/(^|\n)\s*export\s+default\s+/,(l,f)=>`${f}__apollion_config_export = `);if(r===n)throw new v("apollion.config: missing `export default <object>;` \u2014 config must export a default object literal.",o);let t={__apollion_config_export:void 0,console:Ko(),Symbol,Number,String,Boolean,Array,Object,JSON,Math,defineConfig:s(l=>l,"defineConfig")},i=zo(t);try{new Xo(r,{filename:o}).runInContext(i,{timeout:Yo})}catch(l){throw new v(`apollion.config: evaluation failed \u2014 ${l instanceof Error?l.message:String(l)}`,o)}let a=t.__apollion_config_export;if(a===void 0)throw new v("apollion.config: `export default` produced undefined.",o);let c=Ye.safeParse(a);if(!c.success){let l=c.error.issues.map(f=>` ${f.path.join(".")||"(root)"}: ${f.message}`).join(`
8
+ `);throw new v(`apollion.config: schema validation failed \u2014
9
+ ${l}`,o)}return c.data}s(Ke,"loadConfig");function Ko(){return{log:s((...e)=>console.log("[apollion.config]",...e),"log"),warn:s((...e)=>console.warn("[apollion.config]",...e),"warn"),error:s((...e)=>console.error("[apollion.config]",...e),"error")}}s(Ko,"makeReadOnlyConsole");function Qo(e){let o=e.slice(2),n=o[0];n!=="build"&&W(`Unknown command "${n??""}". Usage: apollion-tokens build [--check] [--verbose] --config <path> [--out <dir>]`);let r="apollion.config.mjs",t="dist",i=!1,a=!1;for(let c=1;c<o.length;c++){let l=o[c];switch(l){case"--config":r=o[++c]??W("--config needs a path");break;case"--out":t=o[++c]??W("--out needs a path");break;case"--check":i=!0;break;case"--verbose":a=!0;break;default:W(`Unknown flag "${l}"`)}}return{command:n,configPath:r,outDir:t,check:i,verbose:a}}s(Qo,"parseArgs");function W(e){console.error(`apollion-tokens: ${e}`),process.exit(2)}s(W,"fail");async function en(e){let o=ne(e);if(o.endsWith(".json")){let n=await Zo(o,"utf8");return JSON.parse(n)}return Ke({configPath:o})}s(en,"loadConfigFromPath");async function on(){let e=Qo(process.argv),o=await en(e.configPath);if(e.check){await qe({config:o,outDir:ne(e.outDir)})||(console.error("apollion-tokens: dist/ is stale or missing (configHash mismatch). Re-run `apollion-tokens build` without --check."),process.exit(1)),console.log("apollion-tokens: dist/ is up-to-date with config.");return}let{manifest:n}=await Xe({config:o,outDir:ne(e.outDir),verbose:e.verbose});console.log(`apollion-tokens: wrote ${n.files.length} file(s) \u2014 configHash=${n.configHash.slice(0,12)}\u2026`)}s(on,"main");on().catch(e=>{console.error(`apollion-tokens: ${e instanceof Error?e.message:String(e)}`),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apollion-dsi/tokens",
3
- "version": "4.4.0",
3
+ "version": "4.5.1",
4
4
  "description": "Apollion Design System — Framework-agnostic design tokens",
5
5
  "homepage": "https://github.com/apollion-ds/apollion",
6
6
  "license": "MIT",
package/src/build.ts CHANGED
@@ -9,9 +9,9 @@
9
9
  *
10
10
  * **Output surfaces (R5):**
11
11
  * - `dist/json/` — DTCG **Resolver**: `resolver.json` + reference-closed
12
- * `sets/{base, spacing.<dimension>, <brand>.color.<mode>.<surface>}.json`.
12
+ * `sets/{base, spacing.<dimension>, font.<dimension>, <brand>.color.<mode>.<surface>}.json`.
13
13
  * Hard cutover from the old per-variant JSON (pre-4.0 GA — no consumer reads
14
- * `dist/json/*` yet). One manifest + O(b·m·s + d + 1) sets, not b·m·s·d docs.
14
+ * `dist/json/*` yet). One manifest + O(b·m·s + 2·d + 1) sets, not b·m·s·d docs.
15
15
  * - `dist/css/` + `dist/ts/` — per-variant, fully resolved (unchanged).
16
16
  *
17
17
  * **Idempotency contract:** rerunning with the same `(config, gitHead,
@@ -31,12 +31,12 @@ import { tmpdir } from 'node:os';
31
31
  import { dirname, join } from 'node:path';
32
32
 
33
33
  import { renderCss } from './renderers/css';
34
- import { renderBaseSet, renderColorSet, renderResolver, renderSpacingSet } from './renderers/resolver';
34
+ import { renderBaseSet, renderColorSet, renderFontSet, renderResolver, renderSpacingSet } from './renderers/resolver';
35
35
  import { renderTs } from './renderers/ts';
36
36
  import type { ApollionConfig, Variant } from './config-schema';
37
37
  import { expandVariants, variantName } from './config-schema';
38
38
  import type { IRSlice } from './ir';
39
- import { assertSlicesMetaComplete, buildBaseIR, buildColorIR, buildFullIR, buildSpacingIR } from './ir';
39
+ import { assertSlicesMetaComplete, buildBaseIR, buildColorIR, buildFontIR, buildFullIR, buildSpacingIR } from './ir';
40
40
  import type { BuildManifest, ManifestFileEntry } from './manifest';
41
41
  import { buildEnv, detectGitCommit, hashConfig, serializeManifest, sha256 } from './manifest';
42
42
  import { planSets, RESOLVER_PATH } from './set-plan';
@@ -76,7 +76,7 @@ export async function build(opts: BuildOptions): Promise<BuildResult> {
76
76
 
77
77
  // ── JSON surface (R5): Resolver manifest + reference-closed sets ─────────
78
78
  // Hard cutover — no per-variant JSON. The base set is axis-invariant; colour
79
- // sets vary by (brand × mode × surface); spacing sets vary by dimension.
79
+ // sets vary by (brand × mode × surface); spacing + font sets vary by dimension.
80
80
  // bg/text are dimension-invariant and spacing is brand/surface-invariant, so
81
81
  // a single representative variant resolves each set's foundation.
82
82
  if (output.json) {
@@ -95,6 +95,14 @@ export async function build(opts: BuildOptions): Promise<BuildResult> {
95
95
  await emit(set.file, renderSpacingSet(slice, set.dimension));
96
96
  }
97
97
 
98
+ // Font sets are dimension-keyed like spacing (ADR-011), but the scale is
99
+ // self-contained (no foundation refs), so the slice needs only the dimension.
100
+ for (const set of plan.font) {
101
+ const slice = buildFontIR(set.dimension);
102
+ slices.push(slice);
103
+ await emit(set.file, renderFontSet(slice, set.dimension));
104
+ }
105
+
98
106
  for (const set of plan.color) {
99
107
  const variant = variants.find(
100
108
  (v) => v.brand === set.brand && v.mode === set.mode && v.surface === set.surface,
package/src/ir.ts CHANGED
@@ -31,7 +31,7 @@
31
31
  import { defaultInputBorder } from '@apollion-dsi/core/themes/border';
32
32
  import { createDeth, levelValues } from '@apollion-dsi/core/themes/depth';
33
33
  import type { Dimension } from '@apollion-dsi/core/themes/dimension';
34
- import { defaultInputFont } from '@apollion-dsi/core/themes/font';
34
+ import { createFont, defaultInputFont } from '@apollion-dsi/core/themes/font';
35
35
  import type { FoundationLayer } from '@apollion-dsi/core/themes/foundation';
36
36
  import type { SpacingAlias } from '@apollion-dsi/core/themes/spacing';
37
37
  import { defaultInputSpacing } from '@apollion-dsi/core/themes/spacing';
@@ -435,17 +435,26 @@ function buildBorder(primitives: IRGroup): { group: IRGroup; extensions: Record<
435
435
  return { group: { radius, width, style }, extensions: extRadius };
436
436
  }
437
437
 
438
- /** Font scales: family/size/weight/lineHeight as DTCG types; non-DTCG bits
439
- * (letterSpacing/textTransform/fontStyle) go to `$extensions`. */
440
- function buildFont(): { group: IRGroup; extensions: Record<string, unknown> } {
438
+ /**
439
+ * Font scales: family/size/weight/lineHeight as DTCG types; non-DTCG bits
440
+ * (letterSpacing/textTransform/fontStyle) go to `$extensions`.
441
+ *
442
+ * **ADR-011:** `size` is now density-aware. Built with the SAME `dimension` the
443
+ * variant uses (`createFont`), so a `font.size.*` token emits the resolved `rem`
444
+ * value for that density (e.g. `medium = 1.25rem` at normal, `1rem` at compact),
445
+ * mirroring `buildSpacePrimitives`. `family/weight/lineHeight` stay axis-invariant
446
+ * — they're identical across dimensions, just carried in each font set.
447
+ */
448
+ function buildFont(dimension: Dimension): { group: IRGroup; extensions: Record<string, unknown> } {
449
+ const resolved = createFont(defaultInputFont, dimension);
441
450
  const family: Record<string, IRToken> = {};
442
451
  for (const [key, value] of Object.entries(defaultInputFont.fontFamily)) {
443
452
  const clean = value.replace(/;\s*$/, '').trim();
444
453
  family[key] = { type: 'fontFamily', value: { kind: 'fontFamily', raw: clean, family: clean } };
445
454
  }
446
455
  const size: Record<string, IRToken> = {};
447
- for (const [key, value] of Object.entries(defaultInputFont.fontSize)) {
448
- size[key] = { type: 'dimension', value: { kind: 'dimension', raw: `${value}px`, value, unit: 'px' } };
456
+ for (const [key, value] of Object.entries(resolved.fontSize)) {
457
+ size[key] = { type: 'dimension', value: toDimensionValue(value) };
449
458
  }
450
459
  const weight: Record<string, IRToken> = {};
451
460
  for (const [key, value] of Object.entries(defaultInputFont.fontWeight)) {
@@ -565,9 +574,10 @@ function decorateMeta(doc: IRDocument): IRDocument {
565
574
  //
566
575
  // Closure invariant: each slice contains BOTH the primitives it introduces and
567
576
  // the foundation groups that reference them, so a set is self-resolving:
568
- // - base → border (+ `border-width.*` it references) + font [axis-invariant]
577
+ // - base → border (+ `border-width.*` it references) [axis-invariant]
569
578
  // - color → `color.*` primitives + bg/text (refs) + shadow [brand×mode×surface]
570
579
  // - spacing → `space.*` primitives + spacing (refs) [dimension]
580
+ // - font → font scale (size density-aware, ADR-011) [dimension]
571
581
  // `decorateMeta` runs per-slice to attach prose; the build asserts the UNION of
572
582
  // all emitted paths is meta-complete (a single set is intentionally partial).
573
583
  // ───────────────────────────────────────────────────────────────────────────
@@ -608,27 +618,43 @@ export function assertSlicesMetaComplete(slices: readonly IRSlice[]): void {
608
618
  }
609
619
 
610
620
  /**
611
- * Axis-invariant base slice: border (radius/width/style) + font. `border.width`
621
+ * Axis-invariant base slice: border (radius/width/style). `border.width`
612
622
  * references the `border-width.*` primitives, which travel WITH this slice
613
623
  * (`border-width` namespace) so the set is reference-closed. Identical for every
614
624
  * brand/mode/surface/dimension.
625
+ *
626
+ * **ADR-011:** font left the base set — its `size` scale is now density-aware,
627
+ * so it lives in per-dimension `font.<dimension>` sets ({@link buildFontIR}),
628
+ * symmetric with spacing.
615
629
  */
616
630
  export function buildBaseIR(): IRSlice {
617
631
  const borderWidth = buildBorderWidthPrimitives();
618
632
  const primitives: IRGroup = { borderWidth };
619
633
  const border = buildBorder(primitives);
620
- const font = buildFont();
621
634
 
622
- const extensions: Record<string, unknown> = { 'com.apollion.font': font.extensions };
635
+ const extensions: Record<string, unknown> = {};
623
636
  if (Object.keys(border.extensions).length > 0) {
624
637
  extensions['com.apollion.border'] = { radius: border.extensions };
625
638
  }
626
639
 
627
640
  const seen = new Set<string>();
628
- const groups = decorateSlice({ 'border-width': borderWidth, border: border.group, font: font.group }, seen);
641
+ const groups = decorateSlice({ 'border-width': borderWidth, border: border.group }, seen);
629
642
  return { groups, extensions };
630
643
  }
631
644
 
645
+ /**
646
+ * Font slice for one dimension: the typographic scale built with that dimension's
647
+ * multiplier (ADR-011). Mirrors {@link buildSpacingIR} — font joined the density
648
+ * axis, so it is no longer part of the axis-invariant base set. The non-DTCG bits
649
+ * (letterSpacing/textTransform/fontStyle) ride along in `$extensions`.
650
+ */
651
+ export function buildFontIR(dimension: Dimension): IRSlice {
652
+ const font = buildFont(dimension);
653
+ const seen = new Set<string>();
654
+ const groups = decorateSlice({ font: font.group }, seen);
655
+ return { groups, extensions: { 'com.apollion.font': font.extensions } };
656
+ }
657
+
632
658
  /**
633
659
  * Colour slice for one (brand × mode × surface): the `color.*` palette SSOT plus
634
660
  * the `bg`/`text` foundation aliases (which reference it) and `shadow`. `mode` is
@@ -686,7 +712,7 @@ export function buildIR(foundation: FoundationLayer, colors: ColorsThemeInterfac
686
712
  };
687
713
  const primitives = buildPrimitives(colors, variant.dimension);
688
714
  const border = buildBorder(primitives);
689
- const font = buildFont();
715
+ const font = buildFont(variant.dimension);
690
716
 
691
717
  const extensions: Record<string, unknown> = { 'com.apollion.variant': meta, 'com.apollion.font': font.extensions };
692
718
  if (Object.keys(border.extensions).length > 0) {
@@ -7,15 +7,16 @@
7
7
  * files (`sets`) and a set of `modifiers` (enumerated axes with a `default`); a
8
8
  * consumer composes the chosen modifier values into a single resolved token
9
9
  * tree. This replaces the old N-file per-variant JSON explosion with one
10
- * manifest + O(brand·mode·surface + dimension + 1) sets.
10
+ * manifest + O(brand·mode·surface + 2·dimension + 1) sets (spacing + font per
11
+ * dimension).
11
12
  *
12
13
  * **S5 mode caveat:** `mode` is emitted as a real modifier (values + default)
13
14
  * even though palette generation is currently mode-agnostic (dark == light).
14
15
  * The topology is therefore correct ahead of S6 wiring real dark-mode logic.
15
16
  *
16
17
  * Set documents are projected from `IRSlice`s via the shared `dtcg-project`
17
- * mapping, so a composed (base + color + spacing) tree is byte-equivalent to the
18
- * old full per-variant document (asserted in `resolver.test.ts`).
18
+ * mapping, so a composed (base + color + spacing + font) tree is byte-equivalent
19
+ * to the old full per-variant document (asserted in `resolver.test.ts`).
19
20
  *
20
21
  * @see ../ir.ts (slices) · ./dtcg-project.ts · ../set-plan.ts
21
22
  * @see https://www.designtokens.org/TR/ (Resolver draft)
@@ -58,9 +59,9 @@ function renderSet(slice: IRSlice, description: string): string {
58
59
  return `${JSON.stringify(doc, null, 2)}\n`;
59
60
  }
60
61
 
61
- /** Axis-invariant base set (border + font). */
62
+ /** Axis-invariant base set (border). */
62
63
  export function renderBaseSet(slice: IRSlice): string {
63
- return renderSet(slice, 'Apollion DS — base set (axis-invariant: border + font). DTCG 2025.10.');
64
+ return renderSet(slice, 'Apollion DS — base set (axis-invariant: border). DTCG 2025.10.');
64
65
  }
65
66
 
66
67
  /** Colour set for one (brand × mode × surface). */
@@ -73,6 +74,11 @@ export function renderSpacingSet(slice: IRSlice, dimension: string): string {
73
74
  return renderSet(slice, `Apollion DS — spacing set. dimension=${dimension}. DTCG 2025.10.`);
74
75
  }
75
76
 
77
+ /** Font set for one dimension (size density-aware, ADR-011). */
78
+ export function renderFontSet(slice: IRSlice, dimension: string): string {
79
+ return renderSet(slice, `Apollion DS — font set. dimension=${dimension}. DTCG 2025.10.`);
80
+ }
81
+
76
82
  /**
77
83
  * Render the Resolver manifest (`resolver.json`).
78
84
  *
@@ -96,6 +102,7 @@ export function renderResolver(config: ApollionConfig, plan: SetPlan): string {
96
102
  const sets: ResolverSet[] = [
97
103
  { name: plan.base.name, source: plan.base.file },
98
104
  ...plan.spacing.map((s) => ({ name: s.name, source: s.file })),
105
+ ...plan.font.map((f) => ({ name: f.name, source: f.file })),
99
106
  ...plan.color.map((c) => ({ name: c.name, source: c.file })),
100
107
  ];
101
108
 
@@ -103,9 +110,9 @@ export function renderResolver(config: ApollionConfig, plan: SetPlan): string {
103
110
  name: 'apollion-tokens',
104
111
  description:
105
112
  'Apollion DS token resolver — DTCG 2025.10. Compose the base set with the ' +
106
- 'colour set for the chosen brand/mode/surface and the spacing set for the ' +
107
- 'chosen dimension. NOTE: mode is a topology placeholder in this release ' +
108
- '(dark resolves identically to light until S6).',
113
+ 'colour set for the chosen brand/mode/surface and the spacing + font sets ' +
114
+ 'for the chosen dimension. NOTE: mode is a topology placeholder in this ' +
115
+ 'release (dark resolves identically to light until S6).',
109
116
  sets,
110
117
  modifiers: modifierList,
111
118
  $extensions: {
@@ -118,6 +125,8 @@ export function renderResolver(config: ApollionConfig, plan: SetPlan): string {
118
125
  color: '${brand}.color.${mode}.${surface}',
119
126
  // spacing set name = `spacing.<dimension>`
120
127
  spacing: 'spacing.${dimension}',
128
+ // font set name = `font.<dimension>` (size density-aware, ADR-011)
129
+ font: 'font.${dimension}',
121
130
  },
122
131
  },
123
132
  modeIsPlaceholder: true,
package/src/set-plan.ts CHANGED
@@ -7,11 +7,12 @@
7
7
  * drift between the two. Derived purely from the expanded variants of a config.
8
8
  *
9
9
  * **Set topology** (each set is reference-closed, see `ir.ts` slices):
10
- * - `base` — 1 file, axis-invariant (border + font).
10
+ * - `base` — 1 file, axis-invariant (border).
11
11
  * - `spacing.<dimension>` — one per dimension.
12
+ * - `font.<dimension>` — one per dimension (size density-aware, ADR-011).
12
13
  * - `<brand>.color.<mode>.<surface>` — one per (brand × mode × surface).
13
14
  *
14
- * @see ir.ts (`buildBaseIR` / `buildColorIR` / `buildSpacingIR`)
15
+ * @see ir.ts (`buildBaseIR` / `buildColorIR` / `buildSpacingIR` / `buildFontIR`)
15
16
  * @see renderers/resolver.ts (manifest) · build.ts (set emission)
16
17
  */
17
18
 
@@ -43,6 +44,14 @@ export interface SpacingSetPlan {
43
44
  readonly dimension: Dimension;
44
45
  }
45
46
 
47
+ /** A font set keyed by its dimension (size density-aware, ADR-011). */
48
+ export interface FontSetPlan {
49
+ readonly kind: 'font';
50
+ readonly name: string;
51
+ readonly file: string;
52
+ readonly dimension: Dimension;
53
+ }
54
+
46
55
  /** The axis-invariant base set. */
47
56
  export interface BaseSetPlan {
48
57
  readonly kind: 'base';
@@ -53,6 +62,7 @@ export interface BaseSetPlan {
53
62
  export interface SetPlan {
54
63
  readonly base: BaseSetPlan;
55
64
  readonly spacing: readonly SpacingSetPlan[];
65
+ readonly font: readonly FontSetPlan[];
56
66
  readonly color: readonly ColorSetPlan[];
57
67
  /** Distinct modifier values (declaration/encounter order), for the manifest. */
58
68
  readonly modifiers: {
@@ -78,6 +88,11 @@ export function spacingSetName(dimension: Dimension): string {
78
88
  return `spacing.${dimension}`;
79
89
  }
80
90
 
91
+ /** Stable font-set name for a dimension: `font.<dimension>`. */
92
+ export function fontSetName(dimension: Dimension): string {
93
+ return `font.${dimension}`;
94
+ }
95
+
81
96
  /** Push `value` onto `list` if absent — preserves first-encounter order. */
82
97
  function pushUnique<T>(list: T[], value: T): void {
83
98
  if (!list.includes(value)) list.push(value);
@@ -100,6 +115,8 @@ export function planSets(config: ApollionConfig): SetPlan {
100
115
  const color: ColorSetPlan[] = [];
101
116
  const spacingSeen = new Set<string>();
102
117
  const spacing: SpacingSetPlan[] = [];
118
+ const fontSeen = new Set<string>();
119
+ const font: FontSetPlan[] = [];
103
120
 
104
121
  for (const v of variants) {
105
122
  pushUnique(brands, v.brand);
@@ -125,11 +142,18 @@ export function planSets(config: ApollionConfig): SetPlan {
125
142
  spacingSeen.add(sName);
126
143
  spacing.push({ kind: 'spacing', name: sName, file: setFile(sName), dimension: v.dimension });
127
144
  }
145
+
146
+ const fName = fontSetName(v.dimension);
147
+ if (!fontSeen.has(fName)) {
148
+ fontSeen.add(fName);
149
+ font.push({ kind: 'font', name: fName, file: setFile(fName), dimension: v.dimension });
150
+ }
128
151
  }
129
152
 
130
153
  return {
131
154
  base: { kind: 'base', name: 'base', file: setFile('base') },
132
155
  spacing,
156
+ font,
133
157
  color,
134
158
  modifiers: { brand: brands, mode: modes, surface: surfaces, dimension: dimensions },
135
159
  };