@gryt/theme 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +172 -93
- package/dist/index.js.map +1 -1
- package/dist/motion.d.ts +65 -0
- package/dist/motion.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function O(r){return r<=.04045?r/12.92:((r+.055)/1.055)**2.4}function v(r){return r<=.0031308?12.92*r:1.055*r**(1/2.4)-.055}function S(r){return Math.min(1,Math.max(0,r))}function p(r){const a=r.replace("#",""),t=a.length===3?a.split("").map(e=>e+e).join(""):a;return[parseInt(t.slice(0,2),16)/255,parseInt(t.slice(2,4),16)/255,parseInt(t.slice(4,6),16)/255]}function G([r,a,t]){const e=s=>Math.round(S(s)*255).toString(16).padStart(2,"0");return`#${e(r)}${e(a)}${e(t)}`}function x(r){const[a,t,e]=p(r).map(O),s=Math.cbrt(.4122214708*a+.5363325363*t+.0514459929*e),c=Math.cbrt(.2119034982*a+.6806995451*t+.1073969566*e),n=Math.cbrt(.0883024619*a+.2817188376*t+.6299787005*e),f=.2104542553*s+.793617785*c-.0040720468*n,d=1.9779984951*s-2.428592205*c+.4505937099*n,g=.0259040371*s+.7827717662*c-.808675766*n;return{l:f,c:Math.hypot(d,g),h:(Math.atan2(g,d)*180/Math.PI+360)%360}}function y({l:r,c:a,h:t}){const e=a*Math.cos(t*Math.PI/180),s=a*Math.sin(t*Math.PI/180),c=(r+.3963377774*e+.2158037573*s)**3,n=(r-.1055613458*e-.0638541728*s)**3,f=(r-.0894841775*e-1.291485548*s)**3;return G([v(S(4.0767416621*c-3.3077115913*n+.2309699292*f)),v(S(-1.2684380046*c+2.6097574011*n-.3413193965*f)),v(S(-.0041960863*c-.7034186147*n+1.707614701*f))])}const W=[.195,.24,.27,.3,.33,.37,.43,.52],X=[.014,.026,.04,.052,.062,.072,.084,.1];function l(r,a){const{h:t}=x(r),e=W.map((f,d)=>y({l:f,c:X[d],h:t}));e.push(r,a);const s=x(a).l,c=Math.min(.95,Math.max(.84,s+.04)),n=Math.min(.98,Math.max(c+.06,.93));return e.push(y({l:c,c:.11,h:t})),e.push(y({l:n,c:.055,h:t})),e}const q=[.187,.231,.245,.268,.289,.31,.355,.425,.52,.57,.627,.908],J=[.011,.014,.016,.019,.022,.024,.026,.026,.02,.012,0,.008];function D(r){const a={0:r.bg,1:r.surface,2:r.surfaceRaised,5:r.border,10:r.muted,11:r.text},t=x(r.border).h;return q.map((e,s)=>a[s]??y({l:e,c:J[s],h:t}))}function H(r,a){const t=p(a);return r.map(e=>{const s=p(e);let c=0;for(let u=0;u<3;u++){const b=s[u],m=t[u];b>m?c=Math.max(c,m<1?(b-m)/(1-m):0):b<m&&(c=Math.max(c,m>0?(m-b)/m:0))}if(c<1e-6)return"transparent";const n=G(s.map((u,b)=>S(t[b]+(u-t[b])/c))),[f,d,g]=p(n).map(u=>Math.round(u*255));return`rgb(${f} ${d} ${g} / ${(c*100).toFixed(1)}%)`})}const Q=[.962,1,.978,.952,.928,.898,.855,.79,.66,.61,.48,.25],V=[.006,0,.004,.007,.01,.013,.016,.018,.016,.014,.012,.014],Z=[.975,.955,.93,.905,.878,.845,.795,.72],ee=[.012,.024,.038,.05,.062,.074,.09,.11];function P(r){const a={0:r.bg,1:r.surface,2:r.surfaceRaised,5:r.border,10:r.muted,11:r.text},t=x(r.border).h;return Q.map((e,s)=>a[s]??y({l:e,c:V[s],h:t}))}function h(r){const{l:a,c:t,h:e}=x(r),s=Z.map((c,n)=>y({l:c,c:ee[n],h:e}));return s.push(r),s.push(y({l:Math.max(0,a-.07),c:t,h:e})),s.push(y({l:.46,c:.15,h:e})),s.push(y({l:.33,c:.1,h:e})),s}function C(r){const[a,t,e]=p(r).map(O);return .2126*a+.7152*t+.0722*e}function re(r,a){const t=C(r),e=C(a);return(Math.max(t,e)+.05)/(Math.min(t,e)+.05)}const o={color:{bg:"#111318",surface:"#1a1d24",surfaceRaised:"#1e2028",surfaceHover:"#334155",border:"#2b303d",text:"#e0e0e6",muted:"#888888",accent:"#968ff8",accentLight:"#b4afff",secondary:"#7dd3fc",secondaryLight:"#bae6fd",success:"#4ade80",danger:"#f87171",dangerLight:"#fca5a5",warning:"#fbbf24",onAccent:"#0c0a20",onSecondary:"#02121a",onDanger:"#1f0405"},radius:{sm:8,md:12,lg:20,xl:28,full:999}},i={bg:"#f1f2f7",surface:"#ffffff",surfaceRaised:"#f7f8fb",border:"#dadde6",muted:"#5b5d65",text:"#1f2129"},_={neutral:D({bg:o.color.bg,surface:o.color.surface,surfaceRaised:o.color.surfaceRaised,border:o.color.border,muted:o.color.muted,text:o.color.text}),accent:l(o.color.accent,o.color.accentLight),secondary:l(o.color.secondary,o.color.secondaryLight),success:l(o.color.success,o.color.success),danger:l(o.color.danger,o.color.dangerLight),warning:l(o.color.warning,o.color.warning)},w={neutral:P(i),accent:h(o.color.accent),secondary:h(o.color.secondary),success:h(o.color.success),danger:h(o.color.danger),warning:h(o.color.warning)},j=w.neutral[3],ae={neutral:H(_.neutral,o.color.bg),accent:H(_.accent,o.color.bg)},ce={neutral:H(w.neutral,i.bg),accent:H(w.accent,i.bg)};function te(r={}){const a=r.appearance==="light",e={...a?{...o.color,...i,surfaceHover:j}:o.color,...r.color},s={...o.radius,...r.radius},c={bg:e.bg,surface:e.surface,surfaceRaised:e.surfaceRaised,border:e.border,muted:e.muted,text:e.text},n=a?{neutral:P(c),accent:h(e.accent),secondary:h(e.secondary),success:h(e.success),danger:h(e.danger),warning:h(e.warning)}:{neutral:D(c),accent:l(e.accent,e.accentLight),secondary:l(e.secondary,e.secondaryLight),success:l(e.success,e.success),danger:l(e.danger,e.dangerLight),warning:l(e.warning,e.warning)},f={};for(const[d,g]of Object.entries(n))g.forEach((u,b)=>{f[`--gryt-${d}-${b+1}`]=u,f[`--color-gryt-${d}-${b+1}`]=u});for(const d of["neutral","accent"])H(n[d],e.bg).forEach((g,u)=>{f[`--gryt-${d}-a${u+1}`]=g,f[`--color-gryt-${d}-a${u+1}`]=g});return{...f,"--gryt-bg":e.bg,"--gryt-surface":e.surface,"--gryt-surface-raised":e.surfaceRaised,"--gryt-surface-hover":e.surfaceHover,"--gryt-border":e.border,"--gryt-text":e.text,"--gryt-muted":e.muted,"--gryt-accent":e.accent,"--gryt-accent-light":e.accentLight,"--gryt-secondary":e.secondary,"--gryt-secondary-light":e.secondaryLight,"--gryt-success":e.success,"--gryt-danger":e.danger,"--gryt-danger-light":e.dangerLight,"--gryt-warning":e.warning,"--gryt-on-accent":e.onAccent,"--gryt-on-secondary":e.onSecondary,"--gryt-on-danger":e.onDanger,"--color-gryt-bg":e.bg,"--color-gryt-surface":e.surface,"--color-gryt-surface-raised":e.surfaceRaised,"--color-gryt-surface-hover":e.surfaceHover,"--color-gryt-border":e.border,"--color-gryt-text":e.text,"--color-gryt-muted":e.muted,"--color-gryt-accent":e.accent,"--color-gryt-accent-light":e.accentLight,"--color-gryt-secondary":e.secondary,"--color-gryt-secondary-light":e.secondaryLight,"--color-gryt-success":e.success,"--color-gryt-danger":e.danger,"--color-gryt-danger-light":e.dangerLight,"--color-gryt-warning":e.warning,"--color-gryt-on-accent":e.onAccent,"--color-gryt-on-secondary":e.onSecondary,"--color-gryt-on-danger":e.onDanger,"--gryt-radius-sm":`${s.sm}px`,"--gryt-radius-md":`${s.md}px`,"--gryt-radius-lg":`${s.lg}px`,"--gryt-radius-xl":`${s.xl}px`,"--gryt-radius-full":`${s.full}px`}}const T=["accent","accentLight","secondary","secondaryLight","success","danger","dangerLight","warning","onAccent","onSecondary","onDanger"],N=["bg","surface","surfaceRaised","surfaceHover","border","muted","text"],k=["sm","md","lg","xl","full"],z=60;function A(r){return r.replace(/\s+/g," ").trim().slice(0,z)}const L={hue:{accent:o.color.accent,accentLight:o.color.accentLight,secondary:o.color.secondary,secondaryLight:o.color.secondaryLight,success:o.color.success,danger:o.color.danger,dangerLight:o.color.dangerLight,warning:o.color.warning,onAccent:o.color.onAccent,onSecondary:o.color.onSecondary,onDanger:o.color.onDanger},lightHue:null,dark:{bg:o.color.bg,surface:o.color.surface,surfaceRaised:o.color.surfaceRaised,surfaceHover:o.color.surfaceHover,border:o.color.border,muted:o.color.muted,text:o.color.text},light:{bg:i.bg,surface:i.surface,surfaceRaised:i.surfaceRaised,surfaceHover:j,border:i.border,muted:i.muted,text:i.text},radius:{...o.radius}};function I(r){return{...r.name===void 0?{}:{name:r.name},hue:{...r.hue},lightHue:r.lightHue===null?null:{...r.lightHue},dark:{...r.dark},light:{...r.light},radius:{...r.radius}}}function K(r,a){return a==="light"&&r.lightHue!==null?r.lightHue:r.hue}function ne(r,a){return{appearance:a,color:{...K(r,a),...r[a]},radius:{...r.radius}}}const R={accent:"accent",accentLight:"accent-light",secondary:"secondary",secondaryLight:"secondary-light",success:"success",danger:"danger",dangerLight:"danger-light",warning:"warning",onAccent:"on-accent",onSecondary:"on-secondary",onDanger:"on-danger"},F={bg:"bg",surface:"surface",surfaceRaised:"raised",surfaceHover:"hover",border:"border",muted:"muted",text:"text"},oe=/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;function U(r){return oe.test(r.trim())}function M(r){const a=r.trim().toLowerCase();return a.length===4?`#${a[1]}${a[1]}${a[2]}${a[2]}${a[3]}${a[3]}`:a}function se(r,a){const t=new URLSearchParams,e=c=>M(c).slice(1),s=A(r.name??"");s!==""&&t.set("name",s);for(const c of T)r.hue[c]!==L.hue[c]&&t.set(R[c],e(r.hue[c]));if(r.lightHue!==null)for(const c of T)t.set(`lh-${R[c]}`,e(r.lightHue[c]));for(const c of["dark","light"]){const n=c==="dark"?"d":"l";for(const f of N)r[c][f]!==L[c][f]&&t.set(`${n}-${F[f]}`,e(r[c][f]))}for(const c of k)r.radius[c]!==L.radius[c]&&t.set(`r-${c}`,String(r.radius[c]));return a==="light"&&t.set("mode","light"),t}function fe(r){const a=r.trim();if(a==="")return null;if(a.startsWith("{"))return ue(a);const t=a.includes("?")?a.slice(a.indexOf("?")+1):a;return de(new URLSearchParams(t))}function de(r){const a=I(L);let t=!1;const e=c=>{const n=r.get(c);if(n===null)return null;const f=n.startsWith("#")?n:`#${n}`;return U(f)?(t=!0,M(f)):null},s=A(r.get("name")??"");s!==""&&(a.name=s,t=!0);for(const c of T){const n=e(R[c]);n!==null&&(a.hue[c]=n)}if(r.has(`lh-${R.accent}`)){const c={...a.hue};for(const n of T){const f=e(`lh-${R[n]}`);f!==null&&(c[n]=f)}a.lightHue=c}for(const c of["dark","light"]){const n=c==="dark"?"d":"l";for(const f of N){const d=e(`${n}-${F[f]}`);d!==null&&(a[c][f]=d)}}for(const c of k){const n=Number(r.get(`r-${c}`));Number.isFinite(n)&&n>=0&&n<=999&&r.has(`r-${c}`)&&(a.radius[c]=Math.round(n),t=!0)}return t?{theme:a,appearance:r.get("mode")==="light"?"light":"dark"}:null}function ue(r){let a;try{a=JSON.parse(r)}catch{return null}if(typeof a!="object"||a===null)return null;const t=a,e=I(L);let s=!1;const c=(n,f)=>{if(!(typeof n!="object"||n===null))for(const[d,g]of Object.entries(n))typeof g=="string"&&U(g)&&d in f&&(f[d]=M(g),s=!0)};if(typeof t.name=="string"){const n=A(t.name);n!==""&&(e.name=n,s=!0)}if(c(t.hue,e.hue),c(t.dark,e.dark),c(t.light,e.light),typeof t.lightHue=="object"&&t.lightHue!==null){const n={...e.hue};c(t.lightHue,n),e.lightHue=n}if(typeof t.radius=="object"&&t.radius!==null)for(const[n,f]of Object.entries(t.radius)){const d=Number(f);k.includes(n)&&Number.isFinite(d)&&d>=0&&d<=999&&(e.radius[n]=Math.round(d),s=!0)}return s?{theme:e,appearance:"dark"}:null}const $={sm:8,md:12,lg:20,xl:28,full:999},E={sm:6,md:8,lg:14,xl:18,full:999},ge={sm:4,md:6,lg:10,xl:14,full:6},ie={sm:6,md:8,lg:10,xl:14,full:10},Y={sm:2,md:4,lg:6,xl:8,full:4},B=[{id:"gryt",name:"Gryt",note:"What the library ships, from the Gryt code-theme.",group:"Gryt",source:"github.com/Gryt-chat/code-theme",theme:L},{id:"ember",name:"Ember",note:"Warm all the way down — the neutrals are brown, not blue.",group:"Gryt",theme:{name:"Ember",hue:{accent:"#f0803c",accentLight:"#ff9f66",secondary:"#d9a441",secondaryLight:"#ecc06a",success:"#8bb056",danger:"#e35d55",dangerLight:"#ef8079",warning:"#e8b33e",onAccent:"#231004",onSecondary:"#241a04",onDanger:"#2b0a08"},lightHue:null,dark:{bg:"#17110e",surface:"#1f1815",surfaceRaised:"#251d19",surfaceHover:"#33261f",border:"#352822",muted:"#a48f81",text:"#f5ece5"},light:{bg:"#f6efe8",surface:"#fffdfb",surfaceRaised:"#faf3ec",surfaceHover:"#efe3d8",border:"#e0d2c4",muted:"#6b5b50",text:"#241a14"},radius:$}},{id:"paper",name:"Paper",note:"Near-monochrome. One quiet slate accent and nothing else.",group:"Gryt",theme:{name:"Paper",hue:{accent:"#8390a8",accentLight:"#a3aec2",secondary:"#93a0a0",secondaryLight:"#b1bcbc",success:"#7f9b7f",danger:"#b56b6b",dangerLight:"#c98d8d",warning:"#b39a6a",onAccent:"#11151c",onSecondary:"#121717",onDanger:"#1d0e0e"},lightHue:null,dark:{bg:"#101011",surface:"#17171a",surfaceRaised:"#1d1d20",surfaceHover:"#282a2e",border:"#2a2a2e",muted:"#8e8e94",text:"#ededf0"},light:{bg:"#f0f0f2",surface:"#ffffff",surfaceRaised:"#f7f7f9",surfaceHover:"#e6e6ea",border:"#d6d6dc",muted:"#5b5b63",text:"#17171a"},radius:E}},{id:"signal",name:"Signal",note:"Black, white, and a yellow that cannot be missed.",group:"Gryt",theme:{name:"Signal",hue:{accent:"#ffd400",accentLight:"#ffe454",secondary:"#00d0ff",secondaryLight:"#66e2ff",success:"#00e06a",danger:"#ff453a",dangerLight:"#ff7a72",warning:"#ffab00",onAccent:"#161200",onSecondary:"#001a20",onDanger:"#1a0300"},lightHue:null,dark:{bg:"#000000",surface:"#0c0c0c",surfaceRaised:"#151515",surfaceHover:"#242424",border:"#454545",muted:"#bcbcbc",text:"#ffffff"},light:{bg:"#f0f0f0",surface:"#ffffff",surfaceRaised:"#f8f8f8",surfaceHover:"#e3e3e3",border:"#6f6f6f",muted:"#3d3d3d",text:"#000000"},radius:Y}},{id:"dracula",name:"Dracula",note:"The purple-and-pink dark theme, with Alucard as its light half.",group:"Ported",source:"draculatheme.com, MIT",theme:{name:"Dracula",hue:{accent:"#bd93f9",accentLight:"#d0b3fb",secondary:"#8be9fd",secondaryLight:"#aff0fe",success:"#50fa7b",danger:"#ff5555",dangerLight:"#ff7979",warning:"#ffb86c",onAccent:"#282a36",onSecondary:"#282a36",onDanger:"#282a36"},lightHue:{accent:"#644ac9",accentLight:"#7b64d6",secondary:"#036a96",secondaryLight:"#0b83b5",success:"#14710a",danger:"#cb3a2a",dangerLight:"#d95445",warning:"#a34d14",onAccent:"#fffbeb",onSecondary:"#fffbeb",onDanger:"#fffbeb"},dark:{bg:"#282a36",surface:"#31323f",surfaceRaised:"#383a49",surfaceHover:"#44475a",border:"#44475a",muted:"#6272a4",text:"#f8f8f2"},light:{bg:"#f5f1e1",surface:"#fffbeb",surfaceRaised:"#faf6e6",surfaceHover:"#ece7d4",border:"#dcd6bf",muted:"#6c664b",text:"#1f1f1f"},radius:E}},{id:"nord",name:"Nord",note:"Polar Night and Snow Storm, with Frost on top.",group:"Ported",source:"nordtheme.com, MIT",theme:{name:"Nord",hue:{accent:"#88c0d0",accentLight:"#8fbcbb",secondary:"#81a1c1",secondaryLight:"#a3b8d4",success:"#a3be8c",danger:"#bf616a",dangerLight:"#d08770",warning:"#ebcb8b",onAccent:"#2e3440",onSecondary:"#2e3440",onDanger:"#eceff4"},lightHue:{accent:"#5e81ac",accentLight:"#81a1c1",secondary:"#8fbcbb",secondaryLight:"#88c0d0",success:"#a3be8c",danger:"#bf616a",dangerLight:"#d08770",warning:"#ebcb8b",onAccent:"#eceff4",onSecondary:"#2e3440",onDanger:"#eceff4"},dark:{bg:"#2e3440",surface:"#3b4252",surfaceRaised:"#434c5e",surfaceHover:"#4c566a",border:"#4c566a",muted:"#d8dee9",text:"#eceff4"},light:{bg:"#e5e9f0",surface:"#eceff4",surfaceRaised:"#e9edf2",surfaceHover:"#d8dee9",border:"#c9d1de",muted:"#4c566a",text:"#2e3440"},radius:E}},{id:"catppuccin",name:"Catppuccin",note:"Mocha for dark, Latte for light. Mauve does the accent work.",group:"Ported",source:"catppuccin/palette, MIT",theme:{name:"Catppuccin",hue:{accent:"#cba6f7",accentLight:"#dcc0fa",secondary:"#89b4fa",secondaryLight:"#a8c8fb",success:"#a6e3a1",danger:"#f38ba8",dangerLight:"#eba0ac",warning:"#f9e2af",onAccent:"#1e1e2e",onSecondary:"#1e1e2e",onDanger:"#1e1e2e"},lightHue:{accent:"#8839ef",accentLight:"#9a55f2",secondary:"#1e66f5",secondaryLight:"#4680f7",success:"#40a02b",danger:"#d20f39",dangerLight:"#e64553",warning:"#df8e1d",onAccent:"#eff1f5",onSecondary:"#eff1f5",onDanger:"#eff1f5"},dark:{bg:"#1e1e2e",surface:"#313244",surfaceRaised:"#45475a",surfaceHover:"#585b70",border:"#45475a",muted:"#a6adc8",text:"#cdd6f4"},light:{bg:"#e6e9ef",surface:"#eff1f5",surfaceRaised:"#eaedf3",surfaceHover:"#dce0e8",border:"#ccd0da",muted:"#6c6f85",text:"#4c4f69"},radius:$}},{id:"github",name:"GitHub",note:"Primer's own tokens, six-pixel corners included.",group:"Ported",source:"@primer/primitives",theme:{name:"GitHub",hue:{accent:"#1f6feb",accentLight:"#4493f8",secondary:"#8957e5",secondaryLight:"#a371f7",success:"#238636",danger:"#da3633",dangerLight:"#f85149",warning:"#9e6a03",onAccent:"#ffffff",onSecondary:"#ffffff",onDanger:"#ffffff"},lightHue:{accent:"#0969da",accentLight:"#218bff",secondary:"#8250df",secondaryLight:"#a475f9",success:"#1f883d",danger:"#cf222e",dangerLight:"#d1242f",warning:"#9a6700",onAccent:"#ffffff",onSecondary:"#ffffff",onDanger:"#ffffff"},dark:{bg:"#0d1117",surface:"#151b23",surfaceRaised:"#1c222b",surfaceHover:"#262c36",border:"#3d444d",muted:"#9198a1",text:"#f0f6fc"},light:{bg:"#f6f8fa",surface:"#ffffff",surfaceRaised:"#fbfcfd",surfaceHover:"#eef1f4",border:"#d1d9e0",muted:"#59636e",text:"#1f2328"},radius:ge}},{id:"claude",name:"Claude",note:"Anthropic's clay orange on cream and near-black.",group:"Ported",source:"anthropic.com — a likeness, not a published palette",theme:{name:"Claude",hue:{accent:"#d97757",accentLight:"#e59275",secondary:"#7d9ec4",secondaryLight:"#9db8d6",success:"#6ba368",danger:"#bf4d43",dangerLight:"#d4726a",warning:"#d9a441",onAccent:"#241009",onSecondary:"#0c1720",onDanger:"#faf9f5"},lightHue:null,dark:{bg:"#141413",surface:"#1f1e1d",surfaceRaised:"#262624",surfaceHover:"#3d3d3a",border:"#3d3d3a",muted:"#b0aea5",text:"#faf9f5"},light:{bg:"#f0eee6",surface:"#faf9f5",surfaceRaised:"#f5f3ec",surfaceHover:"#e8e6dc",border:"#d5d2c5",muted:"#87867f",text:"#141413"},radius:$}},{id:"shadcn",name:"shadcn/ui",note:"Zinc neutrals and a ten-pixel radius. No pills anywhere.",group:"Ported",source:"ui.shadcn.com, MIT — accent adapted",theme:{name:"shadcn/ui",hue:{accent:"#a1a1aa",accentLight:"#d4d4d8",secondary:"#71717a",secondaryLight:"#a1a1aa",success:"#4ade80",danger:"#e7000b",dangerLight:"#fb2c36",warning:"#fd9a00",onAccent:"#18181b",onSecondary:"#fafafa",onDanger:"#fafafa"},lightHue:{accent:"#3f3f46",accentLight:"#52525b",secondary:"#71717a",secondaryLight:"#a1a1aa",success:"#00a63e",danger:"#e7000b",dangerLight:"#fb2c36",warning:"#e17100",onAccent:"#fafafa",onSecondary:"#fafafa",onDanger:"#fafafa"},dark:{bg:"#18181b",surface:"#27272a",surfaceRaised:"#3f3f46",surfaceHover:"#3f3f46",border:"#3f3f46",muted:"#a1a1aa",text:"#fafafa"},light:{bg:"#f4f4f5",surface:"#ffffff",surfaceRaised:"#fafafa",surfaceHover:"#e4e4e7",border:"#e4e4e7",muted:"#71717a",text:"#18181b"},radius:ie}},{id:"solarized",name:"Solarized",note:"Both halves on one set of accents, as designed.",group:"Ported",source:"ethanschoonover.com/solarized, MIT",theme:{name:"Solarized",hue:{accent:"#268bd2",accentLight:"#4ba3e3",secondary:"#2aa198",secondaryLight:"#43bbb1",success:"#859900",danger:"#dc322f",dangerLight:"#cb4b16",warning:"#b58900",onAccent:"#fdf6e3",onSecondary:"#002b36",onDanger:"#fdf6e3"},lightHue:null,dark:{bg:"#002b36",surface:"#073642",surfaceRaised:"#0b414f",surfaceHover:"#134b5a",border:"#0f4757",muted:"#93a1a1",text:"#eee8d5"},light:{bg:"#eee8d5",surface:"#fdf6e3",surfaceRaised:"#f7f0dc",surfaceHover:"#e4dcc4",border:"#d9d0b4",muted:"#586e75",text:"#073642"},radius:Y}}],le=new Map(B.map(r=>[r.id,r]));exports.GRYT_HUE_KEYS=T;exports.GRYT_NEUTRAL_KEYS=N;exports.GRYT_RADIUS_KEYS=k;exports.GRYT_THEME_NAME_MAX=z;exports.alphaScale=H;exports.cloneGrytTheme=I;exports.contrast=re;exports.createGrytTheme=te;exports.decodeGrytTheme=fe;exports.encodeGrytTheme=se;exports.grytAlphaScales=ae;exports.grytAlphaScalesLight=ce;exports.grytLightTokens=i;exports.grytPresets=B;exports.grytPresetsById=le;exports.grytScales=_;exports.grytScalesLight=w;exports.grytTheme=L;exports.grytThemeHues=K;exports.grytThemeToOptions=ne;exports.grytTokens=o;exports.hexToOklch=x;exports.hexToRgb=p;exports.hueScale=l;exports.hueScaleLight=h;exports.isHexColor=U;exports.neutralScale=D;exports.neutralScaleLight=P;exports.normalizeHexColor=M;exports.normalizeThemeName=A;exports.oklchToHex=y;exports.rgbToHex=G;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function O(r){return r<=.04045?r/12.92:((r+.055)/1.055)**2.4}function M(r){return r<=.0031308?12.92*r:1.055*r**(1/2.4)-.055}function S(r){return Math.min(1,Math.max(0,r))}function L(r){const a=r.replace("#",""),t=a.length===3?a.split("").map(e=>e+e).join(""):a;return[parseInt(t.slice(0,2),16)/255,parseInt(t.slice(2,4),16)/255,parseInt(t.slice(4,6),16)/255]}function D([r,a,t]){const e=s=>Math.round(S(s)*255).toString(16).padStart(2,"0");return`#${e(r)}${e(a)}${e(t)}`}function x(r){const[a,t,e]=L(r).map(O),s=Math.cbrt(.4122214708*a+.5363325363*t+.0514459929*e),c=Math.cbrt(.2119034982*a+.6806995451*t+.1073969566*e),n=Math.cbrt(.0883024619*a+.2817188376*t+.6299787005*e),f=.2104542553*s+.793617785*c-.0040720468*n,d=1.9779984951*s-2.428592205*c+.4505937099*n,g=.0259040371*s+.7827717662*c-.808675766*n;return{l:f,c:Math.hypot(d,g),h:(Math.atan2(g,d)*180/Math.PI+360)%360}}function y({l:r,c:a,h:t}){const e=a*Math.cos(t*Math.PI/180),s=a*Math.sin(t*Math.PI/180),c=(r+.3963377774*e+.2158037573*s)**3,n=(r-.1055613458*e-.0638541728*s)**3,f=(r-.0894841775*e-1.291485548*s)**3;return D([M(S(4.0767416621*c-3.3077115913*n+.2309699292*f)),M(S(-1.2684380046*c+2.6097574011*n-.3413193965*f)),M(S(-.0041960863*c-.7034186147*n+1.707614701*f))])}const W=[.195,.24,.27,.3,.33,.37,.43,.52],X=[.014,.026,.04,.052,.062,.072,.084,.1];function l(r,a){const{h:t}=x(r),e=W.map((f,d)=>y({l:f,c:X[d],h:t}));e.push(r,a);const s=x(a).l,c=Math.min(.95,Math.max(.84,s+.04)),n=Math.min(.98,Math.max(c+.06,.93));return e.push(y({l:c,c:.11,h:t})),e.push(y({l:n,c:.055,h:t})),e}const q=[.187,.231,.245,.268,.289,.31,.355,.425,.52,.57,.627,.908],J=[.011,.014,.016,.019,.022,.024,.026,.026,.02,.012,0,.008];function G(r){const a={0:r.bg,1:r.surface,2:r.surfaceRaised,5:r.border,10:r.muted,11:r.text},t=x(r.border).h;return q.map((e,s)=>a[s]??y({l:e,c:J[s],h:t}))}function H(r,a){const t=L(a);return r.map(e=>{const s=L(e);let c=0;for(let u=0;u<3;u++){const b=s[u],m=t[u];b>m?c=Math.max(c,m<1?(b-m)/(1-m):0):b<m&&(c=Math.max(c,m>0?(m-b)/m:0))}if(c<1e-6)return"transparent";const n=D(s.map((u,b)=>S(t[b]+(u-t[b])/c))),[f,d,g]=L(n).map(u=>Math.round(u*255));return`rgb(${f} ${d} ${g} / ${(c*100).toFixed(1)}%)`})}const Q=[.962,1,.978,.952,.928,.898,.855,.79,.66,.61,.48,.25],V=[.006,0,.004,.007,.01,.013,.016,.018,.016,.014,.012,.014],Z=[.975,.955,.93,.905,.878,.845,.795,.72],ee=[.012,.024,.038,.05,.062,.074,.09,.11];function P(r){const a={0:r.bg,1:r.surface,2:r.surfaceRaised,5:r.border,10:r.muted,11:r.text},t=x(r.border).h;return Q.map((e,s)=>a[s]??y({l:e,c:V[s],h:t}))}function h(r){const{l:a,c:t,h:e}=x(r),s=Z.map((c,n)=>y({l:c,c:ee[n],h:e}));return s.push(r),s.push(y({l:Math.max(0,a-.07),c:t,h:e})),s.push(y({l:.46,c:.15,h:e})),s.push(y({l:.33,c:.1,h:e})),s}function C(r){const[a,t,e]=L(r).map(O);return .2126*a+.7152*t+.0722*e}function re(r,a){const t=C(r),e=C(a);return(Math.max(t,e)+.05)/(Math.min(t,e)+.05)}const o={color:{bg:"#111318",surface:"#1a1d24",surfaceRaised:"#1e2028",surfaceHover:"#334155",border:"#2b303d",text:"#e0e0e6",muted:"#888888",accent:"#968ff8",accentLight:"#b4afff",secondary:"#7dd3fc",secondaryLight:"#bae6fd",success:"#4ade80",danger:"#f87171",dangerLight:"#fca5a5",warning:"#fbbf24",onAccent:"#0c0a20",onSecondary:"#02121a",onDanger:"#1f0405"},radius:{sm:8,md:12,lg:20,xl:28,full:999}},i={bg:"#f1f2f7",surface:"#ffffff",surfaceRaised:"#f7f8fb",border:"#dadde6",muted:"#5b5d65",text:"#1f2129"},_={neutral:G({bg:o.color.bg,surface:o.color.surface,surfaceRaised:o.color.surfaceRaised,border:o.color.border,muted:o.color.muted,text:o.color.text}),accent:l(o.color.accent,o.color.accentLight),secondary:l(o.color.secondary,o.color.secondaryLight),success:l(o.color.success,o.color.success),danger:l(o.color.danger,o.color.dangerLight),warning:l(o.color.warning,o.color.warning)},w={neutral:P(i),accent:h(o.color.accent),secondary:h(o.color.secondary),success:h(o.color.success),danger:h(o.color.danger),warning:h(o.color.warning)},j=w.neutral[3],ae={neutral:H(_.neutral,o.color.bg),accent:H(_.accent,o.color.bg)},ce={neutral:H(w.neutral,i.bg),accent:H(w.accent,i.bg)};function te(r={}){const a=r.appearance==="light",e={...a?{...o.color,...i,surfaceHover:j}:o.color,...r.color},s={...o.radius,...r.radius},c={bg:e.bg,surface:e.surface,surfaceRaised:e.surfaceRaised,border:e.border,muted:e.muted,text:e.text},n=a?{neutral:P(c),accent:h(e.accent),secondary:h(e.secondary),success:h(e.success),danger:h(e.danger),warning:h(e.warning)}:{neutral:G(c),accent:l(e.accent,e.accentLight),secondary:l(e.secondary,e.secondaryLight),success:l(e.success,e.success),danger:l(e.danger,e.dangerLight),warning:l(e.warning,e.warning)},f={};for(const[d,g]of Object.entries(n))g.forEach((u,b)=>{f[`--gryt-${d}-${b+1}`]=u,f[`--color-gryt-${d}-${b+1}`]=u});for(const d of["neutral","accent"])H(n[d],e.bg).forEach((g,u)=>{f[`--gryt-${d}-a${u+1}`]=g,f[`--color-gryt-${d}-a${u+1}`]=g});return{...f,"--gryt-bg":e.bg,"--gryt-surface":e.surface,"--gryt-surface-raised":e.surfaceRaised,"--gryt-surface-hover":e.surfaceHover,"--gryt-border":e.border,"--gryt-text":e.text,"--gryt-muted":e.muted,"--gryt-accent":e.accent,"--gryt-accent-light":e.accentLight,"--gryt-secondary":e.secondary,"--gryt-secondary-light":e.secondaryLight,"--gryt-success":e.success,"--gryt-danger":e.danger,"--gryt-danger-light":e.dangerLight,"--gryt-warning":e.warning,"--gryt-on-accent":e.onAccent,"--gryt-on-secondary":e.onSecondary,"--gryt-on-danger":e.onDanger,"--color-gryt-bg":e.bg,"--color-gryt-surface":e.surface,"--color-gryt-surface-raised":e.surfaceRaised,"--color-gryt-surface-hover":e.surfaceHover,"--color-gryt-border":e.border,"--color-gryt-text":e.text,"--color-gryt-muted":e.muted,"--color-gryt-accent":e.accent,"--color-gryt-accent-light":e.accentLight,"--color-gryt-secondary":e.secondary,"--color-gryt-secondary-light":e.secondaryLight,"--color-gryt-success":e.success,"--color-gryt-danger":e.danger,"--color-gryt-danger-light":e.dangerLight,"--color-gryt-warning":e.warning,"--color-gryt-on-accent":e.onAccent,"--color-gryt-on-secondary":e.onSecondary,"--color-gryt-on-danger":e.onDanger,"--gryt-radius-sm":`${s.sm}px`,"--gryt-radius-md":`${s.md}px`,"--gryt-radius-lg":`${s.lg}px`,"--gryt-radius-xl":`${s.xl}px`,"--gryt-radius-full":`${s.full}px`}}const R=["accent","accentLight","secondary","secondaryLight","success","danger","dangerLight","warning","onAccent","onSecondary","onDanger"],N=["bg","surface","surfaceRaised","surfaceHover","border","muted","text"],k=["sm","md","lg","xl","full"],z=60;function A(r){return r.replace(/\s+/g," ").trim().slice(0,z)}const p={hue:{accent:o.color.accent,accentLight:o.color.accentLight,secondary:o.color.secondary,secondaryLight:o.color.secondaryLight,success:o.color.success,danger:o.color.danger,dangerLight:o.color.dangerLight,warning:o.color.warning,onAccent:o.color.onAccent,onSecondary:o.color.onSecondary,onDanger:o.color.onDanger},lightHue:null,dark:{bg:o.color.bg,surface:o.color.surface,surfaceRaised:o.color.surfaceRaised,surfaceHover:o.color.surfaceHover,border:o.color.border,muted:o.color.muted,text:o.color.text},light:{bg:i.bg,surface:i.surface,surfaceRaised:i.surfaceRaised,surfaceHover:j,border:i.border,muted:i.muted,text:i.text},radius:{...o.radius}};function I(r){return{...r.name===void 0?{}:{name:r.name},hue:{...r.hue},lightHue:r.lightHue===null?null:{...r.lightHue},dark:{...r.dark},light:{...r.light},radius:{...r.radius}}}function K(r,a){return a==="light"&&r.lightHue!==null?r.lightHue:r.hue}function ne(r,a){return{appearance:a,color:{...K(r,a),...r[a]},radius:{...r.radius}}}const T={accent:"accent",accentLight:"accent-light",secondary:"secondary",secondaryLight:"secondary-light",success:"success",danger:"danger",dangerLight:"danger-light",warning:"warning",onAccent:"on-accent",onSecondary:"on-secondary",onDanger:"on-danger"},F={bg:"bg",surface:"surface",surfaceRaised:"raised",surfaceHover:"hover",border:"border",muted:"muted",text:"text"},oe=/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;function U(r){return oe.test(r.trim())}function v(r){const a=r.trim().toLowerCase();return a.length===4?`#${a[1]}${a[1]}${a[2]}${a[2]}${a[3]}${a[3]}`:a}function se(r,a){const t=new URLSearchParams,e=c=>v(c).slice(1),s=A(r.name??"");s!==""&&t.set("name",s);for(const c of R)r.hue[c]!==p.hue[c]&&t.set(T[c],e(r.hue[c]));if(r.lightHue!==null)for(const c of R)t.set(`lh-${T[c]}`,e(r.lightHue[c]));for(const c of["dark","light"]){const n=c==="dark"?"d":"l";for(const f of N)r[c][f]!==p[c][f]&&t.set(`${n}-${F[f]}`,e(r[c][f]))}for(const c of k)r.radius[c]!==p.radius[c]&&t.set(`r-${c}`,String(r.radius[c]));return a==="light"&&t.set("mode","light"),t}function fe(r){const a=r.trim();if(a==="")return null;if(a.startsWith("{"))return ue(a);const t=a.includes("?")?a.slice(a.indexOf("?")+1):a;return de(new URLSearchParams(t))}function de(r){const a=I(p);let t=!1;const e=c=>{const n=r.get(c);if(n===null)return null;const f=n.startsWith("#")?n:`#${n}`;return U(f)?(t=!0,v(f)):null},s=A(r.get("name")??"");s!==""&&(a.name=s,t=!0);for(const c of R){const n=e(T[c]);n!==null&&(a.hue[c]=n)}if(r.has(`lh-${T.accent}`)){const c={...a.hue};for(const n of R){const f=e(`lh-${T[n]}`);f!==null&&(c[n]=f)}a.lightHue=c}for(const c of["dark","light"]){const n=c==="dark"?"d":"l";for(const f of N){const d=e(`${n}-${F[f]}`);d!==null&&(a[c][f]=d)}}for(const c of k){const n=Number(r.get(`r-${c}`));Number.isFinite(n)&&n>=0&&n<=999&&r.has(`r-${c}`)&&(a.radius[c]=Math.round(n),t=!0)}return t?{theme:a,appearance:r.get("mode")==="light"?"light":"dark"}:null}function ue(r){let a;try{a=JSON.parse(r)}catch{return null}if(typeof a!="object"||a===null)return null;const t=a,e=I(p);let s=!1;const c=(n,f)=>{if(!(typeof n!="object"||n===null))for(const[d,g]of Object.entries(n))typeof g=="string"&&U(g)&&d in f&&(f[d]=v(g),s=!0)};if(typeof t.name=="string"){const n=A(t.name);n!==""&&(e.name=n,s=!0)}if(c(t.hue,e.hue),c(t.dark,e.dark),c(t.light,e.light),typeof t.lightHue=="object"&&t.lightHue!==null){const n={...e.hue};c(t.lightHue,n),e.lightHue=n}if(typeof t.radius=="object"&&t.radius!==null)for(const[n,f]of Object.entries(t.radius)){const d=Number(f);k.includes(n)&&Number.isFinite(d)&&d>=0&&d<=999&&(e.radius[n]=Math.round(d),s=!0)}return s?{theme:e,appearance:"dark"}:null}const $={sm:8,md:12,lg:20,xl:28,full:999},E={sm:6,md:8,lg:14,xl:18,full:999},ge={sm:4,md:6,lg:10,xl:14,full:6},ie={sm:6,md:8,lg:10,xl:14,full:10},Y={sm:2,md:4,lg:6,xl:8,full:4},B=[{id:"gryt",name:"Gryt",note:"What the library ships, from the Gryt code-theme.",group:"Gryt",source:"github.com/Gryt-chat/code-theme",theme:p},{id:"ember",name:"Ember",note:"Warm all the way down — the neutrals are brown, not blue.",group:"Gryt",theme:{name:"Ember",hue:{accent:"#f0803c",accentLight:"#ff9f66",secondary:"#d9a441",secondaryLight:"#ecc06a",success:"#8bb056",danger:"#e35d55",dangerLight:"#ef8079",warning:"#e8b33e",onAccent:"#231004",onSecondary:"#241a04",onDanger:"#2b0a08"},lightHue:null,dark:{bg:"#17110e",surface:"#1f1815",surfaceRaised:"#251d19",surfaceHover:"#33261f",border:"#352822",muted:"#a48f81",text:"#f5ece5"},light:{bg:"#f6efe8",surface:"#fffdfb",surfaceRaised:"#faf3ec",surfaceHover:"#efe3d8",border:"#e0d2c4",muted:"#6b5b50",text:"#241a14"},radius:$}},{id:"paper",name:"Paper",note:"Near-monochrome. One quiet slate accent and nothing else.",group:"Gryt",theme:{name:"Paper",hue:{accent:"#8390a8",accentLight:"#a3aec2",secondary:"#93a0a0",secondaryLight:"#b1bcbc",success:"#7f9b7f",danger:"#b56b6b",dangerLight:"#c98d8d",warning:"#b39a6a",onAccent:"#11151c",onSecondary:"#121717",onDanger:"#1d0e0e"},lightHue:null,dark:{bg:"#101011",surface:"#17171a",surfaceRaised:"#1d1d20",surfaceHover:"#282a2e",border:"#2a2a2e",muted:"#8e8e94",text:"#ededf0"},light:{bg:"#f0f0f2",surface:"#ffffff",surfaceRaised:"#f7f7f9",surfaceHover:"#e6e6ea",border:"#d6d6dc",muted:"#5b5b63",text:"#17171a"},radius:E}},{id:"signal",name:"Signal",note:"Black, white, and a yellow that cannot be missed.",group:"Gryt",theme:{name:"Signal",hue:{accent:"#ffd400",accentLight:"#ffe454",secondary:"#00d0ff",secondaryLight:"#66e2ff",success:"#00e06a",danger:"#ff453a",dangerLight:"#ff7a72",warning:"#ffab00",onAccent:"#161200",onSecondary:"#001a20",onDanger:"#1a0300"},lightHue:null,dark:{bg:"#000000",surface:"#0c0c0c",surfaceRaised:"#151515",surfaceHover:"#242424",border:"#454545",muted:"#bcbcbc",text:"#ffffff"},light:{bg:"#f0f0f0",surface:"#ffffff",surfaceRaised:"#f8f8f8",surfaceHover:"#e3e3e3",border:"#6f6f6f",muted:"#3d3d3d",text:"#000000"},radius:Y}},{id:"dracula",name:"Dracula",note:"The purple-and-pink dark theme, with Alucard as its light half.",group:"Ported",source:"draculatheme.com, MIT",theme:{name:"Dracula",hue:{accent:"#bd93f9",accentLight:"#d0b3fb",secondary:"#8be9fd",secondaryLight:"#aff0fe",success:"#50fa7b",danger:"#ff5555",dangerLight:"#ff7979",warning:"#ffb86c",onAccent:"#282a36",onSecondary:"#282a36",onDanger:"#282a36"},lightHue:{accent:"#644ac9",accentLight:"#7b64d6",secondary:"#036a96",secondaryLight:"#0b83b5",success:"#14710a",danger:"#cb3a2a",dangerLight:"#d95445",warning:"#a34d14",onAccent:"#fffbeb",onSecondary:"#fffbeb",onDanger:"#fffbeb"},dark:{bg:"#282a36",surface:"#31323f",surfaceRaised:"#383a49",surfaceHover:"#44475a",border:"#44475a",muted:"#6272a4",text:"#f8f8f2"},light:{bg:"#f5f1e1",surface:"#fffbeb",surfaceRaised:"#faf6e6",surfaceHover:"#ece7d4",border:"#dcd6bf",muted:"#6c664b",text:"#1f1f1f"},radius:E}},{id:"nord",name:"Nord",note:"Polar Night and Snow Storm, with Frost on top.",group:"Ported",source:"nordtheme.com, MIT",theme:{name:"Nord",hue:{accent:"#88c0d0",accentLight:"#8fbcbb",secondary:"#81a1c1",secondaryLight:"#a3b8d4",success:"#a3be8c",danger:"#bf616a",dangerLight:"#d08770",warning:"#ebcb8b",onAccent:"#2e3440",onSecondary:"#2e3440",onDanger:"#eceff4"},lightHue:{accent:"#5e81ac",accentLight:"#81a1c1",secondary:"#8fbcbb",secondaryLight:"#88c0d0",success:"#a3be8c",danger:"#bf616a",dangerLight:"#d08770",warning:"#ebcb8b",onAccent:"#eceff4",onSecondary:"#2e3440",onDanger:"#eceff4"},dark:{bg:"#2e3440",surface:"#3b4252",surfaceRaised:"#434c5e",surfaceHover:"#4c566a",border:"#4c566a",muted:"#d8dee9",text:"#eceff4"},light:{bg:"#e5e9f0",surface:"#eceff4",surfaceRaised:"#e9edf2",surfaceHover:"#d8dee9",border:"#c9d1de",muted:"#4c566a",text:"#2e3440"},radius:E}},{id:"catppuccin",name:"Catppuccin",note:"Mocha for dark, Latte for light. Mauve does the accent work.",group:"Ported",source:"catppuccin/palette, MIT",theme:{name:"Catppuccin",hue:{accent:"#cba6f7",accentLight:"#dcc0fa",secondary:"#89b4fa",secondaryLight:"#a8c8fb",success:"#a6e3a1",danger:"#f38ba8",dangerLight:"#eba0ac",warning:"#f9e2af",onAccent:"#1e1e2e",onSecondary:"#1e1e2e",onDanger:"#1e1e2e"},lightHue:{accent:"#8839ef",accentLight:"#9a55f2",secondary:"#1e66f5",secondaryLight:"#4680f7",success:"#40a02b",danger:"#d20f39",dangerLight:"#e64553",warning:"#df8e1d",onAccent:"#eff1f5",onSecondary:"#eff1f5",onDanger:"#eff1f5"},dark:{bg:"#1e1e2e",surface:"#313244",surfaceRaised:"#45475a",surfaceHover:"#585b70",border:"#45475a",muted:"#a6adc8",text:"#cdd6f4"},light:{bg:"#e6e9ef",surface:"#eff1f5",surfaceRaised:"#eaedf3",surfaceHover:"#dce0e8",border:"#ccd0da",muted:"#6c6f85",text:"#4c4f69"},radius:$}},{id:"github",name:"GitHub",note:"Primer's own tokens, six-pixel corners included.",group:"Ported",source:"@primer/primitives",theme:{name:"GitHub",hue:{accent:"#1f6feb",accentLight:"#4493f8",secondary:"#8957e5",secondaryLight:"#a371f7",success:"#238636",danger:"#da3633",dangerLight:"#f85149",warning:"#9e6a03",onAccent:"#ffffff",onSecondary:"#ffffff",onDanger:"#ffffff"},lightHue:{accent:"#0969da",accentLight:"#218bff",secondary:"#8250df",secondaryLight:"#a475f9",success:"#1f883d",danger:"#cf222e",dangerLight:"#d1242f",warning:"#9a6700",onAccent:"#ffffff",onSecondary:"#ffffff",onDanger:"#ffffff"},dark:{bg:"#0d1117",surface:"#151b23",surfaceRaised:"#1c222b",surfaceHover:"#262c36",border:"#3d444d",muted:"#9198a1",text:"#f0f6fc"},light:{bg:"#f6f8fa",surface:"#ffffff",surfaceRaised:"#fbfcfd",surfaceHover:"#eef1f4",border:"#d1d9e0",muted:"#59636e",text:"#1f2328"},radius:ge}},{id:"claude",name:"Claude",note:"Anthropic's clay orange on cream and near-black.",group:"Ported",source:"anthropic.com — a likeness, not a published palette",theme:{name:"Claude",hue:{accent:"#d97757",accentLight:"#e59275",secondary:"#7d9ec4",secondaryLight:"#9db8d6",success:"#6ba368",danger:"#bf4d43",dangerLight:"#d4726a",warning:"#d9a441",onAccent:"#241009",onSecondary:"#0c1720",onDanger:"#faf9f5"},lightHue:null,dark:{bg:"#141413",surface:"#1f1e1d",surfaceRaised:"#262624",surfaceHover:"#3d3d3a",border:"#3d3d3a",muted:"#b0aea5",text:"#faf9f5"},light:{bg:"#f0eee6",surface:"#faf9f5",surfaceRaised:"#f5f3ec",surfaceHover:"#e8e6dc",border:"#d5d2c5",muted:"#87867f",text:"#141413"},radius:$}},{id:"shadcn",name:"shadcn/ui",note:"Zinc neutrals and a ten-pixel radius. No pills anywhere.",group:"Ported",source:"ui.shadcn.com, MIT — accent adapted",theme:{name:"shadcn/ui",hue:{accent:"#a1a1aa",accentLight:"#d4d4d8",secondary:"#71717a",secondaryLight:"#a1a1aa",success:"#4ade80",danger:"#e7000b",dangerLight:"#fb2c36",warning:"#fd9a00",onAccent:"#18181b",onSecondary:"#fafafa",onDanger:"#fafafa"},lightHue:{accent:"#3f3f46",accentLight:"#52525b",secondary:"#71717a",secondaryLight:"#a1a1aa",success:"#00a63e",danger:"#e7000b",dangerLight:"#fb2c36",warning:"#e17100",onAccent:"#fafafa",onSecondary:"#fafafa",onDanger:"#fafafa"},dark:{bg:"#18181b",surface:"#27272a",surfaceRaised:"#3f3f46",surfaceHover:"#3f3f46",border:"#3f3f46",muted:"#a1a1aa",text:"#fafafa"},light:{bg:"#f4f4f5",surface:"#ffffff",surfaceRaised:"#fafafa",surfaceHover:"#e4e4e7",border:"#e4e4e7",muted:"#71717a",text:"#18181b"},radius:ie}},{id:"solarized",name:"Solarized",note:"Both halves on one set of accents, as designed.",group:"Ported",source:"ethanschoonover.com/solarized, MIT",theme:{name:"Solarized",hue:{accent:"#268bd2",accentLight:"#4ba3e3",secondary:"#2aa198",secondaryLight:"#43bbb1",success:"#859900",danger:"#dc322f",dangerLight:"#cb4b16",warning:"#b58900",onAccent:"#fdf6e3",onSecondary:"#002b36",onDanger:"#fdf6e3"},lightHue:null,dark:{bg:"#002b36",surface:"#073642",surfaceRaised:"#0b414f",surfaceHover:"#134b5a",border:"#0f4757",muted:"#93a1a1",text:"#eee8d5"},light:{bg:"#eee8d5",surface:"#fdf6e3",surfaceRaised:"#f7f0dc",surfaceHover:"#e4dcc4",border:"#d9d0b4",muted:"#586e75",text:"#073642"},radius:Y}}],le=new Map(B.map(r=>[r.id,r])),he=[0,.1217,.3812,.6579,.883,1.0304,1.1034,1.12,1.1025,1.0705,1.0376,1.0115,.9949,.987,.9857,.9881,.992,.9959,.9989,1.0008,1.0016,1.0017,1.0014,1.0009,1.0004,1.0001,1],be=[0,.0496,.1585,.2869,.4135,.5279,.6263,.7079,.7741,.8268,.8681,.9002,.9249,.9437,.958,.9688,.9768,.9829,.9874,.9907,.9932,.995,.9963,.9973,.9981,.9986,1],ye={spring:500,springSoft:700,fast:150},me={button:{hover:1.03,press:.96},toast:{hover:1.04,press:.96},sliderThumb:{hover:1.12,press:.94}};function pe(r,a){if(r.length===0)return a;if(a<=0)return r[0];if(a>=1)return r[r.length-1];const t=(r.length-1)*a,e=Math.floor(t),s=t-e,c=r[e],n=r[e+1]??c;return c+(n-c)*s}exports.GRYT_HUE_KEYS=R;exports.GRYT_NEUTRAL_KEYS=N;exports.GRYT_RADIUS_KEYS=k;exports.GRYT_THEME_NAME_MAX=z;exports.alphaScale=H;exports.cloneGrytTheme=I;exports.contrast=re;exports.createGrytTheme=te;exports.decodeGrytTheme=fe;exports.encodeGrytTheme=se;exports.grytAlphaScales=ae;exports.grytAlphaScalesLight=ce;exports.grytDurations=ye;exports.grytLightTokens=i;exports.grytPresets=B;exports.grytPresetsById=le;exports.grytScaleSteps=me;exports.grytScales=_;exports.grytScalesLight=w;exports.grytTheme=p;exports.grytThemeHues=K;exports.grytThemeToOptions=ne;exports.grytTokens=o;exports.hexToOklch=x;exports.hexToRgb=L;exports.hueScale=l;exports.hueScaleLight=h;exports.isHexColor=U;exports.neutralScale=G;exports.neutralScaleLight=P;exports.normalizeHexColor=v;exports.normalizeThemeName=A;exports.oklchToHex=y;exports.rgbToHex=D;exports.sampleCurve=pe;exports.springSamples=he;exports.springTightSamples=be;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/oklch.ts","../src/createGrytTheme.ts","../src/theme.ts","../src/presets.ts"],"sourcesContent":["/**\n * sRGB and OKLCH, and the scale generator that runs on both sides of the build.\n *\n * This exists at runtime rather than only in a script because overriding a\n * colour has to regenerate that colour's whole scale. A theme that set\n * --gryt-accent and left --gryt-accent-9 alone would change almost nothing:\n * the components read the scale.\n *\n * No dependency. The conversions are the published OKLab matrices, and the\n * whole file is about eighty lines of arithmetic — a colour library would be\n * more weight than the maths it replaces.\n */\n\nexport interface Oklch {\n l: number;\n c: number;\n h: number;\n}\n\nfunction srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\n\nfunction linearToSrgb(c: number): number {\n return c <= 0.0031308 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;\n}\n\nfunction clamp01(value: number): number {\n return Math.min(1, Math.max(0, value));\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace(\"#\", \"\");\n const full =\n h.length === 3\n ? h\n .split(\"\")\n .map((c) => c + c)\n .join(\"\")\n : h;\n return [\n parseInt(full.slice(0, 2), 16) / 255,\n parseInt(full.slice(2, 4), 16) / 255,\n parseInt(full.slice(4, 6), 16) / 255\n ];\n}\n\nexport function rgbToHex([r, g, b]: [number, number, number]): string {\n const part = (c: number) =>\n Math.round(clamp01(c) * 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${part(r)}${part(g)}${part(b)}`;\n}\n\nexport function hexToOklch(hex: string): Oklch {\n const [r0, g0, b0] = hexToRgb(hex).map(srgbToLinear) as [\n number,\n number,\n number\n ];\n const l = Math.cbrt(\n 0.4122214708 * r0 + 0.5363325363 * g0 + 0.0514459929 * b0\n );\n const m = Math.cbrt(\n 0.2119034982 * r0 + 0.6806995451 * g0 + 0.1073969566 * b0\n );\n const s = Math.cbrt(\n 0.0883024619 * r0 + 0.2817188376 * g0 + 0.6299787005 * b0\n );\n const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;\n const a = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;\n const b = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;\n return {\n l: L,\n c: Math.hypot(a, b),\n h: ((Math.atan2(b, a) * 180) / Math.PI + 360) % 360\n };\n}\n\nexport function oklchToHex({ l, c, h }: Oklch): string {\n const a = c * Math.cos((h * Math.PI) / 180);\n const b = c * Math.sin((h * Math.PI) / 180);\n const l3 = (l + 0.3963377774 * a + 0.2158037573 * b) ** 3;\n const m3 = (l - 0.1055613458 * a - 0.0638541728 * b) ** 3;\n const s3 = (l - 0.0894841775 * a - 1.291485548 * b) ** 3;\n return rgbToHex([\n linearToSrgb(clamp01(4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3)),\n linearToSrgb(clamp01(-1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3)),\n linearToSrgb(clamp01(-0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3))\n ]);\n}\n\n/** The lightness and chroma of each step on a hue scale, dark theme. */\nconst HUE_L = [0.195, 0.24, 0.27, 0.3, 0.33, 0.37, 0.43, 0.52];\nconst HUE_C = [0.014, 0.026, 0.04, 0.052, 0.062, 0.072, 0.084, 0.1];\n\n/**\n * Twelve steps for a hue, from its solid step and the lighter one beside it.\n *\n * Steps 1 to 8 are the hue sunk into the dark end of the ramp — backgrounds,\n * then borders. 9 and 10 are the anchors themselves. 11 and 12 are text, and\n * they are placed relative to 10 rather than at a fixed lightness: the -light\n * tokens differ family to family, so a fixed value puts the text step above the\n * fill in one scale and below it in another.\n */\nexport function hueScale(solid: string, solidHover: string): string[] {\n const { h } = hexToOklch(solid);\n const steps = HUE_L.map((l, i) => oklchToHex({ l, c: HUE_C[i], h }));\n steps.push(solid, solidHover);\n\n const l10 = hexToOklch(solidHover).l;\n const l11 = Math.min(0.95, Math.max(0.84, l10 + 0.04));\n const l12 = Math.min(0.98, Math.max(l11 + 0.06, 0.93));\n steps.push(oklchToHex({ l: l11, c: 0.11, h }));\n steps.push(oklchToHex({ l: l12, c: 0.055, h }));\n return steps;\n}\n\nconst NEUTRAL_L = [\n 0.187, 0.231, 0.245, 0.268, 0.289, 0.31, 0.355, 0.425, 0.52, 0.57, 0.627,\n 0.908\n];\nconst NEUTRAL_C = [\n 0.011, 0.014, 0.016, 0.019, 0.022, 0.024, 0.026, 0.026, 0.02, 0.012, 0.0,\n 0.008\n];\n\n/**\n * Twelve neutral steps, from the six an app names directly.\n *\n * Those six are kept exactly — a theme that says its background is #0b0b0f\n * means it, and interpolating through it would move it by a shade.\n */\nexport function neutralScale(anchors: {\n bg: string;\n surface: string;\n surfaceRaised: string;\n border: string;\n muted: string;\n text: string;\n}): string[] {\n const fixed: Record<number, string> = {\n 0: anchors.bg,\n 1: anchors.surface,\n 2: anchors.surfaceRaised,\n 5: anchors.border,\n 10: anchors.muted,\n 11: anchors.text\n };\n const hue = hexToOklch(anchors.border).h;\n return NEUTRAL_L.map(\n (l, i) => fixed[i] ?? oklchToHex({ l, c: NEUTRAL_C[i], h: hue })\n );\n}\n\n/**\n * The same steps as translucent overlays.\n *\n * Solved rather than guessed: the smallest alpha whose overlay colour is still\n * inside the gamut, which is what makes a tinted hover composite to the same\n * value over an avatar as it does over the app background.\n */\nexport function alphaScale(scale: string[], background: string): string[] {\n const bg = hexToRgb(background);\n return scale.map((hex) => {\n const target = hexToRgb(hex);\n let alpha = 0;\n for (let i = 0; i < 3; i++) {\n const t = target[i];\n const b = bg[i];\n if (t > b) alpha = Math.max(alpha, b < 1 ? (t - b) / (1 - b) : 0);\n else if (t < b) alpha = Math.max(alpha, b > 0 ? (b - t) / b : 0);\n }\n if (alpha < 1e-6) return \"transparent\";\n const overlay = rgbToHex(\n target.map((t, i) => clamp01(bg[i] + (t - bg[i]) / alpha)) as [\n number,\n number,\n number\n ]\n );\n const [r, g, b] = hexToRgb(overlay).map((c) => Math.round(c * 255));\n return `rgb(${r} ${g} ${b} / ${(alpha * 100).toFixed(1)}%)`;\n });\n}\n\n/* ── light ──────────────────────────────────────────────────────────────\n Not a mirror of the dark ramps, because elevation does not mirror. In dark,\n a surface sitting on the page is lighter than the page; in light it is\n whiter and the page is the grey one. So step 1 is a light grey page and step\n 2 is white, and the ramp is deliberately not monotonic across those two —\n that non-monotonicity *is* the elevation.\n\n The text steps are the ones that had to be measured. In dark they need to be\n light enough on near-black; here they need to be dark enough on white, which\n is a different and tighter constraint because step 2 is pure white. */\n\nconst LIGHT_NEUTRAL_L = [\n 0.962, 1.0, 0.978, 0.952, 0.928, 0.898, 0.855, 0.79, 0.66, 0.61, 0.48, 0.25\n];\nconst LIGHT_NEUTRAL_C = [\n 0.006, 0.0, 0.004, 0.007, 0.01, 0.013, 0.016, 0.018, 0.016, 0.014, 0.012,\n 0.014\n];\n\nconst LIGHT_HUE_L = [0.975, 0.955, 0.93, 0.905, 0.878, 0.845, 0.795, 0.72];\nconst LIGHT_HUE_C = [0.012, 0.024, 0.038, 0.05, 0.062, 0.074, 0.09, 0.11];\n\n/** Twelve light neutral steps. Anchors are kept exactly, as in the dark set. */\nexport function neutralScaleLight(anchors: {\n bg: string;\n surface: string;\n surfaceRaised: string;\n border: string;\n muted: string;\n text: string;\n}): string[] {\n const fixed: Record<number, string> = {\n 0: anchors.bg,\n 1: anchors.surface,\n 2: anchors.surfaceRaised,\n 5: anchors.border,\n 10: anchors.muted,\n 11: anchors.text\n };\n const hue = hexToOklch(anchors.border).h;\n return LIGHT_NEUTRAL_L.map(\n (l, i) => fixed[i] ?? oklchToHex({ l, c: LIGHT_NEUTRAL_C[i], h: hue })\n );\n}\n\n/**\n * Twelve light steps for a hue.\n *\n * Step 9 stays the brand colour, so a filled button is the same colour in both\n * appearances and Gryt looks like Gryt either way. 10 goes *darker* for hover,\n * which is the light-mode direction — the dark set goes lighter. 11 and 12 are\n * text, dark enough to read on white.\n */\nexport function hueScaleLight(solid: string): string[] {\n const { l, c, h } = hexToOklch(solid);\n const steps = LIGHT_HUE_L.map((sl, i) =>\n oklchToHex({ l: sl, c: LIGHT_HUE_C[i], h })\n );\n steps.push(solid);\n steps.push(oklchToHex({ l: Math.max(0, l - 0.07), c, h }));\n // 0.46 rather than 0.5, which is where this started. Step 11 has to carry\n // text on step 3 as well as on the page — a Chip, an Alert and a Toast are\n // all that pairing — and at 0.5 the secondary hue measured 4.48:1 against its\n // own tint. Four hundredths of lightness is not visible; failing AA is.\n steps.push(oklchToHex({ l: 0.46, c: 0.15, h }));\n steps.push(oklchToHex({ l: 0.33, c: 0.1, h }));\n return steps;\n}\n\n/** WCAG relative luminance, for asserting contrast rather than eyeballing it. */\nfunction luminance(hex: string): number {\n const [r, g, b] = hexToRgb(hex).map(srgbToLinear);\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/** WCAG contrast ratio. 4.5 is AA for body text, 3 for large text and UI. */\nexport function contrast(a: string, b: string): number {\n const la = luminance(a);\n const lb = luminance(b);\n return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);\n}\n","import type { CSSProperties } from \"react\";\nimport {\n alphaScale,\n hueScale,\n hueScaleLight,\n neutralScale,\n neutralScaleLight\n} from \"./oklch\";\n\nexport const grytTokens = {\n color: {\n bg: \"#111318\",\n surface: \"#1a1d24\",\n surfaceRaised: \"#1e2028\",\n surfaceHover: \"#334155\",\n border: \"#2b303d\",\n text: \"#e0e0e6\",\n muted: \"#888888\",\n accent: \"#968ff8\",\n accentLight: \"#b4afff\",\n secondary: \"#7dd3fc\",\n secondaryLight: \"#bae6fd\",\n success: \"#4ade80\",\n danger: \"#f87171\",\n dangerLight: \"#fca5a5\",\n warning: \"#fbbf24\",\n // The fill's own hue, dark enough to clear 7:1 against it. See the note in\n // theme.css: these are the only text in the library that always sits on a\n // saturated colour, so they are held to AAA rather than AA.\n onAccent: \"#0c0a20\",\n onSecondary: \"#02121a\",\n onDanger: \"#1f0405\"\n },\n radius: {\n sm: 8,\n md: 12,\n lg: 20,\n xl: 28,\n full: 999\n }\n} as const;\n\nexport type GrytTokens = typeof grytTokens;\n\n// Widened off the `as const` token types on purpose. Partial<GrytTokens> would\n// inherit the literal types, so an override could only ever be re-assigned its\n// own current value.\nexport interface GrytThemeOptions {\n color?: Partial<Record<keyof GrytTokens[\"color\"], string>>;\n radius?: Partial<Record<keyof GrytTokens[\"radius\"], number>>;\n /**\n * Which set of ramps to build. Dark is the default because it is what the\n * library ships on :root; an app toggling appearance calls this twice and\n * puts each result behind its own selector.\n */\n appearance?: \"dark\" | \"light\";\n}\n\n// This used to return a MUI theme object. There is no theme object now — the\n// components read CSS custom properties, so a theme is the set of variables to\n// put on an element. Returning CSSProperties means it drops straight into a\n// style prop, and overriding one token does not require reproducing the rest.\n/**\n * The scales, computed rather than written down.\n *\n * There is one generator, and this is it — theme.css is emitted from these same\n * functions by scripts/generate-theme.ts, and a test asserts the stylesheet\n * still matches. Two hand-maintained copies of a twelve-step ramp would drift\n * the first time somebody nudged a colour.\n */\n/**\n * The light anchors.\n *\n * Picked for this palette rather than computed from the dark ones. The page is\n * a light grey and panels are white, which is the arrangement the client\n * already used and the one people expect of a light UI.\n */\nexport const grytLightTokens = {\n bg: \"#f1f2f7\",\n surface: \"#ffffff\",\n surfaceRaised: \"#f7f8fb\",\n border: \"#dadde6\",\n muted: \"#5b5d65\",\n text: \"#1f2129\"\n} as const;\n\nexport const grytScales = {\n neutral: neutralScale({\n bg: grytTokens.color.bg,\n surface: grytTokens.color.surface,\n surfaceRaised: grytTokens.color.surfaceRaised,\n border: grytTokens.color.border,\n muted: grytTokens.color.muted,\n text: grytTokens.color.text\n }),\n accent: hueScale(grytTokens.color.accent, grytTokens.color.accentLight),\n secondary: hueScale(\n grytTokens.color.secondary,\n grytTokens.color.secondaryLight\n ),\n success: hueScale(grytTokens.color.success, grytTokens.color.success),\n danger: hueScale(grytTokens.color.danger, grytTokens.color.dangerLight),\n warning: hueScale(grytTokens.color.warning, grytTokens.color.warning)\n} as const;\n\n/** The same six families, light. */\nexport const grytScalesLight = {\n neutral: neutralScaleLight(grytLightTokens),\n accent: hueScaleLight(grytTokens.color.accent),\n secondary: hueScaleLight(grytTokens.color.secondary),\n success: hueScaleLight(grytTokens.color.success),\n danger: hueScaleLight(grytTokens.color.danger),\n warning: hueScaleLight(grytTokens.color.warning)\n} as const;\n\n/**\n * The light hover fill.\n *\n * Not one of the six anchors, because it is not a colour anybody picks: it is\n * step 4, the step that means \"component background, hovered\", and writing it\n * down as a literal would be a second definition of a value the ramp already\n * has. It exists at all because `.light` never set surface-hover, so a neutral\n * Button in a light app hovered to the dark slate the @theme block declares —\n * a slate block on a white panel.\n */\nexport const grytLightSurfaceHover = grytScalesLight.neutral[3];\n\nexport const grytAlphaScales = {\n neutral: alphaScale(grytScales.neutral, grytTokens.color.bg),\n accent: alphaScale(grytScales.accent, grytTokens.color.bg)\n} as const;\n\nexport const grytAlphaScalesLight = {\n neutral: alphaScale(grytScalesLight.neutral, grytLightTokens.bg),\n accent: alphaScale(grytScalesLight.accent, grytLightTokens.bg)\n} as const;\n\nexport function createGrytTheme(options: GrytThemeOptions = {}): CSSProperties {\n const light = options.appearance === \"light\";\n const defaults = light\n ? {\n ...grytTokens.color,\n ...grytLightTokens,\n surfaceHover: grytLightSurfaceHover\n }\n : grytTokens.color;\n const color = { ...defaults, ...options.color };\n const radius = { ...grytTokens.radius, ...options.radius };\n\n /**\n * Overriding a colour regenerates its scale.\n *\n * The components read the scale, not the flat name — bg-gryt-neutral-4 for a\n * hover, text-gryt-accent-11 for a link — so a theme that set --gryt-accent\n * and stopped there would change almost nothing on screen. The same\n * generator that produced the defaults runs here on whatever anchors the\n * caller passed, which is what makes one line of override recolour the app\n * coherently rather than in patches.\n */\n const anchors = {\n bg: color.bg,\n surface: color.surface,\n surfaceRaised: color.surfaceRaised,\n border: color.border,\n muted: color.muted,\n text: color.text\n };\n const scales: Record<string, string[]> = light\n ? {\n neutral: neutralScaleLight(anchors),\n accent: hueScaleLight(color.accent),\n secondary: hueScaleLight(color.secondary),\n success: hueScaleLight(color.success),\n danger: hueScaleLight(color.danger),\n warning: hueScaleLight(color.warning)\n }\n : {\n neutral: neutralScale(anchors),\n accent: hueScale(color.accent, color.accentLight),\n secondary: hueScale(color.secondary, color.secondaryLight),\n success: hueScale(color.success, color.success),\n danger: hueScale(color.danger, color.dangerLight),\n warning: hueScale(color.warning, color.warning)\n };\n\n const scaleVars: Record<string, string> = {};\n for (const [name, steps] of Object.entries(scales)) {\n steps.forEach((value, index) => {\n scaleVars[`--gryt-${name}-${index + 1}`] = value;\n scaleVars[`--color-gryt-${name}-${index + 1}`] = value;\n });\n }\n for (const name of [\"neutral\", \"accent\"] as const) {\n alphaScale(scales[name], color.bg).forEach((value, index) => {\n scaleVars[`--gryt-${name}-a${index + 1}`] = value;\n scaleVars[`--color-gryt-${name}-a${index + 1}`] = value;\n });\n }\n\n return {\n ...scaleVars,\n \"--gryt-bg\": color.bg,\n \"--gryt-surface\": color.surface,\n \"--gryt-surface-raised\": color.surfaceRaised,\n \"--gryt-surface-hover\": color.surfaceHover,\n \"--gryt-border\": color.border,\n \"--gryt-text\": color.text,\n \"--gryt-muted\": color.muted,\n \"--gryt-accent\": color.accent,\n \"--gryt-accent-light\": color.accentLight,\n \"--gryt-secondary\": color.secondary,\n \"--gryt-secondary-light\": color.secondaryLight,\n \"--gryt-success\": color.success,\n \"--gryt-danger\": color.danger,\n \"--gryt-danger-light\": color.dangerLight,\n \"--gryt-warning\": color.warning,\n \"--gryt-on-accent\": color.onAccent,\n \"--gryt-on-secondary\": color.onSecondary,\n \"--gryt-on-danger\": color.onDanger,\n\n // Tailwind's @theme emits --color-* names, and the utilities compile\n // against those. Both sets have to move together or an override would\n // change the raw var but not bg-gryt-accent.\n \"--color-gryt-bg\": color.bg,\n \"--color-gryt-surface\": color.surface,\n \"--color-gryt-surface-raised\": color.surfaceRaised,\n \"--color-gryt-surface-hover\": color.surfaceHover,\n \"--color-gryt-border\": color.border,\n \"--color-gryt-text\": color.text,\n \"--color-gryt-muted\": color.muted,\n \"--color-gryt-accent\": color.accent,\n \"--color-gryt-accent-light\": color.accentLight,\n \"--color-gryt-secondary\": color.secondary,\n \"--color-gryt-secondary-light\": color.secondaryLight,\n \"--color-gryt-success\": color.success,\n \"--color-gryt-danger\": color.danger,\n \"--color-gryt-danger-light\": color.dangerLight,\n \"--color-gryt-warning\": color.warning,\n \"--color-gryt-on-accent\": color.onAccent,\n \"--color-gryt-on-secondary\": color.onSecondary,\n \"--color-gryt-on-danger\": color.onDanger,\n\n \"--gryt-radius-sm\": `${radius.sm}px`,\n \"--gryt-radius-md\": `${radius.md}px`,\n \"--gryt-radius-lg\": `${radius.lg}px`,\n \"--gryt-radius-xl\": `${radius.xl}px`,\n \"--gryt-radius-full\": `${radius.full}px`\n } as CSSProperties;\n}\n","/* A whole theme, as a thing you can hand to somebody.\n *\n * createGrytTheme takes the colours for one appearance. That is the right shape\n * for the caller who wants one theme, and the wrong shape for a theme that\n * travels: dark and light do not derive from each other, so a theme somebody\n * shares has to carry both.\n *\n * Two sets of neutrals, then, and one set of hues — because step 9 is the same\n * colour in both appearances by design, so a filled button does not change\n * colour when somebody switches. `lightHue` is the exception, for palettes\n * where that is not true. Catppuccin's mauve is #cba6f7 in Mocha and #8839ef in\n * Latte; forcing one on it would make the theme wrong in one half.\n *\n * The encoding is a query string because that is the useful property of a\n * palette this small: a theme is a couple of dozen hex values, which fits in a\n * link, and a link is the thing people actually send each other. Only what\n * differs from Gryt's own values is carried, so a theme that changed one colour\n * is a link with one parameter in it.\n */\n\nimport { grytLightSurfaceHover, grytLightTokens, grytTokens } from \"./createGrytTheme\";\nimport type { GrytThemeOptions } from \"./createGrytTheme\";\n\nexport type GrytAppearance = \"dark\" | \"light\";\n\nexport const GRYT_HUE_KEYS = [\n \"accent\",\n \"accentLight\",\n \"secondary\",\n \"secondaryLight\",\n \"success\",\n \"danger\",\n \"dangerLight\",\n \"warning\",\n \"onAccent\",\n \"onSecondary\",\n \"onDanger\"\n] as const;\n\nexport const GRYT_NEUTRAL_KEYS = [\n \"bg\",\n \"surface\",\n \"surfaceRaised\",\n \"surfaceHover\",\n \"border\",\n \"muted\",\n \"text\"\n] as const;\n\nexport const GRYT_RADIUS_KEYS = [\"sm\", \"md\", \"lg\", \"xl\", \"full\"] as const;\n\nexport type GrytHueKey = (typeof GRYT_HUE_KEYS)[number];\nexport type GrytNeutralKey = (typeof GRYT_NEUTRAL_KEYS)[number];\nexport type GrytRadiusKey = (typeof GRYT_RADIUS_KEYS)[number];\n\nexport type GrytHues = Record<GrytHueKey, string>;\nexport type GrytNeutrals = Record<GrytNeutralKey, string>;\n\nexport interface GrytTheme {\n /**\n * What its author called it, if they called it anything.\n *\n * Metadata rather than a colour: nothing about how a theme looks depends on\n * it, and grytThemeToOptions drops it. It exists because a link full of hex\n * values says nothing about what it is, and the person who made it already\n * knew — so the receiving end should not have to ask.\n */\n name?: string;\n hue: GrytHues;\n /** Null when light borrows the hues above, which is the usual case. */\n lightHue: GrytHues | null;\n dark: GrytNeutrals;\n light: GrytNeutrals;\n radius: Record<GrytRadiusKey, number>;\n}\n\n/** Long enough for a name, short enough not to be a payload. */\nexport const GRYT_THEME_NAME_MAX = 60;\n\nexport function normalizeThemeName(value: string): string {\n return value.replace(/\\s+/g, \" \").trim().slice(0, GRYT_THEME_NAME_MAX);\n}\n\n/** What the library ships, as a document. */\nexport const grytTheme: GrytTheme = {\n hue: {\n accent: grytTokens.color.accent,\n accentLight: grytTokens.color.accentLight,\n secondary: grytTokens.color.secondary,\n secondaryLight: grytTokens.color.secondaryLight,\n success: grytTokens.color.success,\n danger: grytTokens.color.danger,\n dangerLight: grytTokens.color.dangerLight,\n warning: grytTokens.color.warning,\n onAccent: grytTokens.color.onAccent,\n onSecondary: grytTokens.color.onSecondary,\n onDanger: grytTokens.color.onDanger\n },\n lightHue: null,\n dark: {\n bg: grytTokens.color.bg,\n surface: grytTokens.color.surface,\n surfaceRaised: grytTokens.color.surfaceRaised,\n surfaceHover: grytTokens.color.surfaceHover,\n border: grytTokens.color.border,\n muted: grytTokens.color.muted,\n text: grytTokens.color.text\n },\n light: {\n bg: grytLightTokens.bg,\n surface: grytLightTokens.surface,\n surfaceRaised: grytLightTokens.surfaceRaised,\n surfaceHover: grytLightSurfaceHover,\n border: grytLightTokens.border,\n muted: grytLightTokens.muted,\n text: grytLightTokens.text\n },\n radius: { ...grytTokens.radius }\n};\n\nexport function cloneGrytTheme(theme: GrytTheme): GrytTheme {\n return {\n ...(theme.name === undefined ? {} : { name: theme.name }),\n hue: { ...theme.hue },\n lightHue: theme.lightHue === null ? null : { ...theme.lightHue },\n dark: { ...theme.dark },\n light: { ...theme.light },\n radius: { ...theme.radius }\n };\n}\n\n/** Which hues this appearance reads. */\nexport function grytThemeHues(\n theme: GrytTheme,\n appearance: GrytAppearance\n): GrytHues {\n return appearance === \"light\" && theme.lightHue !== null\n ? theme.lightHue\n : theme.hue;\n}\n\n/**\n * One appearance of a theme, in the shape createGrytTheme takes.\n *\n * The name does not come along: createGrytTheme returns CSS variables, and a\n * name is not one.\n */\nexport function grytThemeToOptions(\n theme: GrytTheme,\n appearance: GrytAppearance\n): GrytThemeOptions {\n return {\n appearance,\n color: { ...grytThemeHues(theme, appearance), ...theme[appearance] },\n radius: { ...theme.radius }\n };\n}\n\n/* ── the link ─────────────────────────────────────────────────────────── */\n\nconst HUE_PARAM: Record<GrytHueKey, string> = {\n accent: \"accent\",\n accentLight: \"accent-light\",\n secondary: \"secondary\",\n secondaryLight: \"secondary-light\",\n success: \"success\",\n danger: \"danger\",\n dangerLight: \"danger-light\",\n warning: \"warning\",\n onAccent: \"on-accent\",\n onSecondary: \"on-secondary\",\n onDanger: \"on-danger\"\n};\n\nconst NEUTRAL_PARAM: Record<GrytNeutralKey, string> = {\n bg: \"bg\",\n surface: \"surface\",\n surfaceRaised: \"raised\",\n surfaceHover: \"hover\",\n border: \"border\",\n muted: \"muted\",\n text: \"text\"\n};\n\nconst HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;\n\nexport function isHexColor(value: string): boolean {\n return HEX.test(value.trim());\n}\n\n/** #abc to #aabbcc, lower case, so two of the same colour compare equal. */\nexport function normalizeHexColor(value: string): string {\n const hex = value.trim().toLowerCase();\n return hex.length === 4\n ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`\n : hex;\n}\n\n/**\n * The theme as query parameters, carrying only what differs from Gryt's own.\n *\n * `appearance` is which half the sender was looking at, and it rides along\n * because a shared link that opens on the other one is showing something the\n * sender never saw.\n */\nexport function encodeGrytTheme(\n theme: GrytTheme,\n appearance?: GrytAppearance\n): URLSearchParams {\n const params = new URLSearchParams();\n const bare = (hex: string) => normalizeHexColor(hex).slice(1);\n\n const name = normalizeThemeName(theme.name ?? \"\");\n if (name !== \"\") params.set(\"name\", name);\n\n for (const key of GRYT_HUE_KEYS) {\n if (theme.hue[key] !== grytTheme.hue[key]) {\n params.set(HUE_PARAM[key], bare(theme.hue[key]));\n }\n }\n // A split light set is carried whole rather than diffed. It is only there\n // when somebody meant it, and diffing it against the dark hues would drop\n // exactly the values that make it a split.\n if (theme.lightHue !== null) {\n for (const key of GRYT_HUE_KEYS) {\n params.set(`lh-${HUE_PARAM[key]}`, bare(theme.lightHue[key]));\n }\n }\n for (const half of [\"dark\", \"light\"] as const) {\n const prefix = half === \"dark\" ? \"d\" : \"l\";\n for (const key of GRYT_NEUTRAL_KEYS) {\n if (theme[half][key] !== grytTheme[half][key]) {\n params.set(`${prefix}-${NEUTRAL_PARAM[key]}`, bare(theme[half][key]));\n }\n }\n }\n for (const key of GRYT_RADIUS_KEYS) {\n if (theme.radius[key] !== grytTheme.radius[key]) {\n params.set(`r-${key}`, String(theme.radius[key]));\n }\n }\n if (appearance === \"light\") params.set(\"mode\", \"light\");\n\n return params;\n}\n\nexport interface DecodedGrytTheme {\n theme: GrytTheme;\n /** Which half the link was sent from. Dark unless it says otherwise. */\n appearance: GrytAppearance;\n}\n\n/**\n * Whatever somebody pasted.\n *\n * A whole URL, a bare query string, or the JSON form — one function, because\n * from the outside they are the same act. Null when there is no theme in it at\n * all; a value it cannot parse is left at Gryt's, so one mistyped colour does\n * not throw the rest away.\n */\nexport function decodeGrytTheme(input: string): DecodedGrytTheme | null {\n const text = input.trim();\n if (text === \"\") return null;\n if (text.startsWith(\"{\")) return decodeJson(text);\n\n const query = text.includes(\"?\") ? text.slice(text.indexOf(\"?\") + 1) : text;\n return decodeParams(new URLSearchParams(query));\n}\n\nfunction decodeParams(params: URLSearchParams): DecodedGrytTheme | null {\n const theme = cloneGrytTheme(grytTheme);\n let present = false;\n\n const read = (name: string): string | null => {\n const raw = params.get(name);\n if (raw === null) return null;\n const hex = raw.startsWith(\"#\") ? raw : `#${raw}`;\n if (!isHexColor(hex)) return null;\n present = true;\n return normalizeHexColor(hex);\n };\n\n const name = normalizeThemeName(params.get(\"name\") ?? \"\");\n if (name !== \"\") {\n theme.name = name;\n present = true;\n }\n\n for (const key of GRYT_HUE_KEYS) {\n const value = read(HUE_PARAM[key]);\n if (value !== null) theme.hue[key] = value;\n }\n if (params.has(`lh-${HUE_PARAM.accent}`)) {\n const light = { ...theme.hue };\n for (const key of GRYT_HUE_KEYS) {\n const value = read(`lh-${HUE_PARAM[key]}`);\n if (value !== null) light[key] = value;\n }\n theme.lightHue = light;\n }\n for (const half of [\"dark\", \"light\"] as const) {\n const prefix = half === \"dark\" ? \"d\" : \"l\";\n for (const key of GRYT_NEUTRAL_KEYS) {\n const value = read(`${prefix}-${NEUTRAL_PARAM[key]}`);\n if (value !== null) theme[half][key] = value;\n }\n }\n for (const key of GRYT_RADIUS_KEYS) {\n const value = Number(params.get(`r-${key}`));\n // Anything outside this is a typo or somebody having a laugh, and a\n // 40000px radius makes an app look broken rather than themed.\n if (Number.isFinite(value) && value >= 0 && value <= 999 && params.has(`r-${key}`)) {\n theme.radius[key] = Math.round(value);\n present = true;\n }\n }\n\n if (!present) return null;\n return {\n theme,\n appearance: params.get(\"mode\") === \"light\" ? \"light\" : \"dark\"\n };\n}\n\nfunction decodeJson(text: string): DecodedGrytTheme | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n if (typeof parsed !== \"object\" || parsed === null) return null;\n const source = parsed as Record<string, unknown>;\n\n const theme = cloneGrytTheme(grytTheme);\n let present = false;\n\n const colors = (value: unknown, target: Record<string, string>) => {\n if (typeof value !== \"object\" || value === null) return;\n for (const [key, raw] of Object.entries(value as Record<string, unknown>)) {\n if (typeof raw === \"string\" && isHexColor(raw) && key in target) {\n target[key] = normalizeHexColor(raw);\n present = true;\n }\n }\n };\n\n if (typeof source.name === \"string\") {\n const named = normalizeThemeName(source.name);\n if (named !== \"\") {\n theme.name = named;\n present = true;\n }\n }\n\n colors(source.hue, theme.hue);\n colors(source.dark, theme.dark);\n colors(source.light, theme.light);\n\n if (typeof source.lightHue === \"object\" && source.lightHue !== null) {\n const light = { ...theme.hue };\n colors(source.lightHue, light);\n theme.lightHue = light;\n }\n\n if (typeof source.radius === \"object\" && source.radius !== null) {\n for (const [key, raw] of Object.entries(\n source.radius as Record<string, unknown>\n )) {\n const value = Number(raw);\n if (\n (GRYT_RADIUS_KEYS as readonly string[]).includes(key) &&\n Number.isFinite(value) &&\n value >= 0 &&\n value <= 999\n ) {\n theme.radius[key as GrytRadiusKey] = Math.round(value);\n present = true;\n }\n }\n }\n\n if (!present) return null;\n return { theme, appearance: \"dark\" };\n}\n","/* Themes to start from.\n *\n * Two kinds. The Gryt ones show the range — warm, near-monochrome,\n * high-contrast, and the palette the library ships. The ported ones are\n * well-known palettes, because \"can it look like the thing I already use?\" is\n * the question people arrive with, and a paragraph claiming yes is worth less\n * than a click.\n *\n * Every ported value is the published one, taken from the source named in the\n * comment above each preset rather than from memory. Where a palette defines\n * both a dark and a light variant — Alucard, Latte, Snow Storm, GitHub Light,\n * Solarized Light — both are here, which is why lightHue exists: Catppuccin's\n * mauve and GitHub's blue are genuinely different colours in each half, and\n * sharing one would make the preset wrong in the other.\n *\n * Two honest limits, and the page says both:\n *\n * - Gryt names seven neutral anchors. Most palettes name fewer, so the steps\n * in between are derived — marked `derived` where that happens. Nothing\n * derived is invented out of nowhere; it sits between two published values.\n * - A palette is a set of names with colours behind them, and mapping those\n * names onto \"page, surface, border, muted, text\" is a judgement. Somebody\n * else mapping the same palette would put a couple of them elsewhere.\n *\n * Radius is part of a preset too. GitHub's buttons are not pills and\n * Solarized's are square; a preset that got the colours right and left\n * everything fully rounded would not look like the thing it names.\n *\n * Names belong to their projects. Dracula, Nord, Catppuccin, Solarized and\n * shadcn/ui are MIT-licensed; the rest are referenced by name only.\n *\n * These ship with the library rather than with the docs site, because the docs\n * site is not the only thing that lists them: the client offers the same set,\n * and it should get a new one by taking a newer @gryt/ui rather than by\n * somebody copying eleven palettes across by hand.\n */\n\nimport type { GrytRadiusKey, GrytTheme } from \"./theme\";\nimport { grytTheme } from \"./theme\";\n\nexport interface GrytThemePreset {\n id: string;\n name: string;\n /** One line under the name: what makes this one different. */\n note: string;\n group: \"Gryt\" | \"Ported\";\n /** Where the values came from. Shown as the attribution line. */\n source?: string;\n theme: GrytTheme;\n}\n\ntype Radius = Record<GrytRadiusKey, number>;\n\nconst ROUND: Radius = { sm: 8, md: 12, lg: 20, xl: 28, full: 999 };\nconst SOFT: Radius = { sm: 6, md: 8, lg: 14, xl: 18, full: 999 };\n/** Buttons that are not pills. `full` is what controls use, so it does the work. */\nconst CRISP: Radius = { sm: 4, md: 6, lg: 10, xl: 14, full: 6 };\nconst SHADCN: Radius = { sm: 6, md: 8, lg: 10, xl: 14, full: 10 };\nconst SQUARE: Radius = { sm: 2, md: 4, lg: 6, xl: 8, full: 4 };\n\nexport const grytPresets: GrytThemePreset[] = [\n {\n id: \"gryt\",\n name: \"Gryt\",\n note: \"What the library ships, from the Gryt code-theme.\",\n group: \"Gryt\",\n source: \"github.com/Gryt-chat/code-theme\",\n theme: grytTheme\n },\n {\n id: \"ember\",\n name: \"Ember\",\n note: \"Warm all the way down — the neutrals are brown, not blue.\",\n group: \"Gryt\",\n theme: {\n name: \"Ember\",\n hue: {\n accent: \"#f0803c\",\n accentLight: \"#ff9f66\",\n secondary: \"#d9a441\",\n secondaryLight: \"#ecc06a\",\n success: \"#8bb056\",\n danger: \"#e35d55\",\n dangerLight: \"#ef8079\",\n warning: \"#e8b33e\",\n onAccent: \"#231004\",\n onSecondary: \"#241a04\",\n onDanger: \"#2b0a08\"\n },\n lightHue: null,\n dark: {\n bg: \"#17110e\",\n surface: \"#1f1815\",\n surfaceRaised: \"#251d19\",\n surfaceHover: \"#33261f\",\n border: \"#352822\",\n muted: \"#a48f81\",\n text: \"#f5ece5\"\n },\n light: {\n bg: \"#f6efe8\",\n surface: \"#fffdfb\",\n surfaceRaised: \"#faf3ec\",\n surfaceHover: \"#efe3d8\",\n border: \"#e0d2c4\",\n muted: \"#6b5b50\",\n text: \"#241a14\"\n },\n radius: ROUND\n }\n },\n {\n id: \"paper\",\n name: \"Paper\",\n note: \"Near-monochrome. One quiet slate accent and nothing else.\",\n group: \"Gryt\",\n theme: {\n name: \"Paper\",\n hue: {\n accent: \"#8390a8\",\n accentLight: \"#a3aec2\",\n secondary: \"#93a0a0\",\n secondaryLight: \"#b1bcbc\",\n success: \"#7f9b7f\",\n danger: \"#b56b6b\",\n dangerLight: \"#c98d8d\",\n warning: \"#b39a6a\",\n onAccent: \"#11151c\",\n onSecondary: \"#121717\",\n onDanger: \"#1d0e0e\"\n },\n lightHue: null,\n dark: {\n bg: \"#101011\",\n surface: \"#17171a\",\n surfaceRaised: \"#1d1d20\",\n surfaceHover: \"#282a2e\",\n border: \"#2a2a2e\",\n muted: \"#8e8e94\",\n text: \"#ededf0\"\n },\n light: {\n bg: \"#f0f0f2\",\n surface: \"#ffffff\",\n surfaceRaised: \"#f7f7f9\",\n surfaceHover: \"#e6e6ea\",\n border: \"#d6d6dc\",\n muted: \"#5b5b63\",\n text: \"#17171a\"\n },\n radius: SOFT\n }\n },\n {\n id: \"signal\",\n name: \"Signal\",\n note: \"Black, white, and a yellow that cannot be missed.\",\n group: \"Gryt\",\n theme: {\n name: \"Signal\",\n hue: {\n accent: \"#ffd400\",\n accentLight: \"#ffe454\",\n secondary: \"#00d0ff\",\n secondaryLight: \"#66e2ff\",\n success: \"#00e06a\",\n danger: \"#ff453a\",\n dangerLight: \"#ff7a72\",\n warning: \"#ffab00\",\n onAccent: \"#161200\",\n onSecondary: \"#001a20\",\n onDanger: \"#1a0300\"\n },\n lightHue: null,\n dark: {\n bg: \"#000000\",\n surface: \"#0c0c0c\",\n surfaceRaised: \"#151515\",\n surfaceHover: \"#242424\",\n border: \"#454545\",\n muted: \"#bcbcbc\",\n text: \"#ffffff\"\n },\n light: {\n bg: \"#f0f0f0\",\n surface: \"#ffffff\",\n surfaceRaised: \"#f8f8f8\",\n surfaceHover: \"#e3e3e3\",\n border: \"#6f6f6f\",\n muted: \"#3d3d3d\",\n text: \"#000000\"\n },\n radius: SQUARE\n }\n },\n {\n /* Dracula's eleven, and Alucard's eleven for the light half, from the\n palette tables in dracula/dracula-theme. Background, Current Line,\n Foreground and Comment are exact; the two steps between Background and\n Current Line are derived, because Dracula does not name them. */\n id: \"dracula\",\n name: \"Dracula\",\n note: \"The purple-and-pink dark theme, with Alucard as its light half.\",\n group: \"Ported\",\n source: \"draculatheme.com, MIT\",\n theme: {\n name: \"Dracula\",\n hue: {\n accent: \"#bd93f9\",\n accentLight: \"#d0b3fb\",\n secondary: \"#8be9fd\",\n secondaryLight: \"#aff0fe\",\n success: \"#50fa7b\",\n danger: \"#ff5555\",\n dangerLight: \"#ff7979\",\n warning: \"#ffb86c\",\n onAccent: \"#282a36\",\n onSecondary: \"#282a36\",\n onDanger: \"#282a36\"\n },\n lightHue: {\n accent: \"#644ac9\",\n accentLight: \"#7b64d6\",\n secondary: \"#036a96\",\n secondaryLight: \"#0b83b5\",\n success: \"#14710a\",\n danger: \"#cb3a2a\",\n dangerLight: \"#d95445\",\n warning: \"#a34d14\",\n onAccent: \"#fffbeb\",\n onSecondary: \"#fffbeb\",\n onDanger: \"#fffbeb\"\n },\n dark: {\n bg: \"#282a36\",\n surface: \"#31323f\",\n surfaceRaised: \"#383a49\",\n surfaceHover: \"#44475a\",\n border: \"#44475a\",\n muted: \"#6272a4\",\n text: \"#f8f8f2\"\n },\n light: {\n bg: \"#f5f1e1\",\n surface: \"#fffbeb\",\n surfaceRaised: \"#faf6e6\",\n surfaceHover: \"#ece7d4\",\n border: \"#dcd6bf\",\n muted: \"#6c664b\",\n text: \"#1f1f1f\"\n },\n radius: SOFT\n }\n },\n {\n /* nord0-nord15, exactly as nordtheme.com publishes them. Polar Night is\n the dark neutrals, Snow Storm the light ones, Frost the accents and\n Aurora the status colours. Nothing here is derived. */\n id: \"nord\",\n name: \"Nord\",\n note: \"Polar Night and Snow Storm, with Frost on top.\",\n group: \"Ported\",\n source: \"nordtheme.com, MIT\",\n theme: {\n name: \"Nord\",\n hue: {\n accent: \"#88c0d0\",\n accentLight: \"#8fbcbb\",\n secondary: \"#81a1c1\",\n secondaryLight: \"#a3b8d4\",\n success: \"#a3be8c\",\n danger: \"#bf616a\",\n dangerLight: \"#d08770\",\n warning: \"#ebcb8b\",\n onAccent: \"#2e3440\",\n onSecondary: \"#2e3440\",\n onDanger: \"#eceff4\"\n },\n lightHue: {\n accent: \"#5e81ac\",\n accentLight: \"#81a1c1\",\n secondary: \"#8fbcbb\",\n secondaryLight: \"#88c0d0\",\n success: \"#a3be8c\",\n danger: \"#bf616a\",\n dangerLight: \"#d08770\",\n warning: \"#ebcb8b\",\n onAccent: \"#eceff4\",\n onSecondary: \"#2e3440\",\n onDanger: \"#eceff4\"\n },\n dark: {\n bg: \"#2e3440\",\n surface: \"#3b4252\",\n surfaceRaised: \"#434c5e\",\n surfaceHover: \"#4c566a\",\n border: \"#4c566a\",\n muted: \"#d8dee9\",\n text: \"#eceff4\"\n },\n light: {\n bg: \"#e5e9f0\",\n surface: \"#eceff4\",\n surfaceRaised: \"#e9edf2\",\n surfaceHover: \"#d8dee9\",\n border: \"#c9d1de\",\n muted: \"#4c566a\",\n text: \"#2e3440\"\n },\n radius: SOFT\n }\n },\n {\n /* Mocha and Latte from catppuccin/palette's palette.json. base, mantle,\n surface0/1/2, text and subtext0 are exact; the border step is derived\n from surface1 and surface2, which is where a border sits in their own\n ports. */\n id: \"catppuccin\",\n name: \"Catppuccin\",\n note: \"Mocha for dark, Latte for light. Mauve does the accent work.\",\n group: \"Ported\",\n source: \"catppuccin/palette, MIT\",\n theme: {\n name: \"Catppuccin\",\n hue: {\n accent: \"#cba6f7\",\n accentLight: \"#dcc0fa\",\n secondary: \"#89b4fa\",\n secondaryLight: \"#a8c8fb\",\n success: \"#a6e3a1\",\n danger: \"#f38ba8\",\n dangerLight: \"#eba0ac\",\n warning: \"#f9e2af\",\n onAccent: \"#1e1e2e\",\n onSecondary: \"#1e1e2e\",\n onDanger: \"#1e1e2e\"\n },\n lightHue: {\n accent: \"#8839ef\",\n accentLight: \"#9a55f2\",\n secondary: \"#1e66f5\",\n secondaryLight: \"#4680f7\",\n success: \"#40a02b\",\n danger: \"#d20f39\",\n dangerLight: \"#e64553\",\n warning: \"#df8e1d\",\n onAccent: \"#eff1f5\",\n onSecondary: \"#eff1f5\",\n onDanger: \"#eff1f5\"\n },\n dark: {\n bg: \"#1e1e2e\",\n surface: \"#313244\",\n surfaceRaised: \"#45475a\",\n surfaceHover: \"#585b70\",\n border: \"#45475a\",\n muted: \"#a6adc8\",\n text: \"#cdd6f4\"\n },\n light: {\n bg: \"#e6e9ef\",\n surface: \"#eff1f5\",\n surfaceRaised: \"#eaedf3\",\n surfaceHover: \"#dce0e8\",\n border: \"#ccd0da\",\n muted: \"#6c6f85\",\n text: \"#4c4f69\"\n },\n radius: ROUND\n }\n },\n {\n /* Primer's functional tokens, from @primer/primitives' compiled themes:\n bgColor-default, bgColor-muted, borderColor-default, fgColor-default,\n fgColor-muted, and the -emphasis fills for accent, danger, success,\n attention and done. The raised and hover steps are derived — Primer\n expresses those as translucent overlays rather than as solid colours. */\n id: \"github\",\n name: \"GitHub\",\n note: \"Primer's own tokens, six-pixel corners included.\",\n group: \"Ported\",\n source: \"@primer/primitives\",\n theme: {\n name: \"GitHub\",\n hue: {\n accent: \"#1f6feb\",\n accentLight: \"#4493f8\",\n secondary: \"#8957e5\",\n secondaryLight: \"#a371f7\",\n success: \"#238636\",\n danger: \"#da3633\",\n dangerLight: \"#f85149\",\n warning: \"#9e6a03\",\n onAccent: \"#ffffff\",\n onSecondary: \"#ffffff\",\n onDanger: \"#ffffff\"\n },\n lightHue: {\n accent: \"#0969da\",\n accentLight: \"#218bff\",\n secondary: \"#8250df\",\n secondaryLight: \"#a475f9\",\n success: \"#1f883d\",\n danger: \"#cf222e\",\n dangerLight: \"#d1242f\",\n warning: \"#9a6700\",\n onAccent: \"#ffffff\",\n onSecondary: \"#ffffff\",\n onDanger: \"#ffffff\"\n },\n dark: {\n bg: \"#0d1117\",\n surface: \"#151b23\",\n surfaceRaised: \"#1c222b\",\n surfaceHover: \"#262c36\",\n border: \"#3d444d\",\n muted: \"#9198a1\",\n text: \"#f0f6fc\"\n },\n light: {\n bg: \"#f6f8fa\",\n surface: \"#ffffff\",\n surfaceRaised: \"#fbfcfd\",\n surfaceHover: \"#eef1f4\",\n border: \"#d1d9e0\",\n muted: \"#59636e\",\n text: \"#1f2328\"\n },\n radius: CRISP\n }\n },\n {\n /* Read off anthropic.com's own stylesheet: the clay #d97757, the cream\n #f0eee6 and #faf9f5, the ink #141413, and the neutrals #3d3d3a,\n #87867f, #b0aea5, #c6c4ba, #e8e6dc. Anthropic publishes no token file,\n so the status hues have no published counterpart and are Gryt's own —\n this is the one preset that is a likeness rather than a port. */\n id: \"claude\",\n name: \"Claude\",\n note: \"Anthropic's clay orange on cream and near-black.\",\n group: \"Ported\",\n source: \"anthropic.com — a likeness, not a published palette\",\n theme: {\n name: \"Claude\",\n hue: {\n accent: \"#d97757\",\n accentLight: \"#e59275\",\n secondary: \"#7d9ec4\",\n secondaryLight: \"#9db8d6\",\n success: \"#6ba368\",\n danger: \"#bf4d43\",\n dangerLight: \"#d4726a\",\n warning: \"#d9a441\",\n onAccent: \"#241009\",\n onSecondary: \"#0c1720\",\n onDanger: \"#faf9f5\"\n },\n lightHue: null,\n dark: {\n bg: \"#141413\",\n surface: \"#1f1e1d\",\n surfaceRaised: \"#262624\",\n surfaceHover: \"#3d3d3a\",\n border: \"#3d3d3a\",\n muted: \"#b0aea5\",\n text: \"#faf9f5\"\n },\n light: {\n bg: \"#f0eee6\",\n surface: \"#faf9f5\",\n surfaceRaised: \"#f5f3ec\",\n surfaceHover: \"#e8e6dc\",\n border: \"#d5d2c5\",\n muted: \"#87867f\",\n text: \"#141413\"\n },\n radius: ROUND\n }\n },\n {\n /* The zinc theme from shadcn-ui/ui's registry, converted from its OKLCH\n values. One deliberate departure: shadcn's primary is monochrome —\n near-white in dark, near-black in light — which cannot be a Gryt accent,\n because the accent is also the colour every link and focus ring is drawn\n from. Its destructive red is the accent here, and the neutrals are the\n theme's own. */\n id: \"shadcn\",\n name: \"shadcn/ui\",\n note: \"Zinc neutrals and a ten-pixel radius. No pills anywhere.\",\n group: \"Ported\",\n source: \"ui.shadcn.com, MIT — accent adapted\",\n theme: {\n name: \"shadcn/ui\",\n hue: {\n accent: \"#a1a1aa\",\n accentLight: \"#d4d4d8\",\n secondary: \"#71717a\",\n secondaryLight: \"#a1a1aa\",\n success: \"#4ade80\",\n danger: \"#e7000b\",\n dangerLight: \"#fb2c36\",\n warning: \"#fd9a00\",\n onAccent: \"#18181b\",\n onSecondary: \"#fafafa\",\n onDanger: \"#fafafa\"\n },\n lightHue: {\n accent: \"#3f3f46\",\n accentLight: \"#52525b\",\n secondary: \"#71717a\",\n secondaryLight: \"#a1a1aa\",\n success: \"#00a63e\",\n danger: \"#e7000b\",\n dangerLight: \"#fb2c36\",\n warning: \"#e17100\",\n onAccent: \"#fafafa\",\n onSecondary: \"#fafafa\",\n onDanger: \"#fafafa\"\n },\n dark: {\n bg: \"#18181b\",\n surface: \"#27272a\",\n surfaceRaised: \"#3f3f46\",\n surfaceHover: \"#3f3f46\",\n border: \"#3f3f46\",\n muted: \"#a1a1aa\",\n text: \"#fafafa\"\n },\n light: {\n bg: \"#f4f4f5\",\n surface: \"#ffffff\",\n surfaceRaised: \"#fafafa\",\n surfaceHover: \"#e4e4e7\",\n border: \"#e4e4e7\",\n muted: \"#71717a\",\n text: \"#18181b\"\n },\n radius: SHADCN\n }\n },\n {\n /* Ethan Schoonover's sixteen, exactly. base03 and base02 are the dark\n page and surface, base2 and base3 the light ones, and the accent hues\n are shared between the two halves — which is the whole point of\n Solarized. The steps between base03 and base02 are derived. */\n id: \"solarized\",\n name: \"Solarized\",\n note: \"Both halves on one set of accents, as designed.\",\n group: \"Ported\",\n source: \"ethanschoonover.com/solarized, MIT\",\n theme: {\n name: \"Solarized\",\n hue: {\n accent: \"#268bd2\",\n accentLight: \"#4ba3e3\",\n secondary: \"#2aa198\",\n secondaryLight: \"#43bbb1\",\n success: \"#859900\",\n danger: \"#dc322f\",\n dangerLight: \"#cb4b16\",\n warning: \"#b58900\",\n onAccent: \"#fdf6e3\",\n onSecondary: \"#002b36\",\n onDanger: \"#fdf6e3\"\n },\n lightHue: null,\n dark: {\n bg: \"#002b36\",\n surface: \"#073642\",\n surfaceRaised: \"#0b414f\",\n surfaceHover: \"#134b5a\",\n border: \"#0f4757\",\n muted: \"#93a1a1\",\n text: \"#eee8d5\"\n },\n light: {\n bg: \"#eee8d5\",\n surface: \"#fdf6e3\",\n surfaceRaised: \"#f7f0dc\",\n surfaceHover: \"#e4dcc4\",\n border: \"#d9d0b4\",\n muted: \"#586e75\",\n text: \"#073642\"\n },\n radius: SQUARE\n }\n }\n];\n\nexport const grytPresetsById = new Map(\n grytPresets.map((preset) => [preset.id, preset])\n);\n"],"names":["srgbToLinear","c","linearToSrgb","clamp01","value","hexToRgb","hex","h","full","rgbToHex","g","b","part","hexToOklch","r0","g0","b0","l","m","s","L","a","oklchToHex","l3","m3","s3","HUE_L","HUE_C","hueScale","solid","solidHover","steps","i","l10","l11","l12","NEUTRAL_L","NEUTRAL_C","neutralScale","anchors","fixed","hue","alphaScale","scale","background","bg","target","alpha","t","overlay","r","LIGHT_NEUTRAL_L","LIGHT_NEUTRAL_C","LIGHT_HUE_L","LIGHT_HUE_C","neutralScaleLight","hueScaleLight","sl","luminance","contrast","la","lb","grytTokens","grytLightTokens","grytScales","grytScalesLight","grytLightSurfaceHover","grytAlphaScales","grytAlphaScalesLight","createGrytTheme","options","light","color","radius","scales","scaleVars","name","index","GRYT_HUE_KEYS","GRYT_NEUTRAL_KEYS","GRYT_RADIUS_KEYS","GRYT_THEME_NAME_MAX","normalizeThemeName","grytTheme","cloneGrytTheme","theme","grytThemeHues","appearance","grytThemeToOptions","HUE_PARAM","NEUTRAL_PARAM","HEX","isHexColor","normalizeHexColor","encodeGrytTheme","params","bare","key","half","prefix","decodeGrytTheme","input","text","decodeJson","query","decodeParams","present","read","raw","parsed","source","colors","named","ROUND","SOFT","CRISP","SHADCN","SQUARE","grytPresets","grytPresetsById","preset"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/oklch.ts","../src/createGrytTheme.ts","../src/theme.ts","../src/presets.ts","../src/motion.ts"],"sourcesContent":["/**\n * sRGB and OKLCH, and the scale generator that runs on both sides of the build.\n *\n * This exists at runtime rather than only in a script because overriding a\n * colour has to regenerate that colour's whole scale. A theme that set\n * --gryt-accent and left --gryt-accent-9 alone would change almost nothing:\n * the components read the scale.\n *\n * No dependency. The conversions are the published OKLab matrices, and the\n * whole file is about eighty lines of arithmetic — a colour library would be\n * more weight than the maths it replaces.\n */\n\nexport interface Oklch {\n l: number;\n c: number;\n h: number;\n}\n\nfunction srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\n\nfunction linearToSrgb(c: number): number {\n return c <= 0.0031308 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;\n}\n\nfunction clamp01(value: number): number {\n return Math.min(1, Math.max(0, value));\n}\n\nexport function hexToRgb(hex: string): [number, number, number] {\n const h = hex.replace(\"#\", \"\");\n const full =\n h.length === 3\n ? h\n .split(\"\")\n .map((c) => c + c)\n .join(\"\")\n : h;\n return [\n parseInt(full.slice(0, 2), 16) / 255,\n parseInt(full.slice(2, 4), 16) / 255,\n parseInt(full.slice(4, 6), 16) / 255\n ];\n}\n\nexport function rgbToHex([r, g, b]: [number, number, number]): string {\n const part = (c: number) =>\n Math.round(clamp01(c) * 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${part(r)}${part(g)}${part(b)}`;\n}\n\nexport function hexToOklch(hex: string): Oklch {\n const [r0, g0, b0] = hexToRgb(hex).map(srgbToLinear) as [\n number,\n number,\n number\n ];\n const l = Math.cbrt(\n 0.4122214708 * r0 + 0.5363325363 * g0 + 0.0514459929 * b0\n );\n const m = Math.cbrt(\n 0.2119034982 * r0 + 0.6806995451 * g0 + 0.1073969566 * b0\n );\n const s = Math.cbrt(\n 0.0883024619 * r0 + 0.2817188376 * g0 + 0.6299787005 * b0\n );\n const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;\n const a = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;\n const b = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;\n return {\n l: L,\n c: Math.hypot(a, b),\n h: ((Math.atan2(b, a) * 180) / Math.PI + 360) % 360\n };\n}\n\nexport function oklchToHex({ l, c, h }: Oklch): string {\n const a = c * Math.cos((h * Math.PI) / 180);\n const b = c * Math.sin((h * Math.PI) / 180);\n const l3 = (l + 0.3963377774 * a + 0.2158037573 * b) ** 3;\n const m3 = (l - 0.1055613458 * a - 0.0638541728 * b) ** 3;\n const s3 = (l - 0.0894841775 * a - 1.291485548 * b) ** 3;\n return rgbToHex([\n linearToSrgb(clamp01(4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3)),\n linearToSrgb(clamp01(-1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3)),\n linearToSrgb(clamp01(-0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3))\n ]);\n}\n\n/** The lightness and chroma of each step on a hue scale, dark theme. */\nconst HUE_L = [0.195, 0.24, 0.27, 0.3, 0.33, 0.37, 0.43, 0.52];\nconst HUE_C = [0.014, 0.026, 0.04, 0.052, 0.062, 0.072, 0.084, 0.1];\n\n/**\n * Twelve steps for a hue, from its solid step and the lighter one beside it.\n *\n * Steps 1 to 8 are the hue sunk into the dark end of the ramp — backgrounds,\n * then borders. 9 and 10 are the anchors themselves. 11 and 12 are text, and\n * they are placed relative to 10 rather than at a fixed lightness: the -light\n * tokens differ family to family, so a fixed value puts the text step above the\n * fill in one scale and below it in another.\n */\nexport function hueScale(solid: string, solidHover: string): string[] {\n const { h } = hexToOklch(solid);\n const steps = HUE_L.map((l, i) => oklchToHex({ l, c: HUE_C[i], h }));\n steps.push(solid, solidHover);\n\n const l10 = hexToOklch(solidHover).l;\n const l11 = Math.min(0.95, Math.max(0.84, l10 + 0.04));\n const l12 = Math.min(0.98, Math.max(l11 + 0.06, 0.93));\n steps.push(oklchToHex({ l: l11, c: 0.11, h }));\n steps.push(oklchToHex({ l: l12, c: 0.055, h }));\n return steps;\n}\n\nconst NEUTRAL_L = [\n 0.187, 0.231, 0.245, 0.268, 0.289, 0.31, 0.355, 0.425, 0.52, 0.57, 0.627,\n 0.908\n];\nconst NEUTRAL_C = [\n 0.011, 0.014, 0.016, 0.019, 0.022, 0.024, 0.026, 0.026, 0.02, 0.012, 0.0,\n 0.008\n];\n\n/**\n * Twelve neutral steps, from the six an app names directly.\n *\n * Those six are kept exactly — a theme that says its background is #0b0b0f\n * means it, and interpolating through it would move it by a shade.\n */\nexport function neutralScale(anchors: {\n bg: string;\n surface: string;\n surfaceRaised: string;\n border: string;\n muted: string;\n text: string;\n}): string[] {\n const fixed: Record<number, string> = {\n 0: anchors.bg,\n 1: anchors.surface,\n 2: anchors.surfaceRaised,\n 5: anchors.border,\n 10: anchors.muted,\n 11: anchors.text\n };\n const hue = hexToOklch(anchors.border).h;\n return NEUTRAL_L.map(\n (l, i) => fixed[i] ?? oklchToHex({ l, c: NEUTRAL_C[i], h: hue })\n );\n}\n\n/**\n * The same steps as translucent overlays.\n *\n * Solved rather than guessed: the smallest alpha whose overlay colour is still\n * inside the gamut, which is what makes a tinted hover composite to the same\n * value over an avatar as it does over the app background.\n */\nexport function alphaScale(scale: string[], background: string): string[] {\n const bg = hexToRgb(background);\n return scale.map((hex) => {\n const target = hexToRgb(hex);\n let alpha = 0;\n for (let i = 0; i < 3; i++) {\n const t = target[i];\n const b = bg[i];\n if (t > b) alpha = Math.max(alpha, b < 1 ? (t - b) / (1 - b) : 0);\n else if (t < b) alpha = Math.max(alpha, b > 0 ? (b - t) / b : 0);\n }\n if (alpha < 1e-6) return \"transparent\";\n const overlay = rgbToHex(\n target.map((t, i) => clamp01(bg[i] + (t - bg[i]) / alpha)) as [\n number,\n number,\n number\n ]\n );\n const [r, g, b] = hexToRgb(overlay).map((c) => Math.round(c * 255));\n return `rgb(${r} ${g} ${b} / ${(alpha * 100).toFixed(1)}%)`;\n });\n}\n\n/* ── light ──────────────────────────────────────────────────────────────\n Not a mirror of the dark ramps, because elevation does not mirror. In dark,\n a surface sitting on the page is lighter than the page; in light it is\n whiter and the page is the grey one. So step 1 is a light grey page and step\n 2 is white, and the ramp is deliberately not monotonic across those two —\n that non-monotonicity *is* the elevation.\n\n The text steps are the ones that had to be measured. In dark they need to be\n light enough on near-black; here they need to be dark enough on white, which\n is a different and tighter constraint because step 2 is pure white. */\n\nconst LIGHT_NEUTRAL_L = [\n 0.962, 1.0, 0.978, 0.952, 0.928, 0.898, 0.855, 0.79, 0.66, 0.61, 0.48, 0.25\n];\nconst LIGHT_NEUTRAL_C = [\n 0.006, 0.0, 0.004, 0.007, 0.01, 0.013, 0.016, 0.018, 0.016, 0.014, 0.012,\n 0.014\n];\n\nconst LIGHT_HUE_L = [0.975, 0.955, 0.93, 0.905, 0.878, 0.845, 0.795, 0.72];\nconst LIGHT_HUE_C = [0.012, 0.024, 0.038, 0.05, 0.062, 0.074, 0.09, 0.11];\n\n/** Twelve light neutral steps. Anchors are kept exactly, as in the dark set. */\nexport function neutralScaleLight(anchors: {\n bg: string;\n surface: string;\n surfaceRaised: string;\n border: string;\n muted: string;\n text: string;\n}): string[] {\n const fixed: Record<number, string> = {\n 0: anchors.bg,\n 1: anchors.surface,\n 2: anchors.surfaceRaised,\n 5: anchors.border,\n 10: anchors.muted,\n 11: anchors.text\n };\n const hue = hexToOklch(anchors.border).h;\n return LIGHT_NEUTRAL_L.map(\n (l, i) => fixed[i] ?? oklchToHex({ l, c: LIGHT_NEUTRAL_C[i], h: hue })\n );\n}\n\n/**\n * Twelve light steps for a hue.\n *\n * Step 9 stays the brand colour, so a filled button is the same colour in both\n * appearances and Gryt looks like Gryt either way. 10 goes *darker* for hover,\n * which is the light-mode direction — the dark set goes lighter. 11 and 12 are\n * text, dark enough to read on white.\n */\nexport function hueScaleLight(solid: string): string[] {\n const { l, c, h } = hexToOklch(solid);\n const steps = LIGHT_HUE_L.map((sl, i) =>\n oklchToHex({ l: sl, c: LIGHT_HUE_C[i], h })\n );\n steps.push(solid);\n steps.push(oklchToHex({ l: Math.max(0, l - 0.07), c, h }));\n // 0.46 rather than 0.5, which is where this started. Step 11 has to carry\n // text on step 3 as well as on the page — a Chip, an Alert and a Toast are\n // all that pairing — and at 0.5 the secondary hue measured 4.48:1 against its\n // own tint. Four hundredths of lightness is not visible; failing AA is.\n steps.push(oklchToHex({ l: 0.46, c: 0.15, h }));\n steps.push(oklchToHex({ l: 0.33, c: 0.1, h }));\n return steps;\n}\n\n/** WCAG relative luminance, for asserting contrast rather than eyeballing it. */\nfunction luminance(hex: string): number {\n const [r, g, b] = hexToRgb(hex).map(srgbToLinear);\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\n/** WCAG contrast ratio. 4.5 is AA for body text, 3 for large text and UI. */\nexport function contrast(a: string, b: string): number {\n const la = luminance(a);\n const lb = luminance(b);\n return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);\n}\n","import type { CSSProperties } from \"react\";\nimport {\n alphaScale,\n hueScale,\n hueScaleLight,\n neutralScale,\n neutralScaleLight\n} from \"./oklch\";\n\nexport const grytTokens = {\n color: {\n bg: \"#111318\",\n surface: \"#1a1d24\",\n surfaceRaised: \"#1e2028\",\n surfaceHover: \"#334155\",\n border: \"#2b303d\",\n text: \"#e0e0e6\",\n muted: \"#888888\",\n accent: \"#968ff8\",\n accentLight: \"#b4afff\",\n secondary: \"#7dd3fc\",\n secondaryLight: \"#bae6fd\",\n success: \"#4ade80\",\n danger: \"#f87171\",\n dangerLight: \"#fca5a5\",\n warning: \"#fbbf24\",\n // The fill's own hue, dark enough to clear 7:1 against it. See the note in\n // theme.css: these are the only text in the library that always sits on a\n // saturated colour, so they are held to AAA rather than AA.\n onAccent: \"#0c0a20\",\n onSecondary: \"#02121a\",\n onDanger: \"#1f0405\"\n },\n radius: {\n sm: 8,\n md: 12,\n lg: 20,\n xl: 28,\n full: 999\n }\n} as const;\n\nexport type GrytTokens = typeof grytTokens;\n\n// Widened off the `as const` token types on purpose. Partial<GrytTokens> would\n// inherit the literal types, so an override could only ever be re-assigned its\n// own current value.\nexport interface GrytThemeOptions {\n color?: Partial<Record<keyof GrytTokens[\"color\"], string>>;\n radius?: Partial<Record<keyof GrytTokens[\"radius\"], number>>;\n /**\n * Which set of ramps to build. Dark is the default because it is what the\n * library ships on :root; an app toggling appearance calls this twice and\n * puts each result behind its own selector.\n */\n appearance?: \"dark\" | \"light\";\n}\n\n// This used to return a MUI theme object. There is no theme object now — the\n// components read CSS custom properties, so a theme is the set of variables to\n// put on an element. Returning CSSProperties means it drops straight into a\n// style prop, and overriding one token does not require reproducing the rest.\n/**\n * The scales, computed rather than written down.\n *\n * There is one generator, and this is it — theme.css is emitted from these same\n * functions by scripts/generate-theme.ts, and a test asserts the stylesheet\n * still matches. Two hand-maintained copies of a twelve-step ramp would drift\n * the first time somebody nudged a colour.\n */\n/**\n * The light anchors.\n *\n * Picked for this palette rather than computed from the dark ones. The page is\n * a light grey and panels are white, which is the arrangement the client\n * already used and the one people expect of a light UI.\n */\nexport const grytLightTokens = {\n bg: \"#f1f2f7\",\n surface: \"#ffffff\",\n surfaceRaised: \"#f7f8fb\",\n border: \"#dadde6\",\n muted: \"#5b5d65\",\n text: \"#1f2129\"\n} as const;\n\nexport const grytScales = {\n neutral: neutralScale({\n bg: grytTokens.color.bg,\n surface: grytTokens.color.surface,\n surfaceRaised: grytTokens.color.surfaceRaised,\n border: grytTokens.color.border,\n muted: grytTokens.color.muted,\n text: grytTokens.color.text\n }),\n accent: hueScale(grytTokens.color.accent, grytTokens.color.accentLight),\n secondary: hueScale(\n grytTokens.color.secondary,\n grytTokens.color.secondaryLight\n ),\n success: hueScale(grytTokens.color.success, grytTokens.color.success),\n danger: hueScale(grytTokens.color.danger, grytTokens.color.dangerLight),\n warning: hueScale(grytTokens.color.warning, grytTokens.color.warning)\n} as const;\n\n/** The same six families, light. */\nexport const grytScalesLight = {\n neutral: neutralScaleLight(grytLightTokens),\n accent: hueScaleLight(grytTokens.color.accent),\n secondary: hueScaleLight(grytTokens.color.secondary),\n success: hueScaleLight(grytTokens.color.success),\n danger: hueScaleLight(grytTokens.color.danger),\n warning: hueScaleLight(grytTokens.color.warning)\n} as const;\n\n/**\n * The light hover fill.\n *\n * Not one of the six anchors, because it is not a colour anybody picks: it is\n * step 4, the step that means \"component background, hovered\", and writing it\n * down as a literal would be a second definition of a value the ramp already\n * has. It exists at all because `.light` never set surface-hover, so a neutral\n * Button in a light app hovered to the dark slate the @theme block declares —\n * a slate block on a white panel.\n */\nexport const grytLightSurfaceHover = grytScalesLight.neutral[3];\n\nexport const grytAlphaScales = {\n neutral: alphaScale(grytScales.neutral, grytTokens.color.bg),\n accent: alphaScale(grytScales.accent, grytTokens.color.bg)\n} as const;\n\nexport const grytAlphaScalesLight = {\n neutral: alphaScale(grytScalesLight.neutral, grytLightTokens.bg),\n accent: alphaScale(grytScalesLight.accent, grytLightTokens.bg)\n} as const;\n\nexport function createGrytTheme(options: GrytThemeOptions = {}): CSSProperties {\n const light = options.appearance === \"light\";\n const defaults = light\n ? {\n ...grytTokens.color,\n ...grytLightTokens,\n surfaceHover: grytLightSurfaceHover\n }\n : grytTokens.color;\n const color = { ...defaults, ...options.color };\n const radius = { ...grytTokens.radius, ...options.radius };\n\n /**\n * Overriding a colour regenerates its scale.\n *\n * The components read the scale, not the flat name — bg-gryt-neutral-4 for a\n * hover, text-gryt-accent-11 for a link — so a theme that set --gryt-accent\n * and stopped there would change almost nothing on screen. The same\n * generator that produced the defaults runs here on whatever anchors the\n * caller passed, which is what makes one line of override recolour the app\n * coherently rather than in patches.\n */\n const anchors = {\n bg: color.bg,\n surface: color.surface,\n surfaceRaised: color.surfaceRaised,\n border: color.border,\n muted: color.muted,\n text: color.text\n };\n const scales: Record<string, string[]> = light\n ? {\n neutral: neutralScaleLight(anchors),\n accent: hueScaleLight(color.accent),\n secondary: hueScaleLight(color.secondary),\n success: hueScaleLight(color.success),\n danger: hueScaleLight(color.danger),\n warning: hueScaleLight(color.warning)\n }\n : {\n neutral: neutralScale(anchors),\n accent: hueScale(color.accent, color.accentLight),\n secondary: hueScale(color.secondary, color.secondaryLight),\n success: hueScale(color.success, color.success),\n danger: hueScale(color.danger, color.dangerLight),\n warning: hueScale(color.warning, color.warning)\n };\n\n const scaleVars: Record<string, string> = {};\n for (const [name, steps] of Object.entries(scales)) {\n steps.forEach((value, index) => {\n scaleVars[`--gryt-${name}-${index + 1}`] = value;\n scaleVars[`--color-gryt-${name}-${index + 1}`] = value;\n });\n }\n for (const name of [\"neutral\", \"accent\"] as const) {\n alphaScale(scales[name], color.bg).forEach((value, index) => {\n scaleVars[`--gryt-${name}-a${index + 1}`] = value;\n scaleVars[`--color-gryt-${name}-a${index + 1}`] = value;\n });\n }\n\n return {\n ...scaleVars,\n \"--gryt-bg\": color.bg,\n \"--gryt-surface\": color.surface,\n \"--gryt-surface-raised\": color.surfaceRaised,\n \"--gryt-surface-hover\": color.surfaceHover,\n \"--gryt-border\": color.border,\n \"--gryt-text\": color.text,\n \"--gryt-muted\": color.muted,\n \"--gryt-accent\": color.accent,\n \"--gryt-accent-light\": color.accentLight,\n \"--gryt-secondary\": color.secondary,\n \"--gryt-secondary-light\": color.secondaryLight,\n \"--gryt-success\": color.success,\n \"--gryt-danger\": color.danger,\n \"--gryt-danger-light\": color.dangerLight,\n \"--gryt-warning\": color.warning,\n \"--gryt-on-accent\": color.onAccent,\n \"--gryt-on-secondary\": color.onSecondary,\n \"--gryt-on-danger\": color.onDanger,\n\n // Tailwind's @theme emits --color-* names, and the utilities compile\n // against those. Both sets have to move together or an override would\n // change the raw var but not bg-gryt-accent.\n \"--color-gryt-bg\": color.bg,\n \"--color-gryt-surface\": color.surface,\n \"--color-gryt-surface-raised\": color.surfaceRaised,\n \"--color-gryt-surface-hover\": color.surfaceHover,\n \"--color-gryt-border\": color.border,\n \"--color-gryt-text\": color.text,\n \"--color-gryt-muted\": color.muted,\n \"--color-gryt-accent\": color.accent,\n \"--color-gryt-accent-light\": color.accentLight,\n \"--color-gryt-secondary\": color.secondary,\n \"--color-gryt-secondary-light\": color.secondaryLight,\n \"--color-gryt-success\": color.success,\n \"--color-gryt-danger\": color.danger,\n \"--color-gryt-danger-light\": color.dangerLight,\n \"--color-gryt-warning\": color.warning,\n \"--color-gryt-on-accent\": color.onAccent,\n \"--color-gryt-on-secondary\": color.onSecondary,\n \"--color-gryt-on-danger\": color.onDanger,\n\n \"--gryt-radius-sm\": `${radius.sm}px`,\n \"--gryt-radius-md\": `${radius.md}px`,\n \"--gryt-radius-lg\": `${radius.lg}px`,\n \"--gryt-radius-xl\": `${radius.xl}px`,\n \"--gryt-radius-full\": `${radius.full}px`\n } as CSSProperties;\n}\n","/* A whole theme, as a thing you can hand to somebody.\n *\n * createGrytTheme takes the colours for one appearance. That is the right shape\n * for the caller who wants one theme, and the wrong shape for a theme that\n * travels: dark and light do not derive from each other, so a theme somebody\n * shares has to carry both.\n *\n * Two sets of neutrals, then, and one set of hues — because step 9 is the same\n * colour in both appearances by design, so a filled button does not change\n * colour when somebody switches. `lightHue` is the exception, for palettes\n * where that is not true. Catppuccin's mauve is #cba6f7 in Mocha and #8839ef in\n * Latte; forcing one on it would make the theme wrong in one half.\n *\n * The encoding is a query string because that is the useful property of a\n * palette this small: a theme is a couple of dozen hex values, which fits in a\n * link, and a link is the thing people actually send each other. Only what\n * differs from Gryt's own values is carried, so a theme that changed one colour\n * is a link with one parameter in it.\n */\n\nimport { grytLightSurfaceHover, grytLightTokens, grytTokens } from \"./createGrytTheme\";\nimport type { GrytThemeOptions } from \"./createGrytTheme\";\n\nexport type GrytAppearance = \"dark\" | \"light\";\n\nexport const GRYT_HUE_KEYS = [\n \"accent\",\n \"accentLight\",\n \"secondary\",\n \"secondaryLight\",\n \"success\",\n \"danger\",\n \"dangerLight\",\n \"warning\",\n \"onAccent\",\n \"onSecondary\",\n \"onDanger\"\n] as const;\n\nexport const GRYT_NEUTRAL_KEYS = [\n \"bg\",\n \"surface\",\n \"surfaceRaised\",\n \"surfaceHover\",\n \"border\",\n \"muted\",\n \"text\"\n] as const;\n\nexport const GRYT_RADIUS_KEYS = [\"sm\", \"md\", \"lg\", \"xl\", \"full\"] as const;\n\nexport type GrytHueKey = (typeof GRYT_HUE_KEYS)[number];\nexport type GrytNeutralKey = (typeof GRYT_NEUTRAL_KEYS)[number];\nexport type GrytRadiusKey = (typeof GRYT_RADIUS_KEYS)[number];\n\nexport type GrytHues = Record<GrytHueKey, string>;\nexport type GrytNeutrals = Record<GrytNeutralKey, string>;\n\nexport interface GrytTheme {\n /**\n * What its author called it, if they called it anything.\n *\n * Metadata rather than a colour: nothing about how a theme looks depends on\n * it, and grytThemeToOptions drops it. It exists because a link full of hex\n * values says nothing about what it is, and the person who made it already\n * knew — so the receiving end should not have to ask.\n */\n name?: string;\n hue: GrytHues;\n /** Null when light borrows the hues above, which is the usual case. */\n lightHue: GrytHues | null;\n dark: GrytNeutrals;\n light: GrytNeutrals;\n radius: Record<GrytRadiusKey, number>;\n}\n\n/** Long enough for a name, short enough not to be a payload. */\nexport const GRYT_THEME_NAME_MAX = 60;\n\nexport function normalizeThemeName(value: string): string {\n return value.replace(/\\s+/g, \" \").trim().slice(0, GRYT_THEME_NAME_MAX);\n}\n\n/** What the library ships, as a document. */\nexport const grytTheme: GrytTheme = {\n hue: {\n accent: grytTokens.color.accent,\n accentLight: grytTokens.color.accentLight,\n secondary: grytTokens.color.secondary,\n secondaryLight: grytTokens.color.secondaryLight,\n success: grytTokens.color.success,\n danger: grytTokens.color.danger,\n dangerLight: grytTokens.color.dangerLight,\n warning: grytTokens.color.warning,\n onAccent: grytTokens.color.onAccent,\n onSecondary: grytTokens.color.onSecondary,\n onDanger: grytTokens.color.onDanger\n },\n lightHue: null,\n dark: {\n bg: grytTokens.color.bg,\n surface: grytTokens.color.surface,\n surfaceRaised: grytTokens.color.surfaceRaised,\n surfaceHover: grytTokens.color.surfaceHover,\n border: grytTokens.color.border,\n muted: grytTokens.color.muted,\n text: grytTokens.color.text\n },\n light: {\n bg: grytLightTokens.bg,\n surface: grytLightTokens.surface,\n surfaceRaised: grytLightTokens.surfaceRaised,\n surfaceHover: grytLightSurfaceHover,\n border: grytLightTokens.border,\n muted: grytLightTokens.muted,\n text: grytLightTokens.text\n },\n radius: { ...grytTokens.radius }\n};\n\nexport function cloneGrytTheme(theme: GrytTheme): GrytTheme {\n return {\n ...(theme.name === undefined ? {} : { name: theme.name }),\n hue: { ...theme.hue },\n lightHue: theme.lightHue === null ? null : { ...theme.lightHue },\n dark: { ...theme.dark },\n light: { ...theme.light },\n radius: { ...theme.radius }\n };\n}\n\n/** Which hues this appearance reads. */\nexport function grytThemeHues(\n theme: GrytTheme,\n appearance: GrytAppearance\n): GrytHues {\n return appearance === \"light\" && theme.lightHue !== null\n ? theme.lightHue\n : theme.hue;\n}\n\n/**\n * One appearance of a theme, in the shape createGrytTheme takes.\n *\n * The name does not come along: createGrytTheme returns CSS variables, and a\n * name is not one.\n */\nexport function grytThemeToOptions(\n theme: GrytTheme,\n appearance: GrytAppearance\n): GrytThemeOptions {\n return {\n appearance,\n color: { ...grytThemeHues(theme, appearance), ...theme[appearance] },\n radius: { ...theme.radius }\n };\n}\n\n/* ── the link ─────────────────────────────────────────────────────────── */\n\nconst HUE_PARAM: Record<GrytHueKey, string> = {\n accent: \"accent\",\n accentLight: \"accent-light\",\n secondary: \"secondary\",\n secondaryLight: \"secondary-light\",\n success: \"success\",\n danger: \"danger\",\n dangerLight: \"danger-light\",\n warning: \"warning\",\n onAccent: \"on-accent\",\n onSecondary: \"on-secondary\",\n onDanger: \"on-danger\"\n};\n\nconst NEUTRAL_PARAM: Record<GrytNeutralKey, string> = {\n bg: \"bg\",\n surface: \"surface\",\n surfaceRaised: \"raised\",\n surfaceHover: \"hover\",\n border: \"border\",\n muted: \"muted\",\n text: \"text\"\n};\n\nconst HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;\n\nexport function isHexColor(value: string): boolean {\n return HEX.test(value.trim());\n}\n\n/** #abc to #aabbcc, lower case, so two of the same colour compare equal. */\nexport function normalizeHexColor(value: string): string {\n const hex = value.trim().toLowerCase();\n return hex.length === 4\n ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`\n : hex;\n}\n\n/**\n * The theme as query parameters, carrying only what differs from Gryt's own.\n *\n * `appearance` is which half the sender was looking at, and it rides along\n * because a shared link that opens on the other one is showing something the\n * sender never saw.\n */\nexport function encodeGrytTheme(\n theme: GrytTheme,\n appearance?: GrytAppearance\n): URLSearchParams {\n const params = new URLSearchParams();\n const bare = (hex: string) => normalizeHexColor(hex).slice(1);\n\n const name = normalizeThemeName(theme.name ?? \"\");\n if (name !== \"\") params.set(\"name\", name);\n\n for (const key of GRYT_HUE_KEYS) {\n if (theme.hue[key] !== grytTheme.hue[key]) {\n params.set(HUE_PARAM[key], bare(theme.hue[key]));\n }\n }\n // A split light set is carried whole rather than diffed. It is only there\n // when somebody meant it, and diffing it against the dark hues would drop\n // exactly the values that make it a split.\n if (theme.lightHue !== null) {\n for (const key of GRYT_HUE_KEYS) {\n params.set(`lh-${HUE_PARAM[key]}`, bare(theme.lightHue[key]));\n }\n }\n for (const half of [\"dark\", \"light\"] as const) {\n const prefix = half === \"dark\" ? \"d\" : \"l\";\n for (const key of GRYT_NEUTRAL_KEYS) {\n if (theme[half][key] !== grytTheme[half][key]) {\n params.set(`${prefix}-${NEUTRAL_PARAM[key]}`, bare(theme[half][key]));\n }\n }\n }\n for (const key of GRYT_RADIUS_KEYS) {\n if (theme.radius[key] !== grytTheme.radius[key]) {\n params.set(`r-${key}`, String(theme.radius[key]));\n }\n }\n if (appearance === \"light\") params.set(\"mode\", \"light\");\n\n return params;\n}\n\nexport interface DecodedGrytTheme {\n theme: GrytTheme;\n /** Which half the link was sent from. Dark unless it says otherwise. */\n appearance: GrytAppearance;\n}\n\n/**\n * Whatever somebody pasted.\n *\n * A whole URL, a bare query string, or the JSON form — one function, because\n * from the outside they are the same act. Null when there is no theme in it at\n * all; a value it cannot parse is left at Gryt's, so one mistyped colour does\n * not throw the rest away.\n */\nexport function decodeGrytTheme(input: string): DecodedGrytTheme | null {\n const text = input.trim();\n if (text === \"\") return null;\n if (text.startsWith(\"{\")) return decodeJson(text);\n\n const query = text.includes(\"?\") ? text.slice(text.indexOf(\"?\") + 1) : text;\n return decodeParams(new URLSearchParams(query));\n}\n\nfunction decodeParams(params: URLSearchParams): DecodedGrytTheme | null {\n const theme = cloneGrytTheme(grytTheme);\n let present = false;\n\n const read = (name: string): string | null => {\n const raw = params.get(name);\n if (raw === null) return null;\n const hex = raw.startsWith(\"#\") ? raw : `#${raw}`;\n if (!isHexColor(hex)) return null;\n present = true;\n return normalizeHexColor(hex);\n };\n\n const name = normalizeThemeName(params.get(\"name\") ?? \"\");\n if (name !== \"\") {\n theme.name = name;\n present = true;\n }\n\n for (const key of GRYT_HUE_KEYS) {\n const value = read(HUE_PARAM[key]);\n if (value !== null) theme.hue[key] = value;\n }\n if (params.has(`lh-${HUE_PARAM.accent}`)) {\n const light = { ...theme.hue };\n for (const key of GRYT_HUE_KEYS) {\n const value = read(`lh-${HUE_PARAM[key]}`);\n if (value !== null) light[key] = value;\n }\n theme.lightHue = light;\n }\n for (const half of [\"dark\", \"light\"] as const) {\n const prefix = half === \"dark\" ? \"d\" : \"l\";\n for (const key of GRYT_NEUTRAL_KEYS) {\n const value = read(`${prefix}-${NEUTRAL_PARAM[key]}`);\n if (value !== null) theme[half][key] = value;\n }\n }\n for (const key of GRYT_RADIUS_KEYS) {\n const value = Number(params.get(`r-${key}`));\n // Anything outside this is a typo or somebody having a laugh, and a\n // 40000px radius makes an app look broken rather than themed.\n if (Number.isFinite(value) && value >= 0 && value <= 999 && params.has(`r-${key}`)) {\n theme.radius[key] = Math.round(value);\n present = true;\n }\n }\n\n if (!present) return null;\n return {\n theme,\n appearance: params.get(\"mode\") === \"light\" ? \"light\" : \"dark\"\n };\n}\n\nfunction decodeJson(text: string): DecodedGrytTheme | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n if (typeof parsed !== \"object\" || parsed === null) return null;\n const source = parsed as Record<string, unknown>;\n\n const theme = cloneGrytTheme(grytTheme);\n let present = false;\n\n const colors = (value: unknown, target: Record<string, string>) => {\n if (typeof value !== \"object\" || value === null) return;\n for (const [key, raw] of Object.entries(value as Record<string, unknown>)) {\n if (typeof raw === \"string\" && isHexColor(raw) && key in target) {\n target[key] = normalizeHexColor(raw);\n present = true;\n }\n }\n };\n\n if (typeof source.name === \"string\") {\n const named = normalizeThemeName(source.name);\n if (named !== \"\") {\n theme.name = named;\n present = true;\n }\n }\n\n colors(source.hue, theme.hue);\n colors(source.dark, theme.dark);\n colors(source.light, theme.light);\n\n if (typeof source.lightHue === \"object\" && source.lightHue !== null) {\n const light = { ...theme.hue };\n colors(source.lightHue, light);\n theme.lightHue = light;\n }\n\n if (typeof source.radius === \"object\" && source.radius !== null) {\n for (const [key, raw] of Object.entries(\n source.radius as Record<string, unknown>\n )) {\n const value = Number(raw);\n if (\n (GRYT_RADIUS_KEYS as readonly string[]).includes(key) &&\n Number.isFinite(value) &&\n value >= 0 &&\n value <= 999\n ) {\n theme.radius[key as GrytRadiusKey] = Math.round(value);\n present = true;\n }\n }\n }\n\n if (!present) return null;\n return { theme, appearance: \"dark\" };\n}\n","/* Themes to start from.\n *\n * Two kinds. The Gryt ones show the range — warm, near-monochrome,\n * high-contrast, and the palette the library ships. The ported ones are\n * well-known palettes, because \"can it look like the thing I already use?\" is\n * the question people arrive with, and a paragraph claiming yes is worth less\n * than a click.\n *\n * Every ported value is the published one, taken from the source named in the\n * comment above each preset rather than from memory. Where a palette defines\n * both a dark and a light variant — Alucard, Latte, Snow Storm, GitHub Light,\n * Solarized Light — both are here, which is why lightHue exists: Catppuccin's\n * mauve and GitHub's blue are genuinely different colours in each half, and\n * sharing one would make the preset wrong in the other.\n *\n * Two honest limits, and the page says both:\n *\n * - Gryt names seven neutral anchors. Most palettes name fewer, so the steps\n * in between are derived — marked `derived` where that happens. Nothing\n * derived is invented out of nowhere; it sits between two published values.\n * - A palette is a set of names with colours behind them, and mapping those\n * names onto \"page, surface, border, muted, text\" is a judgement. Somebody\n * else mapping the same palette would put a couple of them elsewhere.\n *\n * Radius is part of a preset too. GitHub's buttons are not pills and\n * Solarized's are square; a preset that got the colours right and left\n * everything fully rounded would not look like the thing it names.\n *\n * Names belong to their projects. Dracula, Nord, Catppuccin, Solarized and\n * shadcn/ui are MIT-licensed; the rest are referenced by name only.\n *\n * These ship with the library rather than with the docs site, because the docs\n * site is not the only thing that lists them: the client offers the same set,\n * and it should get a new one by taking a newer @gryt/ui rather than by\n * somebody copying eleven palettes across by hand.\n */\n\nimport type { GrytRadiusKey, GrytTheme } from \"./theme\";\nimport { grytTheme } from \"./theme\";\n\nexport interface GrytThemePreset {\n id: string;\n name: string;\n /** One line under the name: what makes this one different. */\n note: string;\n group: \"Gryt\" | \"Ported\";\n /** Where the values came from. Shown as the attribution line. */\n source?: string;\n theme: GrytTheme;\n}\n\ntype Radius = Record<GrytRadiusKey, number>;\n\nconst ROUND: Radius = { sm: 8, md: 12, lg: 20, xl: 28, full: 999 };\nconst SOFT: Radius = { sm: 6, md: 8, lg: 14, xl: 18, full: 999 };\n/** Buttons that are not pills. `full` is what controls use, so it does the work. */\nconst CRISP: Radius = { sm: 4, md: 6, lg: 10, xl: 14, full: 6 };\nconst SHADCN: Radius = { sm: 6, md: 8, lg: 10, xl: 14, full: 10 };\nconst SQUARE: Radius = { sm: 2, md: 4, lg: 6, xl: 8, full: 4 };\n\nexport const grytPresets: GrytThemePreset[] = [\n {\n id: \"gryt\",\n name: \"Gryt\",\n note: \"What the library ships, from the Gryt code-theme.\",\n group: \"Gryt\",\n source: \"github.com/Gryt-chat/code-theme\",\n theme: grytTheme\n },\n {\n id: \"ember\",\n name: \"Ember\",\n note: \"Warm all the way down — the neutrals are brown, not blue.\",\n group: \"Gryt\",\n theme: {\n name: \"Ember\",\n hue: {\n accent: \"#f0803c\",\n accentLight: \"#ff9f66\",\n secondary: \"#d9a441\",\n secondaryLight: \"#ecc06a\",\n success: \"#8bb056\",\n danger: \"#e35d55\",\n dangerLight: \"#ef8079\",\n warning: \"#e8b33e\",\n onAccent: \"#231004\",\n onSecondary: \"#241a04\",\n onDanger: \"#2b0a08\"\n },\n lightHue: null,\n dark: {\n bg: \"#17110e\",\n surface: \"#1f1815\",\n surfaceRaised: \"#251d19\",\n surfaceHover: \"#33261f\",\n border: \"#352822\",\n muted: \"#a48f81\",\n text: \"#f5ece5\"\n },\n light: {\n bg: \"#f6efe8\",\n surface: \"#fffdfb\",\n surfaceRaised: \"#faf3ec\",\n surfaceHover: \"#efe3d8\",\n border: \"#e0d2c4\",\n muted: \"#6b5b50\",\n text: \"#241a14\"\n },\n radius: ROUND\n }\n },\n {\n id: \"paper\",\n name: \"Paper\",\n note: \"Near-monochrome. One quiet slate accent and nothing else.\",\n group: \"Gryt\",\n theme: {\n name: \"Paper\",\n hue: {\n accent: \"#8390a8\",\n accentLight: \"#a3aec2\",\n secondary: \"#93a0a0\",\n secondaryLight: \"#b1bcbc\",\n success: \"#7f9b7f\",\n danger: \"#b56b6b\",\n dangerLight: \"#c98d8d\",\n warning: \"#b39a6a\",\n onAccent: \"#11151c\",\n onSecondary: \"#121717\",\n onDanger: \"#1d0e0e\"\n },\n lightHue: null,\n dark: {\n bg: \"#101011\",\n surface: \"#17171a\",\n surfaceRaised: \"#1d1d20\",\n surfaceHover: \"#282a2e\",\n border: \"#2a2a2e\",\n muted: \"#8e8e94\",\n text: \"#ededf0\"\n },\n light: {\n bg: \"#f0f0f2\",\n surface: \"#ffffff\",\n surfaceRaised: \"#f7f7f9\",\n surfaceHover: \"#e6e6ea\",\n border: \"#d6d6dc\",\n muted: \"#5b5b63\",\n text: \"#17171a\"\n },\n radius: SOFT\n }\n },\n {\n id: \"signal\",\n name: \"Signal\",\n note: \"Black, white, and a yellow that cannot be missed.\",\n group: \"Gryt\",\n theme: {\n name: \"Signal\",\n hue: {\n accent: \"#ffd400\",\n accentLight: \"#ffe454\",\n secondary: \"#00d0ff\",\n secondaryLight: \"#66e2ff\",\n success: \"#00e06a\",\n danger: \"#ff453a\",\n dangerLight: \"#ff7a72\",\n warning: \"#ffab00\",\n onAccent: \"#161200\",\n onSecondary: \"#001a20\",\n onDanger: \"#1a0300\"\n },\n lightHue: null,\n dark: {\n bg: \"#000000\",\n surface: \"#0c0c0c\",\n surfaceRaised: \"#151515\",\n surfaceHover: \"#242424\",\n border: \"#454545\",\n muted: \"#bcbcbc\",\n text: \"#ffffff\"\n },\n light: {\n bg: \"#f0f0f0\",\n surface: \"#ffffff\",\n surfaceRaised: \"#f8f8f8\",\n surfaceHover: \"#e3e3e3\",\n border: \"#6f6f6f\",\n muted: \"#3d3d3d\",\n text: \"#000000\"\n },\n radius: SQUARE\n }\n },\n {\n /* Dracula's eleven, and Alucard's eleven for the light half, from the\n palette tables in dracula/dracula-theme. Background, Current Line,\n Foreground and Comment are exact; the two steps between Background and\n Current Line are derived, because Dracula does not name them. */\n id: \"dracula\",\n name: \"Dracula\",\n note: \"The purple-and-pink dark theme, with Alucard as its light half.\",\n group: \"Ported\",\n source: \"draculatheme.com, MIT\",\n theme: {\n name: \"Dracula\",\n hue: {\n accent: \"#bd93f9\",\n accentLight: \"#d0b3fb\",\n secondary: \"#8be9fd\",\n secondaryLight: \"#aff0fe\",\n success: \"#50fa7b\",\n danger: \"#ff5555\",\n dangerLight: \"#ff7979\",\n warning: \"#ffb86c\",\n onAccent: \"#282a36\",\n onSecondary: \"#282a36\",\n onDanger: \"#282a36\"\n },\n lightHue: {\n accent: \"#644ac9\",\n accentLight: \"#7b64d6\",\n secondary: \"#036a96\",\n secondaryLight: \"#0b83b5\",\n success: \"#14710a\",\n danger: \"#cb3a2a\",\n dangerLight: \"#d95445\",\n warning: \"#a34d14\",\n onAccent: \"#fffbeb\",\n onSecondary: \"#fffbeb\",\n onDanger: \"#fffbeb\"\n },\n dark: {\n bg: \"#282a36\",\n surface: \"#31323f\",\n surfaceRaised: \"#383a49\",\n surfaceHover: \"#44475a\",\n border: \"#44475a\",\n muted: \"#6272a4\",\n text: \"#f8f8f2\"\n },\n light: {\n bg: \"#f5f1e1\",\n surface: \"#fffbeb\",\n surfaceRaised: \"#faf6e6\",\n surfaceHover: \"#ece7d4\",\n border: \"#dcd6bf\",\n muted: \"#6c664b\",\n text: \"#1f1f1f\"\n },\n radius: SOFT\n }\n },\n {\n /* nord0-nord15, exactly as nordtheme.com publishes them. Polar Night is\n the dark neutrals, Snow Storm the light ones, Frost the accents and\n Aurora the status colours. Nothing here is derived. */\n id: \"nord\",\n name: \"Nord\",\n note: \"Polar Night and Snow Storm, with Frost on top.\",\n group: \"Ported\",\n source: \"nordtheme.com, MIT\",\n theme: {\n name: \"Nord\",\n hue: {\n accent: \"#88c0d0\",\n accentLight: \"#8fbcbb\",\n secondary: \"#81a1c1\",\n secondaryLight: \"#a3b8d4\",\n success: \"#a3be8c\",\n danger: \"#bf616a\",\n dangerLight: \"#d08770\",\n warning: \"#ebcb8b\",\n onAccent: \"#2e3440\",\n onSecondary: \"#2e3440\",\n onDanger: \"#eceff4\"\n },\n lightHue: {\n accent: \"#5e81ac\",\n accentLight: \"#81a1c1\",\n secondary: \"#8fbcbb\",\n secondaryLight: \"#88c0d0\",\n success: \"#a3be8c\",\n danger: \"#bf616a\",\n dangerLight: \"#d08770\",\n warning: \"#ebcb8b\",\n onAccent: \"#eceff4\",\n onSecondary: \"#2e3440\",\n onDanger: \"#eceff4\"\n },\n dark: {\n bg: \"#2e3440\",\n surface: \"#3b4252\",\n surfaceRaised: \"#434c5e\",\n surfaceHover: \"#4c566a\",\n border: \"#4c566a\",\n muted: \"#d8dee9\",\n text: \"#eceff4\"\n },\n light: {\n bg: \"#e5e9f0\",\n surface: \"#eceff4\",\n surfaceRaised: \"#e9edf2\",\n surfaceHover: \"#d8dee9\",\n border: \"#c9d1de\",\n muted: \"#4c566a\",\n text: \"#2e3440\"\n },\n radius: SOFT\n }\n },\n {\n /* Mocha and Latte from catppuccin/palette's palette.json. base, mantle,\n surface0/1/2, text and subtext0 are exact; the border step is derived\n from surface1 and surface2, which is where a border sits in their own\n ports. */\n id: \"catppuccin\",\n name: \"Catppuccin\",\n note: \"Mocha for dark, Latte for light. Mauve does the accent work.\",\n group: \"Ported\",\n source: \"catppuccin/palette, MIT\",\n theme: {\n name: \"Catppuccin\",\n hue: {\n accent: \"#cba6f7\",\n accentLight: \"#dcc0fa\",\n secondary: \"#89b4fa\",\n secondaryLight: \"#a8c8fb\",\n success: \"#a6e3a1\",\n danger: \"#f38ba8\",\n dangerLight: \"#eba0ac\",\n warning: \"#f9e2af\",\n onAccent: \"#1e1e2e\",\n onSecondary: \"#1e1e2e\",\n onDanger: \"#1e1e2e\"\n },\n lightHue: {\n accent: \"#8839ef\",\n accentLight: \"#9a55f2\",\n secondary: \"#1e66f5\",\n secondaryLight: \"#4680f7\",\n success: \"#40a02b\",\n danger: \"#d20f39\",\n dangerLight: \"#e64553\",\n warning: \"#df8e1d\",\n onAccent: \"#eff1f5\",\n onSecondary: \"#eff1f5\",\n onDanger: \"#eff1f5\"\n },\n dark: {\n bg: \"#1e1e2e\",\n surface: \"#313244\",\n surfaceRaised: \"#45475a\",\n surfaceHover: \"#585b70\",\n border: \"#45475a\",\n muted: \"#a6adc8\",\n text: \"#cdd6f4\"\n },\n light: {\n bg: \"#e6e9ef\",\n surface: \"#eff1f5\",\n surfaceRaised: \"#eaedf3\",\n surfaceHover: \"#dce0e8\",\n border: \"#ccd0da\",\n muted: \"#6c6f85\",\n text: \"#4c4f69\"\n },\n radius: ROUND\n }\n },\n {\n /* Primer's functional tokens, from @primer/primitives' compiled themes:\n bgColor-default, bgColor-muted, borderColor-default, fgColor-default,\n fgColor-muted, and the -emphasis fills for accent, danger, success,\n attention and done. The raised and hover steps are derived — Primer\n expresses those as translucent overlays rather than as solid colours. */\n id: \"github\",\n name: \"GitHub\",\n note: \"Primer's own tokens, six-pixel corners included.\",\n group: \"Ported\",\n source: \"@primer/primitives\",\n theme: {\n name: \"GitHub\",\n hue: {\n accent: \"#1f6feb\",\n accentLight: \"#4493f8\",\n secondary: \"#8957e5\",\n secondaryLight: \"#a371f7\",\n success: \"#238636\",\n danger: \"#da3633\",\n dangerLight: \"#f85149\",\n warning: \"#9e6a03\",\n onAccent: \"#ffffff\",\n onSecondary: \"#ffffff\",\n onDanger: \"#ffffff\"\n },\n lightHue: {\n accent: \"#0969da\",\n accentLight: \"#218bff\",\n secondary: \"#8250df\",\n secondaryLight: \"#a475f9\",\n success: \"#1f883d\",\n danger: \"#cf222e\",\n dangerLight: \"#d1242f\",\n warning: \"#9a6700\",\n onAccent: \"#ffffff\",\n onSecondary: \"#ffffff\",\n onDanger: \"#ffffff\"\n },\n dark: {\n bg: \"#0d1117\",\n surface: \"#151b23\",\n surfaceRaised: \"#1c222b\",\n surfaceHover: \"#262c36\",\n border: \"#3d444d\",\n muted: \"#9198a1\",\n text: \"#f0f6fc\"\n },\n light: {\n bg: \"#f6f8fa\",\n surface: \"#ffffff\",\n surfaceRaised: \"#fbfcfd\",\n surfaceHover: \"#eef1f4\",\n border: \"#d1d9e0\",\n muted: \"#59636e\",\n text: \"#1f2328\"\n },\n radius: CRISP\n }\n },\n {\n /* Read off anthropic.com's own stylesheet: the clay #d97757, the cream\n #f0eee6 and #faf9f5, the ink #141413, and the neutrals #3d3d3a,\n #87867f, #b0aea5, #c6c4ba, #e8e6dc. Anthropic publishes no token file,\n so the status hues have no published counterpart and are Gryt's own —\n this is the one preset that is a likeness rather than a port. */\n id: \"claude\",\n name: \"Claude\",\n note: \"Anthropic's clay orange on cream and near-black.\",\n group: \"Ported\",\n source: \"anthropic.com — a likeness, not a published palette\",\n theme: {\n name: \"Claude\",\n hue: {\n accent: \"#d97757\",\n accentLight: \"#e59275\",\n secondary: \"#7d9ec4\",\n secondaryLight: \"#9db8d6\",\n success: \"#6ba368\",\n danger: \"#bf4d43\",\n dangerLight: \"#d4726a\",\n warning: \"#d9a441\",\n onAccent: \"#241009\",\n onSecondary: \"#0c1720\",\n onDanger: \"#faf9f5\"\n },\n lightHue: null,\n dark: {\n bg: \"#141413\",\n surface: \"#1f1e1d\",\n surfaceRaised: \"#262624\",\n surfaceHover: \"#3d3d3a\",\n border: \"#3d3d3a\",\n muted: \"#b0aea5\",\n text: \"#faf9f5\"\n },\n light: {\n bg: \"#f0eee6\",\n surface: \"#faf9f5\",\n surfaceRaised: \"#f5f3ec\",\n surfaceHover: \"#e8e6dc\",\n border: \"#d5d2c5\",\n muted: \"#87867f\",\n text: \"#141413\"\n },\n radius: ROUND\n }\n },\n {\n /* The zinc theme from shadcn-ui/ui's registry, converted from its OKLCH\n values. One deliberate departure: shadcn's primary is monochrome —\n near-white in dark, near-black in light — which cannot be a Gryt accent,\n because the accent is also the colour every link and focus ring is drawn\n from. Its destructive red is the accent here, and the neutrals are the\n theme's own. */\n id: \"shadcn\",\n name: \"shadcn/ui\",\n note: \"Zinc neutrals and a ten-pixel radius. No pills anywhere.\",\n group: \"Ported\",\n source: \"ui.shadcn.com, MIT — accent adapted\",\n theme: {\n name: \"shadcn/ui\",\n hue: {\n accent: \"#a1a1aa\",\n accentLight: \"#d4d4d8\",\n secondary: \"#71717a\",\n secondaryLight: \"#a1a1aa\",\n success: \"#4ade80\",\n danger: \"#e7000b\",\n dangerLight: \"#fb2c36\",\n warning: \"#fd9a00\",\n onAccent: \"#18181b\",\n onSecondary: \"#fafafa\",\n onDanger: \"#fafafa\"\n },\n lightHue: {\n accent: \"#3f3f46\",\n accentLight: \"#52525b\",\n secondary: \"#71717a\",\n secondaryLight: \"#a1a1aa\",\n success: \"#00a63e\",\n danger: \"#e7000b\",\n dangerLight: \"#fb2c36\",\n warning: \"#e17100\",\n onAccent: \"#fafafa\",\n onSecondary: \"#fafafa\",\n onDanger: \"#fafafa\"\n },\n dark: {\n bg: \"#18181b\",\n surface: \"#27272a\",\n surfaceRaised: \"#3f3f46\",\n surfaceHover: \"#3f3f46\",\n border: \"#3f3f46\",\n muted: \"#a1a1aa\",\n text: \"#fafafa\"\n },\n light: {\n bg: \"#f4f4f5\",\n surface: \"#ffffff\",\n surfaceRaised: \"#fafafa\",\n surfaceHover: \"#e4e4e7\",\n border: \"#e4e4e7\",\n muted: \"#71717a\",\n text: \"#18181b\"\n },\n radius: SHADCN\n }\n },\n {\n /* Ethan Schoonover's sixteen, exactly. base03 and base02 are the dark\n page and surface, base2 and base3 the light ones, and the accent hues\n are shared between the two halves — which is the whole point of\n Solarized. The steps between base03 and base02 are derived. */\n id: \"solarized\",\n name: \"Solarized\",\n note: \"Both halves on one set of accents, as designed.\",\n group: \"Ported\",\n source: \"ethanschoonover.com/solarized, MIT\",\n theme: {\n name: \"Solarized\",\n hue: {\n accent: \"#268bd2\",\n accentLight: \"#4ba3e3\",\n secondary: \"#2aa198\",\n secondaryLight: \"#43bbb1\",\n success: \"#859900\",\n danger: \"#dc322f\",\n dangerLight: \"#cb4b16\",\n warning: \"#b58900\",\n onAccent: \"#fdf6e3\",\n onSecondary: \"#002b36\",\n onDanger: \"#fdf6e3\"\n },\n lightHue: null,\n dark: {\n bg: \"#002b36\",\n surface: \"#073642\",\n surfaceRaised: \"#0b414f\",\n surfaceHover: \"#134b5a\",\n border: \"#0f4757\",\n muted: \"#93a1a1\",\n text: \"#eee8d5\"\n },\n light: {\n bg: \"#eee8d5\",\n surface: \"#fdf6e3\",\n surfaceRaised: \"#f7f0dc\",\n surfaceHover: \"#e4dcc4\",\n border: \"#d9d0b4\",\n muted: \"#586e75\",\n text: \"#073642\"\n },\n radius: SQUARE\n }\n }\n];\n\nexport const grytPresetsById = new Map(\n grytPresets.map((preset) => [preset.id, preset])\n);\n","/* The motion system, as numbers.\n *\n * These lived only in `theme.css` as `linear()` sample lists, which meant the\n * React Native port had to hand-copy 54 numbers and hope they stayed in step.\n * They are arithmetic with no renderer attached, so they belong here with the\n * colour maths.\n *\n * The curves are a damped spring solved analytically and sampled, rather than\n * a physics engine's approximation of one. That distinction is load-bearing:\n * anything reproducing this on another platform should interpolate these\n * samples, not reach for a spring simulator and tune constants until it looks\n * close. `theme.css` emits them into `linear()`; React Native interpolates\n * them as a timing easing. Same curve, same duration, same motion.\n */\n\n/**\n * A damped spring at ζ = 0.5591 — peaks 12% past the target and settles\n * without a second visible swing.\n *\n * Duration-invariant: the natural frequency scales with the duration, so one\n * curve serves every tier and only the duration changes.\n *\n * **For things that scale.** Overshoot is a percentage of the *travel*, so on\n * a control that grows in place it is texture you feel rather than see. On\n * something that travels the width of its container it throws the element\n * outside its own bounds — use {@link springTight} there.\n */\nexport const springSamples: readonly number[] = [\n 0, 0.1217, 0.3812, 0.6579, 0.883, 1.0304, 1.1034, 1.12, 1.1025, 1.0705,\n 1.0376, 1.0115, 0.9949, 0.987, 0.9857, 0.9881, 0.992, 0.9959, 0.9989, 1.0008,\n 1.0016, 1.0017, 1.0014, 1.0009, 1.0004, 1.0001, 1\n];\n\n/**\n * The same spring critically damped at ζ = 1 — settles at the target without\n * ever passing it.\n *\n * **For things that travel inside bounds.** Measured on a slider: a full-track\n * jump on {@link springSamples} put the thumb 110% along a 919px track, 96px\n * outside the control it belongs to, before coming back.\n */\nexport const springTightSamples: readonly number[] = [\n 0, 0.0496, 0.1585, 0.2869, 0.4135, 0.5279, 0.6263, 0.7079, 0.7741, 0.8268,\n 0.8681, 0.9002, 0.9249, 0.9437, 0.958, 0.9688, 0.9768, 0.9829, 0.9874,\n 0.9907, 0.9932, 0.995, 0.9963, 0.9973, 0.9981, 0.9986, 1\n];\n\n/**\n * Durations, in milliseconds.\n *\n * Each spring curve is shaped for one length. Changing a duration without\n * changing the curve moves where the overshoot lands.\n */\nexport const grytDurations = {\n /** Most interactions. */\n spring: 500,\n /** Drawer, where the travel is the width of a panel. */\n springSoft: 700,\n /** Colour changes, which should not feel sprung. */\n fast: 150\n} as const;\n\n/**\n * How far interactive controls scale.\n *\n * `hover` has no equivalent on a touch screen and is here for the web only;\n * a native port should implement `press` and leave `hover` alone rather than\n * inventing a substitute.\n */\nexport const grytScaleSteps = {\n button: { hover: 1.03, press: 0.96 },\n toast: { hover: 1.04, press: 0.96 },\n sliderThumb: { hover: 1.12, press: 0.94 }\n} as const;\n\n/**\n * Sample a curve at `t` in 0..1, interpolating linearly between points.\n *\n * This is what `linear()` does in CSS, written out so other renderers can do\n * the same thing rather than approximating the curve some other way.\n */\nexport function sampleCurve(samples: readonly number[], t: number): number {\n if (samples.length === 0) return t;\n if (t <= 0) return samples[0]!;\n if (t >= 1) return samples[samples.length - 1]!;\n\n const span = (samples.length - 1) * t;\n const index = Math.floor(span);\n const rest = span - index;\n const from = samples[index]!;\n const to = samples[index + 1] ?? from;\n\n return from + (to - from) * rest;\n}\n"],"names":["srgbToLinear","c","linearToSrgb","clamp01","value","hexToRgb","hex","h","full","rgbToHex","g","b","part","hexToOklch","r0","g0","b0","l","m","s","L","a","oklchToHex","l3","m3","s3","HUE_L","HUE_C","hueScale","solid","solidHover","steps","i","l10","l11","l12","NEUTRAL_L","NEUTRAL_C","neutralScale","anchors","fixed","hue","alphaScale","scale","background","bg","target","alpha","t","overlay","r","LIGHT_NEUTRAL_L","LIGHT_NEUTRAL_C","LIGHT_HUE_L","LIGHT_HUE_C","neutralScaleLight","hueScaleLight","sl","luminance","contrast","la","lb","grytTokens","grytLightTokens","grytScales","grytScalesLight","grytLightSurfaceHover","grytAlphaScales","grytAlphaScalesLight","createGrytTheme","options","light","color","radius","scales","scaleVars","name","index","GRYT_HUE_KEYS","GRYT_NEUTRAL_KEYS","GRYT_RADIUS_KEYS","GRYT_THEME_NAME_MAX","normalizeThemeName","grytTheme","cloneGrytTheme","theme","grytThemeHues","appearance","grytThemeToOptions","HUE_PARAM","NEUTRAL_PARAM","HEX","isHexColor","normalizeHexColor","encodeGrytTheme","params","bare","key","half","prefix","decodeGrytTheme","input","text","decodeJson","query","decodeParams","present","read","raw","parsed","source","colors","named","ROUND","SOFT","CRISP","SHADCN","SQUARE","grytPresets","grytPresetsById","preset","springSamples","springTightSamples","grytDurations","grytScaleSteps","sampleCurve","samples","span","rest","from","to"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -24,4 +24,5 @@ export { grytPresets, grytPresetsById } from './presets.js';
|
|
|
24
24
|
export type { GrytThemePreset } from './presets.js';
|
|
25
25
|
export { GRYT_HUE_KEYS, GRYT_NEUTRAL_KEYS, GRYT_RADIUS_KEYS, GRYT_THEME_NAME_MAX, cloneGrytTheme, decodeGrytTheme, encodeGrytTheme, grytTheme, grytThemeHues, grytThemeToOptions, isHexColor, normalizeHexColor, normalizeThemeName } from './theme.js';
|
|
26
26
|
export type { DecodedGrytTheme, GrytAppearance, GrytHueKey, GrytHues, GrytNeutralKey, GrytNeutrals, GrytRadiusKey, GrytTheme } from './theme.js';
|
|
27
|
+
export { grytDurations, grytScaleSteps, sampleCurve, springSamples, springTightSamples } from './motion.js';
|
|
27
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -24,4 +24,5 @@ export { grytPresets, grytPresetsById } from './presets.js';
|
|
|
24
24
|
export type { GrytThemePreset } from './presets.js';
|
|
25
25
|
export { GRYT_HUE_KEYS, GRYT_NEUTRAL_KEYS, GRYT_RADIUS_KEYS, GRYT_THEME_NAME_MAX, cloneGrytTheme, decodeGrytTheme, encodeGrytTheme, grytTheme, grytThemeHues, grytThemeToOptions, isHexColor, normalizeHexColor, normalizeThemeName } from './theme.js';
|
|
26
26
|
export type { DecodedGrytTheme, GrytAppearance, GrytHueKey, GrytHues, GrytNeutralKey, GrytNeutrals, GrytRadiusKey, GrytTheme } from './theme.js';
|
|
27
|
+
export { grytDurations, grytScaleSteps, sampleCurve, springSamples, springTightSamples } from './motion.js';
|
|
27
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,UAAU,EACV,eAAe,EACf,UAAU,EACX,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAM3D,OAAO,EACL,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,eAAe,EACf,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,EACV,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,UAAU,EACV,eAAe,EACf,UAAU,EACX,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAM3D,OAAO,EACL,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,eAAe,EACf,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,SAAS,EACV,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,kBAAkB,EACnB,MAAM,UAAU,CAAC"}
|