agent-design-skills 1.1.1 → 1.1.2
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.js +78 -70
- package/package.json +1 -1
- package/registry/core/02-anti-slop-firewall.md +12 -0
- package/registry/core/03-cross-page-unity.md +7 -0
- package/registry/core/04-ux-and-ergonomics.md +11 -5
- package/registry/starter-kits/data-tool/template.html +5 -5
- package/registry/starter-kits/landing-waitlist/template.html +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as
|
|
2
|
+
import{Command as lt}from"commander";import*as w from"@clack/prompts";import k from"picocolors";import F from"pathe";import q from"fs-extra";import D from"fs-extra";import I from"pathe";import{fileURLToPath as ze}from"url";import N from"fs-extra";import te from"pathe";function Ie(e){let t=0;for(let s=0;s<e.length;s++)t=(t<<5)-t+e.charCodeAt(s),t|=0;return Math.abs(t)%7-3}function ae(e,t,s){return t==="dark"?Math.max(s==="primary"?.97:s==="secondary"?.8:.68,e):Math.min(s==="primary"?.15:s==="secondary"?.34:.44,e)}var _={"dark-obsidian-technical":{A:{display:"Geist",sans:"Instrument Sans",mono:"Geist Mono"},B:{display:"Sora",sans:"Public Sans",mono:"Fira Code"},C:{display:"Satoshi",sans:"General Sans",mono:"Space Mono"}},"swiss-typographic-grid":{A:{display:"Cabinet Grotesk",sans:"Space Grotesk",mono:"Space Mono"},B:{display:"Syne",sans:"Public Sans",mono:"Fragment Mono"},C:{display:"Sora",sans:"General Sans",mono:"DM Mono"}},"kinetic-industrial-mono":{A:{display:"JetBrains Mono",sans:"IBM Plex Sans",mono:"JetBrains Mono"},B:{display:"Fira Code",sans:"Fragment Mono",mono:"Fira Code"},C:{display:"Space Mono",sans:"Chivo",mono:"Space Mono"}},"bento-modular-system":{A:{display:"Satoshi",sans:"General Sans",mono:"Geist Mono"},B:{display:"Sora",sans:"Public Sans",mono:"Fira Code"},C:{display:"Outfit",sans:"DM Sans",mono:"JetBrains Mono"}},"spatial-glass-visionos":{A:{display:"Outfit",sans:"DM Sans",mono:"Fragment Mono"},B:{display:"Sora",sans:"Public Sans",mono:"Geist Mono"},C:{display:"Cabinet Grotesk",sans:"Switzer",mono:"Inconsolata"}},"editorial-serif-paper":{A:{display:"Newsreader",sans:"Work Sans",mono:"Fragment Mono"},B:{display:"Fraunces",sans:"Merriweather Sans",mono:"IBM Plex Mono"},C:{display:"Bespoke Serif",sans:"Switzer",mono:"Inconsolata"}},"quiet-luxury-atelier":{A:{display:"Cormorant Garamond",sans:"DM Sans",mono:"Fragment Mono"},B:{display:"Fraunces",sans:"Work Sans",mono:"IBM Plex Mono"},C:{display:"Bespoke Serif",sans:"Switzer",mono:"Space Mono"}},"warm-artisan-craft":{A:{display:"Fraunces",sans:"Cabinet Grotesk",mono:"DM Mono"},B:{display:"Source Serif 4",sans:"Public Sans",mono:"Fragment Mono"},C:{display:"Newsreader",sans:"General Sans",mono:"Space Mono"}},"japanese-minimal-zen":{A:{display:"Noto Serif Display",sans:"Work Sans",mono:"DM Mono"},B:{display:"Newsreader",sans:"Public Sans",mono:"Fragment Mono"},C:{display:"Bespoke Serif",sans:"Sora",mono:"JetBrains Mono"}},"scandinavian-warm-minimal":{A:{display:"Familjen Grotesk",sans:"DM Sans",mono:"Fragment Mono"},B:{display:"Sora",sans:"Public Sans",mono:"IBM Plex Mono"},C:{display:"Switzer",sans:"Work Sans",mono:"Space Mono"}},"neo-brutalism":{A:{display:"Space Grotesk",sans:"Syne",mono:"Space Mono"},B:{display:"Archivo Black",sans:"Archivo",mono:"DM Mono"},C:{display:"Clash Display",sans:"Cabinet Grotesk",mono:"Fragment Mono"}},"retro-tactile-analog":{A:{display:"Space Mono",sans:"Chivo",mono:"Space Mono"},B:{display:"Syne",sans:"Public Sans",mono:"Fira Code"},C:{display:"Archivo",sans:"DM Mono",mono:"DM Mono"}},"y2k-acid-cyber":{A:{display:"Syne",sans:"Chakra Petch",mono:"Space Mono"},B:{display:"Clash Display",sans:"Space Grotesk",mono:"Fira Code"},C:{display:"Cabinet Grotesk",sans:"Public Sans",mono:"JetBrains Mono"}},"playful-clay-consumer":{A:{display:"Bricolage Grotesque",sans:"Fredoka",mono:"Space Mono"},B:{display:"Outfit",sans:"DM Sans",mono:"Fragment Mono"},C:{display:"Cabinet Grotesk",sans:"Switzer",mono:"DM Mono"}},"vaporwave-crt-terminal":{A:{display:"VT323",sans:"Fira Code",mono:"Fira Code"},B:{display:"Chakra Petch",sans:"Space Mono",mono:"Space Mono"},C:{display:"Syne",sans:"DM Mono",mono:"DM Mono"}},"high-trust-fintech-clarity":{A:{display:"Sora",sans:"Public Sans",mono:"Fira Code"},B:{display:"General Sans",sans:"Instrument Sans",mono:"JetBrains Mono"},C:{display:"Cabinet Grotesk",sans:"Switzer",mono:"Space Mono"}},"clinical-biotech-precision":{A:{display:"Instrument Sans",sans:"Public Sans",mono:"IBM Plex Mono"},B:{display:"Sora",sans:"General Sans",mono:"Fragment Mono"},C:{display:"Cabinet Grotesk",sans:"Work Sans",mono:"Fira Code"}},"civic-govtech-accessible":{A:{display:"Atkinson Hyperlegible",sans:"Public Sans",mono:"Fragment Mono"},B:{display:"Sora",sans:"DM Sans",mono:"IBM Plex Mono"},C:{display:"Work Sans",sans:"General Sans",mono:"Fira Code"}}},ie={calm:{ease:"cubic-bezier(0.25, 1, 0.5, 1)",easeSpring:"cubic-bezier(0.25, 1, 0.5, 1)",durationFast:"140ms",durationNormal:"240ms"},"urgent-precise":{ease:"cubic-bezier(0.16, 1, 0.3, 1)",easeSpring:"cubic-bezier(0.16, 1, 0.3, 1)",durationFast:"110ms",durationNormal:"180ms"},"playful-tactile":{ease:"cubic-bezier(0.34, 1.56, 0.64, 1)",easeSpring:"cubic-bezier(0.22, 1.35, 0.36, 1)",durationFast:"120ms",durationNormal:"240ms"},authoritative:{ease:"cubic-bezier(0.2, 0, 0, 1)",easeSpring:"cubic-bezier(0.2, 0, 0, 1)",durationFast:"120ms",durationNormal:"200ms"}},$e={"instrument sans":"wght@400;500;600;700","space grotesk":"wght@400;500;600;700",sora:"wght@400;600",fraunces:"opsz,wght@9..144,400..700","cormorant garamond":"wght@500;600;700","jetbrains mono":"wght@400;500","fira code":"wght@400;500","ibm plex mono":"wght@400;500","ibm plex sans":"wght@400;500;600","space mono":"wght@400;700","public sans":"wght@400;500;600","dm sans":"wght@400;500;600","dm mono":"wght@400;500","work sans":"wght@400;500;600","atkinson hyperlegible":"wght@400;700","bricolage grotesque":"wght@400;600;700",syne:"wght@600;700","syne mono":"wght@400",vt323:"wght@400",newsreader:"ital,opsz,wght@0,6..72,400..700;1,6..72,400","noto serif display":"wght@400;600","familjen grotesk":"wght@400;600",geist:"wght@400;500;600;700","geist mono":"wght@400;500","chakra petch":"wght@400;600",fredoka:"wght@400;600","archivo black":"wght@400",archivo:"wght@400;600",chivo:"wght@400;600",inconsolata:"wght@400;600","merriweather sans":"wght@400;600","source serif 4":"opsz,wght@8..60,400..700"},oe={"cabinet grotesk":"cabinet-grotesk@500,700,800","general sans":"general-sans@400,500,600",satoshi:"satoshi@400,500,700",switzer:"switzer@400,500,600","bespoke serif":"bespoke-serif@400,600","clash display":"clash-display@500,600,700"};function T(e){if(!e)return"";let t=e.match(/["']([^"']+)["']/);return t?t[1]:e.split(",")[0].trim()}async function Z(e){let t=te.resolve(e,"tokens.css"),s=te.resolve(e,"tokens.json"),a=te.resolve(e,"package.json"),g,f,y,i;if(await N.pathExists(t)){let n=await N.readFile(t,"utf-8"),c=n.match(/--font-display:\s*([^;]+);/),d=n.match(/--font-sans:\s*([^;]+);/),m=n.match(/--font-mono:\s*([^;]+);/),p=n.match(/@import\s+url\(['"]?([^'")]+)['"]?\);/);if(c&&(g=c[1].trim()),d&&(f=d[1].trim()),m&&(y=m[1].trim()),p&&(i=p[1].trim()),g||f||y)return{display:g,sans:f,mono:y,importUrl:i,source:"preserved"}}if(await N.pathExists(s))try{let c=(await N.readJSON(s)).variables||{};if(c["--font-display"]||c["--font-sans"]||c["--font-mono"])return{display:c["--font-display"],sans:c["--font-sans"],mono:c["--font-mono"],source:"preserved"}}catch{}if(await N.pathExists(a))try{let n=await N.readJSON(a),c={...n.dependencies||{},...n.devDependencies||{}},d=Object.keys(c).filter(m=>m.startsWith("@fontsource/"));if(d.length>0){let m=d.map(p=>p.replace("@fontsource/","").split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" "));return{display:m[0],sans:m[1]||m[0],mono:m.find(p=>p.toLowerCase().includes("mono")||p.toLowerCase().includes("code"))||"monospace",source:"package.json"}}}catch{}return null}function De(e){if(!e)return null;let t=["Geist Mono","Geist","Instrument Sans","Space Grotesk","Space Mono","Cabinet Grotesk","General Sans","Satoshi","Switzer","Bespoke Serif","Fraunces","Cormorant Garamond","Newsreader","Noto Serif Display","Source Serif 4","Familjen Grotesk","Sora","Public Sans","Work Sans","Atkinson Hyperlegible","Bricolage Grotesque","Syne Mono","Syne","JetBrains Mono","Fira Code","IBM Plex Mono","IBM Plex Sans","DM Sans","DM Mono","Outfit","VT323","Archivo"],s=e.toLowerCase();for(let a of t)if(new RegExp(`\\b(?:use|with|in|font:?)\\s+${a.toLowerCase()}\\b|\\b${a.toLowerCase()}\\s+(?:font|typography)\\b`,"i").test(e)||s.includes(`use ${a.toLowerCase()}`)){let f=/mono|code|vt323/i.test(a),y=/serif|garamond|fraunces|newsreader|cinzel/i.test(a);return f?{mono:a,source:"custom"}:y?{display:a,source:"custom"}:{sans:a,display:a,source:"custom"}}return null}function re(e,t){if(!e)return"";if(e.includes(",")&&(e.includes("serif")||e.includes("sans-serif")||e.includes("monospace")))return e;let s=e.replace(/['"]/g,"").trim(),a=s.toLowerCase(),g=t==="mono"||/mono|code|vt323|inconsolata/i.test(a),f=t==="display"&&/serif|garamond|fraunces|newsreader|cinzel/i.test(a);return g?`'${s}', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`:f?`'${s}', Georgia, "Times New Roman", serif`:`'${s}', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`}function Re(e,t,s,a){let g=[T(e),T(t),T(s)].filter(Boolean),f=Array.from(new Set(g)),y=[],i=[];for(let c of f){let d=c.toLowerCase();if(oe[d])y.push(`@import url('https://api.fontshare.com/v2/css?f[]=${oe[d]}&display=swap');`);else{if(d==="monospace"||d==="serif"||d==="sans-serif"||d==="customuserfont")continue;{let m=c.replace(/\s+/g,"+"),p=$e[d]||"wght@400;500;600;700";i.push(`family=${m}:${p}`)}}}let n=[];return a&&!n.includes(`@import url('${a}');`)&&n.push(`@import url('${a}');`),n.push(...y),i.length>0&&n.push(`@import url('https://fonts.googleapis.com/css2?${i.join("&")}&display=swap');`),n.length>0?n.join(`
|
|
3
3
|
`)+`
|
|
4
4
|
|
|
5
|
-
`:""}function le(e){let{archetype:t,feeling:
|
|
5
|
+
`:""}function le(e){let{archetype:t,feeling:s,radius:a,blur:g,projectName:f}=e,y=Ie(f),i="dark",n=250,c=.12,d=.18,m=.09,p=.28,v="oklch(0.65 0.20 250)",r="oklch(0.65 0.20 250 / 0.15)",l="oklch(0.70 0.22 250)",o=.96,u=.68,x=.52,b='"Geist", "Instrument Sans", sans-serif',C='"Geist", "Instrument Sans", sans-serif',A='"Geist Mono", "SF Mono", monospace',P=1.25;t==="editorial-serif-paper"?(i="light",n=75,c=.97,d=.99,m=.92,p=.85,v="oklch(0.48 0.18 25)",r="oklch(0.48 0.18 25 / 0.12)",l="oklch(0.42 0.20 25)",o=.2,u=.48,x=.62,b='"Newsreader", Georgia, serif',C='"Work Sans", sans-serif',A='"Fragment Mono", monospace'):t==="neo-brutalism"?(i="light",n=90,c=.97,d=1,m=.9,p=.12,v="oklch(0.85 0.28 130)",r="oklch(0.85 0.28 130 / 0.25)",l="oklch(0.88 0.30 130)",o=.12,u=.38,x=.5,b='"Space Grotesk", sans-serif',C='"Syne", sans-serif',A='"Space Mono", monospace',P=1.333):t==="swiss-typographic-grid"?(i="light",n=260,c=.98,d=1,m=.92,p=.12,v="oklch(0.55 0.22 25)",r="oklch(0.55 0.22 25 / 0.12)",l="oklch(0.50 0.24 25)",o=.12,u=.42,x=.55,b='"Cabinet Grotesk", sans-serif',C='"Space Grotesk", sans-serif',A='"Space Mono", monospace'):t==="kinetic-industrial-mono"?(i="dark",n=240,c=.1,d=.15,m=.07,p=.26,v="oklch(0.76 0.18 70)",r="oklch(0.76 0.18 70 / 0.15)",l="oklch(0.80 0.20 70)",o=.95,u=.68,x=.48,b='"JetBrains Mono", monospace',C='"IBM Plex Sans", sans-serif',A='"JetBrains Mono", monospace',P=1.2):t==="bento-modular-system"?(i="dark",n=255,c=.12,d=.17,m=.09,p=.28,v="oklch(0.64 0.22 255)",r="oklch(0.64 0.22 255 / 0.15)",l="oklch(0.68 0.24 255)",o=.96,u=.68,x=.5,b='"Satoshi", sans-serif',C='"General Sans", sans-serif',A='"Geist Mono", monospace'):t==="spatial-glass-visionos"?(i="dark",n=260,c=.1,d=.18,m=.08,p=.35,v="oklch(0.72 0.18 200)",r="oklch(0.72 0.18 200 / 0.18)",l="oklch(0.76 0.20 200)",o=.98,u=.72,x=.54,b='"Outfit", sans-serif',C='"DM Sans", sans-serif',A='"Fragment Mono", monospace'):t==="quiet-luxury-atelier"?(i="light",n=70,c=.97,d=.99,m=.92,p=.86,v="oklch(0.50 0.04 60)",r="oklch(0.50 0.04 60 / 0.12)",l="oklch(0.45 0.05 60)",o=.18,u=.46,x=.6,b='"Cormorant Garamond", serif',C='"DM Sans", sans-serif',A='"Fragment Mono", monospace'):t==="warm-artisan-craft"?(i="light",n=80,c=.96,d=.98,m=.9,p=.85,v="oklch(0.58 0.16 40)",r="oklch(0.58 0.16 40 / 0.14)",l="oklch(0.52 0.18 40)",o=.24,u=.5,x=.62,b='"Fraunces", serif',C='"Cabinet Grotesk", sans-serif',A='"DM Mono", monospace'):t==="japanese-minimal-zen"?(i="light",n=90,c=.97,d=.99,m=.91,p=.88,v="oklch(0.22 0.01 250)",r="oklch(0.22 0.01 250 / 0.10)",l="oklch(0.16 0.01 250)",o=.2,u=.48,x=.62,b='"Noto Serif Display", serif',C='"Work Sans", sans-serif',A='"DM Mono", monospace'):t==="scandinavian-warm-minimal"?(i="light",n=85,c=.97,d=.99,m=.91,p=.86,v="oklch(0.54 0.14 235)",r="oklch(0.54 0.14 235 / 0.14)",l="oklch(0.48 0.16 235)",o=.2,u=.48,x=.6,b='"Familjen Grotesk", sans-serif',C='"DM Sans", sans-serif',A='"Fragment Mono", monospace'):t==="retro-tactile-analog"?(i="dark",n=240,c=.2,d=.27,m=.14,p=.36,v="oklch(0.68 0.24 45)",r="oklch(0.68 0.24 45 / 0.18)",l="oklch(0.72 0.26 45)",o=.96,u=.72,x=.55,b='"Space Mono", monospace',C='"Chivo", sans-serif',A='"Space Mono", monospace',P=1.2):t==="y2k-acid-cyber"?(i="dark",n=290,c=.08,d=.14,m=.05,p=.3,v="oklch(0.88 0.28 135)",r="oklch(0.88 0.28 135 / 0.20)",l="oklch(0.92 0.30 135)",o=.98,u=.74,x=.55,b='"Syne", sans-serif',C='"Chakra Petch", sans-serif',A='"Space Mono", monospace',P=1.333):t==="playful-clay-consumer"?(i="light",n=280,c=.97,d=.99,m=.92,p=.88,v="oklch(0.66 0.22 295)",r="oklch(0.66 0.22 295 / 0.15)",l="oklch(0.70 0.24 295)",o=.2,u=.48,x=.6,b='"Bricolage Grotesque", sans-serif',C='"Fredoka", sans-serif',A='"Space Mono", monospace'):t==="vaporwave-crt-terminal"?(i="dark",n=290,c=.09,d=.14,m=.06,p=.28,v="oklch(0.78 0.18 200)",r="oklch(0.78 0.18 200 / 0.15)",l="oklch(0.82 0.20 200)",o=.96,u=.7,x=.5,b='"VT323", monospace',C='"Fira Code", monospace',A='"Fira Code", monospace',P=1.2):t==="high-trust-fintech-clarity"?(i="light",n=245,c=.98,d=1,m=.93,p=.86,v="oklch(0.56 0.18 245)",r="oklch(0.56 0.18 245 / 0.12)",l="oklch(0.50 0.20 245)",o=.14,u=.44,x=.58,b='"Sora", sans-serif',C='"Public Sans", sans-serif',A='"Fira Code", monospace'):t==="clinical-biotech-precision"?(i="light",n=220,c=.98,d=1,m=.92,p=.85,v="oklch(0.68 0.16 215)",r="oklch(0.68 0.16 215 / 0.12)",l="oklch(0.62 0.18 215)",o=.14,u=.42,x=.56,b='"Instrument Sans", sans-serif',C='"Public Sans", sans-serif',A='"IBM Plex Mono", monospace'):t==="civic-govtech-accessible"&&(i="light",n=260,c=.99,d=1,m=.92,p=.3,v="oklch(0.42 0.16 245)",r="oklch(0.42 0.16 245 / 0.12)",l="oklch(0.36 0.18 245)",o=.12,u=.38,x=.5,b='"Atkinson Hyperlegible", sans-serif',C='"Public Sans", sans-serif',A='"Fragment Mono", monospace');let S=((n+y)%360+360)%360,Ce=ae(o,i,"primary"),Ae=ae(i==="dark"?.8:.34,i,"secondary"),Me=ae(u,i,"muted"),U="6px",H="4px",j="4px";a==="sharp"?(U="0px",H="0px",j="0px"):a==="medium"?(U="10px",H="6px",j="6px"):a==="high"?(U="16px",H="10px",j="8px"):a==="pill"&&(U="9999px",H="9999px",j="9999px");let X="8px";g==="flat"?X="0px":g==="deep-glass"&&(X="20px");let Y=ie[s]||ie["urgent-precise"],Ee=Y.ease,Fe=Y.easeSpring,Pe=Y.durationFast,Te=Y.durationNormal,Q="0 1px 2px 0 oklch(0 0 0 / 0.45), 0 0 0 1px var(--border-hairline)",ee="0 4px 12px 0 oklch(0 0 0 / 0.50), 0 0 0 1px var(--border-hairline)";i==="light"&&t!=="neo-brutalism"?(Q="0 1px 3px 0 oklch(0.20 0.012 50 / 0.06), 0 0 0 1px var(--border-hairline)",ee="0 6px 16px -2px oklch(0.20 0.012 50 / 0.08), 0 0 0 1px var(--border-hairline)"):t==="neo-brutalism"&&(Q="3px 3px 0px 0px oklch(0.12 0.005 260)",ee="6px 6px 0px 0px oklch(0.12 0.005 260)");let $=_[t]||_["dark-obsidian-technical"],O=$.A.display,B=$.A.sans,G=$.A.mono;e.fontOverride?.source==="preserved"&&(e.fontMode==="keep"||!e.fontMode)?(e.fontOverride.display&&(O=T(e.fontOverride.display)),e.fontOverride.sans&&(B=T(e.fontOverride.sans)),e.fontOverride.mono&&(G=T(e.fontOverride.mono))):e.fontMode==="B"?(O=$.B.display,B=$.B.sans,G=$.B.mono):e.fontMode==="C"?(O=$.C.display,B=$.C.sans,G=$.C.mono):e.fontOverride&&(e.fontOverride.display&&(O=T(e.fontOverride.display)),e.fontOverride.sans&&(B=T(e.fontOverride.sans)),e.fontOverride.mono&&(G=T(e.fontOverride.mono)));let L=De(e.customDirection);L&&e.fontMode!=="keep"&&(L.display&&(O=L.display),L.sans&&(B=L.sans),L.mono&&(G=L.mono)),b=re(O,"display"),C=re(B,"sans"),A=re(G,"mono");let h={"--bg-canvas":`oklch(${c} 0.015 ${S})`,"--bg-elevated":`oklch(${d} 0.015 ${S})`,"--bg-surface-active":`oklch(${d+(i==="dark"?.04:-.04)} 0.018 ${S})`,"--bg-glass":`oklch(${d} 0.015 ${S} / 0.72)`,"--bg-sunken":`oklch(${m} 0.012 ${S})`,"--text-primary":`oklch(${Ce} 0.005 ${S})`,"--text-secondary":`oklch(${Ae} 0.010 ${S})`,"--text-muted":`oklch(${Me} 0.015 ${S})`,"--text-subtle":`oklch(${x} 0.018 ${S})`,"--text-inverse":i==="dark"?`oklch(0.12 0.015 ${S})`:`oklch(0.98 0.005 ${S})`,"--accent-primary":v,"--accent-subtle":r,"--accent-hover":l,"--border-hairline":i==="dark"?"oklch(1 0 0 / 0.07)":"oklch(0 0 0 / 0.07)","--border-subtle":i==="dark"?"oklch(1 0 0 / 0.04)":"oklch(0 0 0 / 0.04)","--border-focus":`oklch(0.65 0.20 ${S} / 0.75)`,"--highlight-specular":i==="dark"?"oklch(1 0 0 / 0.18)":"oklch(1 0 0 / 0.60)","--status-success":"oklch(0.72 0.16 145)","--status-warning":"oklch(0.78 0.14 75)","--status-danger":"oklch(0.65 0.22 25)","--status-info":"oklch(0.70 0.15 230)","--radius-outer":U,"--radius-inner":H,"--radius-badge":j,"--surface-blur":X,"--shadow-surface":Q,"--shadow-elevated":ee,"--section-py-tight":"clamp(2.5rem, 4vw, 4rem)","--section-py-normal":"clamp(4.5rem, 7vw, 6.5rem)","--section-py-breathing":"clamp(7rem, 12vw, 11rem)","--container-max":"1280px","--font-display":b,"--font-sans":C,"--font-mono":A,"--text-xs":"0.8125rem","--text-sm":"0.9375rem","--text-base":"1.0625rem","--text-lg":"1.25rem","--text-xl":`${(1.25*P).toFixed(3)}rem`,"--text-2xl":`${(1.25*Math.pow(P,2)).toFixed(3)}rem`,"--text-3xl":`${(1.25*Math.pow(P,3)).toFixed(3)}rem`,"--text-4xl":`${(1.25*Math.pow(P,4)).toFixed(3)}rem`,"--weight-heading":"600","--weight-body":"400","--weight-mono":"500","--ease-primary":Ee,"--ease-spring":Fe,"--duration-fast":Pe,"--duration-normal":Te};return{css:`${Re(O,B,G,e.fontOverride?.importUrl)}/* =============================================================================
|
|
6
6
|
AGENT DESIGN SKILLS \u2014 TOKEN CONTRACT (v1.1)
|
|
7
7
|
Archetype: ${t}
|
|
8
|
-
Polarity: ${
|
|
9
|
-
Feeling Vector: ${
|
|
8
|
+
Polarity: ${i}
|
|
9
|
+
Feeling Vector: ${s}
|
|
10
10
|
Jitter: ${y>0?`+${y}`:y}\xB0 (Base Hue: ${n})
|
|
11
11
|
============================================================================= */
|
|
12
12
|
|
|
@@ -82,16 +82,16 @@ import{Command as rt}from"commander";import*as k from"@clack/prompts";import w f
|
|
|
82
82
|
============================================================================= */
|
|
83
83
|
|
|
84
84
|
[data-theme="light"], .light {
|
|
85
|
-
--bg-canvas: oklch(0.97 0.015 ${
|
|
86
|
-
--bg-elevated: oklch(0.99 0.015 ${
|
|
87
|
-
--bg-surface-active: oklch(0.95 0.018 ${
|
|
88
|
-
--bg-glass: oklch(0.99 0.015 ${
|
|
89
|
-
--bg-sunken: oklch(0.92 0.012 ${
|
|
90
|
-
--text-primary: oklch(0.15 0.015 ${
|
|
91
|
-
--text-secondary: oklch(0.34 0.015 ${
|
|
92
|
-
--text-muted: oklch(0.44 0.015 ${
|
|
93
|
-
--text-subtle: oklch(0.55 0.018 ${
|
|
94
|
-
--text-inverse: oklch(0.98 0.005 ${
|
|
85
|
+
--bg-canvas: oklch(0.97 0.015 ${S});
|
|
86
|
+
--bg-elevated: oklch(0.99 0.015 ${S});
|
|
87
|
+
--bg-surface-active: oklch(0.95 0.018 ${S});
|
|
88
|
+
--bg-glass: oklch(0.99 0.015 ${S} / 0.72);
|
|
89
|
+
--bg-sunken: oklch(0.92 0.012 ${S});
|
|
90
|
+
--text-primary: oklch(0.15 0.015 ${S});
|
|
91
|
+
--text-secondary: oklch(0.34 0.015 ${S});
|
|
92
|
+
--text-muted: oklch(0.44 0.015 ${S});
|
|
93
|
+
--text-subtle: oklch(0.55 0.018 ${S});
|
|
94
|
+
--text-inverse: oklch(0.98 0.005 ${S});
|
|
95
95
|
--border-hairline: oklch(0 0 0 / 0.07);
|
|
96
96
|
--border-subtle: oklch(0 0 0 / 0.04);
|
|
97
97
|
--highlight-specular: oklch(1 0 0 / 0.60);
|
|
@@ -100,16 +100,16 @@ import{Command as rt}from"commander";import*as k from"@clack/prompts";import w f
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
[data-theme="dark"], .dark {
|
|
103
|
-
--bg-canvas: oklch(0.12 0.015 ${
|
|
104
|
-
--bg-elevated: oklch(0.18 0.015 ${
|
|
105
|
-
--bg-surface-active: oklch(0.22 0.018 ${
|
|
106
|
-
--bg-glass: oklch(0.18 0.015 ${
|
|
107
|
-
--bg-sunken: oklch(0.09 0.012 ${
|
|
108
|
-
--text-primary: oklch(0.97 0.005 ${
|
|
109
|
-
--text-secondary: oklch(0.80 0.010 ${
|
|
110
|
-
--text-muted: oklch(0.68 0.015 ${
|
|
111
|
-
--text-subtle: oklch(0.52 0.018 ${
|
|
112
|
-
--text-inverse: oklch(0.12 0.015 ${
|
|
103
|
+
--bg-canvas: oklch(0.12 0.015 ${S});
|
|
104
|
+
--bg-elevated: oklch(0.18 0.015 ${S});
|
|
105
|
+
--bg-surface-active: oklch(0.22 0.018 ${S});
|
|
106
|
+
--bg-glass: oklch(0.18 0.015 ${S} / 0.72);
|
|
107
|
+
--bg-sunken: oklch(0.09 0.012 ${S});
|
|
108
|
+
--text-primary: oklch(0.97 0.005 ${S});
|
|
109
|
+
--text-secondary: oklch(0.80 0.010 ${S});
|
|
110
|
+
--text-muted: oklch(0.68 0.015 ${S});
|
|
111
|
+
--text-subtle: oklch(0.52 0.018 ${S});
|
|
112
|
+
--text-inverse: oklch(0.12 0.015 ${S});
|
|
113
113
|
--border-hairline: oklch(1 0 0 / 0.07);
|
|
114
114
|
--border-subtle: oklch(1 0 0 / 0.04);
|
|
115
115
|
--highlight-specular: oklch(1 0 0 / 0.18);
|
|
@@ -178,33 +178,32 @@ h1, h2, h3, h4 {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
.spring-interactive {
|
|
181
|
-
transition: transform var(--duration-fast) var(--ease-spring, var(--ease-primary));
|
|
181
|
+
transition: scale var(--duration-fast) var(--ease-spring, var(--ease-primary)), transform var(--duration-fast) var(--ease-spring, var(--ease-primary));
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
.spring-interactive:active {
|
|
185
|
-
|
|
185
|
+
scale: 0.96;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
/* Tactile Card
|
|
188
|
+
/* Tactile Card Physics (Zero transform drift on layout shells, headers, or cards) */
|
|
189
189
|
.glass-panel, .surface-card, [data-interactive-card="true"] {
|
|
190
|
-
transition:
|
|
190
|
+
transition: border-color var(--duration-fast) var(--ease-primary), box-shadow var(--duration-fast) var(--ease-primary);
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
.glass-panel:hover, .surface-card:hover, [data-interactive-card="true"]:hover {
|
|
194
|
-
transform: translateY(-2px) scale(1.008);
|
|
195
194
|
border-color: var(--highlight-specular);
|
|
196
195
|
}
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
/* Universal Input Reset: Prevent inner rectangular outlines inside composite input wrappers */
|
|
198
|
+
input, textarea, select {
|
|
199
|
+
outline: none;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
:
|
|
204
|
-
outline: 2px
|
|
205
|
-
outline-offset: 1px;
|
|
202
|
+
button:focus-visible, a:focus-visible, [role="button"]:focus-visible, [role="tab"]:focus-visible {
|
|
203
|
+
outline: 2px solid var(--accent-primary);
|
|
204
|
+
outline-offset: 2px;
|
|
206
205
|
}
|
|
207
|
-
`,json:{version:"1.1.
|
|
206
|
+
`,json:{version:"1.1.1",archetype:t,polarity:i,feeling:s,folderJitter:y,variables:h},variables:h}}function Oe(e){let s=e.indexOf("## 5. Component Inventory");return s!==-1?e.slice(s).trim():null}function ce(e,t){let{projectName:s,archetype:a,customDirection:g="Needs to feel like a high-precision developer settlement console, crisp 1px hairlines, zero marketing fluff",productBrief:f="High-precision operational workspace and data reconciliation platform"}=e,y="Dark";new Set(["editorial-serif-paper","neo-brutalism","swiss-typographic-grid","quiet-luxury-atelier","warm-artisan-craft","japanese-minimal-zen","scandinavian-warm-minimal","playful-clay-consumer","high-trust-fintech-clarity","clinical-biotech-precision","civic-govtech-accessible"]).has(a)&&(y="Light");let n="Desktop-First",c="Direct, Forensic, Unhurried",d="Row 4,812: $412.50 FX discrepancy between Stripe payout and nodal settlement.",m="Oops! Something went wrong with your reconciliation. Try again!",p="Precision single-sweep scanline pulse over the batch header upon reconciliation commitment (180ms ease, zero overshoot).";a==="editorial-serif-paper"||a==="quiet-luxury-atelier"?(c="Literary, Dispassionate, Deeply-Researched",d="Vault allocation audited against physical treasury bills with verified CUSIP numbers.",m="Supercharge your treasury with our smart AI dashboard! \u{1F680}",p="Gentle 240ms ink-soak underline expansion upon section entry."):a==="neo-brutalism"&&(y="Light",c="Stark, Punchy, Tactile",d="Pipeline output committed. Hash: 0x8F2D. 0 warnings.",m="Enjoy our smooth and seamless creative workflow experience.",p="Hard tactile button depress translating 3px and collapsing shadow.");let v=`# Design Specification & Token Contract
|
|
208
207
|
|
|
209
208
|
**STATUS:** ACTIVE
|
|
210
209
|
**BRIEF STATUS:** LOCKED
|
|
@@ -238,7 +237,7 @@ h1, h2, h3, h4 {
|
|
|
238
237
|
## 2. Voice & Content Brief
|
|
239
238
|
|
|
240
239
|
**Product Definition:**
|
|
241
|
-
${f} for ${
|
|
240
|
+
${f} for ${s}.
|
|
242
241
|
|
|
243
242
|
### Verified Facts (Immutable Ground Truth)
|
|
244
243
|
1. Operational integrity validated against immutable append-only logs.
|
|
@@ -246,15 +245,15 @@ ${f} for ${r}.
|
|
|
246
245
|
3. Full regulatory and security compliance certified under standard industry frameworks.
|
|
247
246
|
|
|
248
247
|
### Voice Adjectives
|
|
249
|
-
- **${
|
|
250
|
-
- **${
|
|
251
|
-
- **${
|
|
248
|
+
- **${c.split(",")[0]?.trim()}**
|
|
249
|
+
- **${c.split(",")[1]?.trim()}**
|
|
250
|
+
- **${c.split(",")[2]?.trim()}**
|
|
252
251
|
|
|
253
252
|
### Voice Contrast
|
|
254
253
|
|
|
255
254
|
| Sounds Like | Never Sounds Like |
|
|
256
255
|
|---|---|
|
|
257
|
-
| "${
|
|
256
|
+
| "${d}" | "${m}" |
|
|
258
257
|
| "12 batches pending verification. Run reconciliation sequence." | "Say goodbye to financial headaches with our smart AI dashboard!" |
|
|
259
258
|
| "Batch \`0x8F2D\`: Merkle root verified against append-only log." | "One-click simplicity for all your enterprise needs." |
|
|
260
259
|
|
|
@@ -285,11 +284,11 @@ All components MUST consume these semantic tokens directly. Never duplicate raw
|
|
|
285
284
|
- **Numeric & Tabular Typography Law:** NEVER use coding monospace fonts (\`--font-mono\`) or \`slashed-zero\` on hero numbers, counters, or KPI figures. Always use \`var(--font-display)\` or \`var(--font-sans)\` with \`font-variant-numeric: tabular-nums lining-nums; font-feature-settings: "tnum" 1, "lnum" 1, "zero" 0;\` so digits have clean, open-oval zeros (\`0\`) with zero horizontal jitter. Reserve \`var(--font-mono)\` strictly for code snippets, file paths, or git hashes.
|
|
286
285
|
- **Badge & Indicator Discipline:** Eyebrows must stand alone as plain monospace text. Colored status dots are forbidden unless tied to a live connection status.
|
|
287
286
|
- **Signature Moment:** ${p}
|
|
288
|
-
`;if(t){let
|
|
287
|
+
`;if(t){let l=Oe(t);if(l)return`${v}
|
|
289
288
|
---
|
|
290
289
|
|
|
291
|
-
${
|
|
292
|
-
`}return`${
|
|
290
|
+
${l}
|
|
291
|
+
`}return`${v}
|
|
293
292
|
---
|
|
294
293
|
|
|
295
294
|
## 5. Component Inventory
|
|
@@ -332,13 +331,13 @@ ${d}
|
|
|
332
331
|
|
|
333
332
|
- [ ] **Tabular Alignment Check:** Ensure all numeric columns right-align with zero jitter.
|
|
334
333
|
- [ ] **Keyboard Navigation:** Bind keyboard shortcut navigation for data grid rows.
|
|
335
|
-
`}import M from"fs-extra";import
|
|
334
|
+
`}import M from"fs-extra";import E from"pathe";import{fileURLToPath as Be}from"url";async function Ge(){let e=Be(import.meta.url),t=E.dirname(e),s=[E.resolve(t,"../registry"),E.resolve(t,"../../registry"),E.resolve(t,"../../../registry"),E.resolve(process.cwd(),"registry")];for(let a of s)if(await M.pathExists(a))return a;return E.resolve(process.cwd(),"registry")}function de(e,t){return e.replace(/\{\{ARCHETYPE_NAME\}\}/g,t.archetype).replace(/\{\{TOKENS_PATH\}\}/g,"./tokens.css").replace(/\{\{DESIGN_DOC_PATH\}\}/g,"./DESIGN.md").replace(/\{\{PRODUCT_NAME\}\}/g,t.projectName).replace(/\{\{PRODUCT_BRIEF\}\}/g,t.productBrief||"High-precision operational workspace and data reconciliation platform")}async function pe(e,t,s){let a=[],f=await M.pathExists(E.resolve(e,".agents"))?".agents":".agent",y=E.resolve(e,f,"rules");await M.ensureDir(y);let i=E.resolve(y,"design-core.md"),n=`---
|
|
336
335
|
trigger: always_on
|
|
337
336
|
description: "Always-On Core Design Governance Rule (v1.0)"
|
|
338
337
|
---
|
|
339
338
|
|
|
340
|
-
${
|
|
341
|
-
`;await M.writeFile(
|
|
339
|
+
${s}
|
|
340
|
+
`;await M.writeFile(i,n,"utf-8"),a.push(i);let c=E.resolve(e,f,"skills/design-system");await M.ensureDir(c);let d=E.resolve(c,"SKILL.md"),m=await Ge(),p=E.resolve(m,"core"),v=E.resolve(m,"archetypes",`${t.archetype}.md`),r=["00-workflow-and-scope.md","01-override-protocol.md","02-anti-slop-firewall.md","03-cross-page-unity.md","04-ux-and-ergonomics.md","05-voice-and-copy.md","06-iteration-discipline.md"];if(t.mode==="single"){let l=`---
|
|
342
341
|
name: design-system
|
|
343
342
|
description: "Complete design system tokens, UX ergonomics, and archetype specifications"
|
|
344
343
|
---
|
|
@@ -349,18 +348,18 @@ Target Archetype: \`${t.archetype}\`
|
|
|
349
348
|
Token Contract: \`./tokens.css\`
|
|
350
349
|
Design Specification: \`./DESIGN.md\`
|
|
351
350
|
|
|
352
|
-
${
|
|
351
|
+
${s}
|
|
353
352
|
|
|
354
353
|
---
|
|
355
|
-
`;for(let
|
|
354
|
+
`;for(let o of r){let u=E.resolve(p,o);if(await M.pathExists(u)){let x=await M.readFile(u,"utf-8");l+=`
|
|
356
355
|
---
|
|
357
356
|
|
|
358
|
-
${de(
|
|
359
|
-
`}}if(await M.pathExists(
|
|
357
|
+
${de(x,t)}
|
|
358
|
+
`}}if(await M.pathExists(v)){let o=await M.readFile(v,"utf-8");l+=`
|
|
360
359
|
---
|
|
361
360
|
|
|
362
|
-
${
|
|
363
|
-
`}await M.writeFile(
|
|
361
|
+
${o}
|
|
362
|
+
`}await M.writeFile(d,l,"utf-8"),a.push(d)}else{let l=E.resolve(c,"references");await M.ensureDir(l);for(let u of r){let x=E.resolve(p,u),b=E.resolve(l,u);if(await M.pathExists(x)){let C=await M.readFile(x,"utf-8");await M.writeFile(b,de(C,t),"utf-8"),a.push(b)}}if(await M.pathExists(v)){let u=E.resolve(l,"archetype.md"),x=await M.readFile(v,"utf-8");await M.writeFile(u,x,"utf-8"),a.push(u)}let o=`---
|
|
364
363
|
name: design-system
|
|
365
364
|
description: "Complete design system tokens, UX ergonomics, and archetype specifications"
|
|
366
365
|
---
|
|
@@ -384,13 +383,13 @@ Consult the following modular references in \`./references/\` during design task
|
|
|
384
383
|
- **05 Voice & Copy:** \`./references/05-voice-and-copy.md\` \u2014 Brochure test, swap test, sentence casing, and punctuation discipline.
|
|
385
384
|
- **06 Iteration Discipline:** \`./references/06-iteration-discipline.md\` \u2014 Fix-forward principle and 2-pass budget.
|
|
386
385
|
- **Archetype Guide:** \`./references/archetype.md\` \u2014 Archetype specifications, font pairings, and OKLCH palettes.
|
|
387
|
-
`;await M.writeFile(
|
|
386
|
+
`;await M.writeFile(d,o,"utf-8"),a.push(d)}return a}import V from"fs-extra";import W from"pathe";async function ue(e,t,s){let a=W.resolve(e,".cursor/rules");await V.ensureDir(a);let g=[],f=W.resolve(a,"00-design-core.mdc"),y=`---
|
|
388
387
|
description: "Always-On Core Design Governance Rule for Cursor (v1.0)"
|
|
389
388
|
alwaysApply: true
|
|
390
389
|
---
|
|
391
390
|
|
|
392
|
-
${
|
|
393
|
-
`;if(await
|
|
391
|
+
${s}
|
|
392
|
+
`;if(await V.writeFile(f,y,"utf-8"),g.push(f),t.mode!=="single"){let i=W.resolve(a,"01-ux-ergonomics.mdc");await V.writeFile(i,`---
|
|
394
393
|
description: "UX Ergonomics, Component States & Realistic Seed Data (v1.0)"
|
|
395
394
|
globs: "**/*.jsx, **/*.tsx, **/*.vue, **/*.svelte, **/*.html"
|
|
396
395
|
alwaysApply: false
|
|
@@ -410,7 +409,7 @@ Every interactive component or data view must handle:
|
|
|
410
409
|
- Ban "John Doe", "Jane Doe", "Lorem ipsum", "Acme", and "$99.99".
|
|
411
410
|
- Require varied string lengths, at least 1 long entity string testing truncation (\`text-overflow: ellipsis\`), 1 null avatar monogram fallback, and 1 zero/pending state.
|
|
412
411
|
- Tabular numbers: All metrics, counters, and currencies must enforce \`font-variant-numeric: tabular-nums\`.
|
|
413
|
-
`,"utf-8"),g.push(
|
|
412
|
+
`,"utf-8"),g.push(i);let c=W.resolve(a,"02-voice-copy.mdc");await V.writeFile(c,`---
|
|
414
413
|
description: "Voice, Copy Honesty, Sentence Casing & Typography Rules (v1.0)"
|
|
415
414
|
globs: "**/*.jsx, **/*.tsx, **/*.vue, **/*.svelte, **/*.html, **/*.md, **/*.mdx"
|
|
416
415
|
alwaysApply: false
|
|
@@ -427,7 +426,7 @@ alwaysApply: false
|
|
|
427
426
|
- **Sentence Case:** Strict sentence case on headings, table columns, tooltips, and buttons.
|
|
428
427
|
- **Cure "UPPERCASE MICRO-LABEL Disease":** Max 1 uppercase eyebrow per view. Ban self-evident labels (redundant status descriptions, section format labels, or narrating obvious controls). Uppercase permitted only on short functional technical tags (<= 3 words in \`var(--font-mono)\`, e.g., STATUS: ACTIVE, REF: 0x4B2).
|
|
429
428
|
- **Punctuation:** Zero em-dashes in headings; maximum 1 em-dash per page in body copy.
|
|
430
|
-
`,"utf-8"),g.push(
|
|
429
|
+
`,"utf-8"),g.push(c);let m=W.resolve(a,"03-archetype-recipe.mdc"),p=`---
|
|
431
430
|
description: "Archetype Recipe & Geometric Token Contract for ${t.archetype} (v1.0)"
|
|
432
431
|
globs: "**/*.css, **/*.scss, **/*.less, **/*.html, **/*.jsx, **/*.tsx"
|
|
433
432
|
alwaysApply: false
|
|
@@ -454,14 +453,14 @@ Child radii must never protrude past or clash with parent borders.
|
|
|
454
453
|
- 1px hairline borders: \`var(--border-hairline)\`
|
|
455
454
|
- Top specular highlight: \`var(--highlight-specular)\`
|
|
456
455
|
- Zero purple AI gradients or ungrounded card drop shadows.
|
|
457
|
-
`;await
|
|
456
|
+
`;await V.writeFile(m,p,"utf-8"),g.push(m)}return g}import me from"fs-extra";import he from"pathe";async function ge(e,t,s){let a=he.resolve(e,"CLAUDE.md"),g=he.resolve(e,"AGENTS.md"),f=`# Design Governance & Token Contract (v4.2)
|
|
458
457
|
|
|
459
|
-
${
|
|
460
|
-
`;return await me.writeFile(a,f,"utf-8"),await me.writeFile(g,f,"utf-8"),[a,g]}import Le from"fs-extra";import Ne from"pathe";async function fe(e,t,
|
|
458
|
+
${s}
|
|
459
|
+
`;return await me.writeFile(a,f,"utf-8"),await me.writeFile(g,f,"utf-8"),[a,g]}import Le from"fs-extra";import Ne from"pathe";async function fe(e,t,s){let a=Ne.resolve(e,"DESIGN-PROMPT.md"),g=`# Frontend Design System Guidelines (v4.2)
|
|
461
460
|
Target Environments: v0, Lovable, Bolt, Replit
|
|
462
461
|
|
|
463
|
-
${
|
|
464
|
-
`;return await Le.writeFile(a,g,"utf-8"),a}async function Ue(){let e=ze(import.meta.url),t=
|
|
462
|
+
${s}
|
|
463
|
+
`;return await Le.writeFile(a,g,"utf-8"),a}async function Ue(){let e=ze(import.meta.url),t=I.dirname(e),s=[I.resolve(t,"../registry"),I.resolve(t,"../../registry"),I.resolve(t,"../../../registry"),I.resolve(process.cwd(),"registry")];for(let a of s)if(await D.pathExists(a))return a;return I.resolve(process.cwd(),"registry")}function He(e){let{archetype:t}=e;return`# Always-On Design Governance Rule (v1.1)
|
|
465
464
|
|
|
466
465
|
You are the design governance engine for this codebase. Every UI decision must preserve geometric unity, copy honesty, and visual calm across every turn.
|
|
467
466
|
|
|
@@ -568,6 +567,12 @@ You are the design governance engine for this codebase. Every UI decision must p
|
|
|
568
567
|
- **Numeric & Tabular Typography Law:** NEVER use coding monospace fonts (\`--font-mono\`) or \`slashed-zero\` on hero numbers, counters, or KPI figures. Always use \`var(--font-display)\` or \`var(--font-sans)\` with \`font-variant-numeric: tabular-nums lining-nums; font-feature-settings: "tnum" 1, "lnum" 1, "zero" 0;\` so digits have clean, open-oval zeros (\`0\`) with zero horizontal jitter. Reserve \`var(--font-mono)\` strictly for code snippets, file paths, or git hashes.
|
|
569
568
|
- **Zero Sci-Fi & Hardware Telemetry Cosplay:** Ban inventing fake brand names, fake tier badges (\`[PRO v2.4]\`, \`[BETA]\`), fake hardware telemetry (\`60 FPS\`, \`SUB-10MS\`), and unrequested Unix \`EPOCH\` readouts.
|
|
570
569
|
- **Zero Fake Status Dots:** Colored status dots (static or animated) are banned in headers and footers unless wired to a real, user-toggleable live connection state.
|
|
570
|
+
- **Clean Media & Artwork Law (Never Overlay Corner Status Pills on Images, Artwork, or Video Thumbnails):**
|
|
571
|
+
- **Keep Media Uncluttered:** NEVER place floating \`position: absolute\` top-left or top-right status pills, tier tags, or promotional badges on top of album art, video thumbnails, avatars, or e-commerce product photography (e.g., ban \`\u2022 PLAYING\`, \`NOW PLAYING\`, \`HD 1080P\`, \`4K HDR\`, \`LIVE\`, \`NEW\`, \`BESTSELLER\`, \`FEATURED\`, \`HOT\`, \`IN STOCK\`).
|
|
572
|
+
- **How to Show Active or Metadata States Instead:**
|
|
573
|
+
- For active media/playback: Use a single centered icon overlay (Play/Pause/Equalizer) on the thumbnail or a quiet indicator inside the text row\u2014never a corner text pill (\`\u2022 PLAYING\`).
|
|
574
|
+
- For product/content metadata (like \`"New Arrival"\`, \`"Limited Edition"\`, or discounts): Render it as clean, quiet plain text (\`var(--text-secondary)\`) below the image alongside the title/price\u2014never as a colored sticker slapped onto the corner of the photograph.
|
|
575
|
+
- **Only Permitted Media Overlay:** A plain bottom-right numeric video duration timestamp (\`3:51\`) or a single subtle top-right icon action (like a quiet heart/bookmark icon on hover).
|
|
571
576
|
|
|
572
577
|
---
|
|
573
578
|
|
|
@@ -575,18 +580,21 @@ You are the design governance engine for this codebase. Every UI decision must p
|
|
|
575
580
|
- **Proportional Canvas Sizing Architecture:**
|
|
576
581
|
- *Focused Utilities & Compact Views:* Compact centered layout (\`max-w-3xl\` / \`768px\u2013880px\` on desktop) with centered segmented control dock; never a 1440px corporate enterprise header with an invented brand logo.
|
|
577
582
|
- *Data-Dense Workspaces (ledgers, financial consoles, multi-column tables):* Standard wide container (\`max-w-6xl\` / \`1152px\u20131280px\`) or fluid responsive workspace (\`w-full px-6\`).
|
|
583
|
+
- *Universal Container Cardinality & Overview Row Discipline (Match Data Slice to Container Intent):* In overview screens, summary sections, or any section with directional navigation (\`< >\` / \`View all\`), constrain the rendered items to a **single row** that matches the grid column count (e.g., \`.slice(0, columns)\` or a single-row \`flex overflow-x-auto\` track). Reserve multi-row wrapping strictly for dedicated full-index or catalog views.
|
|
578
584
|
- **Data Ban:** Never use \`"John Doe"\`, \`"Jane Doe"\`, \`"Lorem ipsum"\`, \`"foo"\`, or \`"$99.99"\`.
|
|
579
585
|
- **Realistic Diversity (\`// SAMPLE DATA\`):**
|
|
580
586
|
- Use realistic domain entities with varying character lengths.
|
|
581
587
|
- Include at least 1 long entity name that explicitly exercises truncation (\`text-overflow: ellipsis\`).
|
|
582
588
|
- Include at least 1 null avatar / fallback monogram.
|
|
583
589
|
- Include at least 1 zero / pending / unverified state.
|
|
590
|
+
- **Universal Asset Uniqueness:** Every distinct record in a UI dataset must have a unique visual asset/URL \u2014 never reuse the exact same image URL across two different records in sample data fixtures.
|
|
584
591
|
- **The 5 Mandatory States:** Every interactive component must handle:
|
|
585
592
|
1. Default
|
|
586
593
|
2. Interactive (Hover / Active / Focus-visible)
|
|
587
594
|
3. Loading (\`aria-busy="true"\` skeleton matching geometry)
|
|
588
595
|
4. Empty (with contextual empty-state handoff for the primary CTA)
|
|
589
596
|
5. Inline Error (clear, actionable, non-destructive feedback)
|
|
597
|
+
- **Universal Composite Input Focus Law:** For form fields and composite inputs (inputs with icons, prefixes, or action buttons), never allow a raw inner \`<input>\` focus box to clip inside a rounded wrapper; use \`outline: none\` on the inner input and apply focus feedback (\`border-color\` or ring) to the outer field container via \`:focus-within\`.
|
|
590
598
|
- **Mobile Bottom-Dock Safe Clearance & Thumb Zone:** On \`mobile-first\` or \`adaptive-hybrid\` layouts, mobile bottom navigation (\`< 768px\`) MUST use \`position: fixed; bottom: 0; left: 0; right: 0; z-index: 50\`, and the scroll container MUST reserve \`padding-bottom: calc(5rem + env(safe-area-inset-bottom))\` (or \`calc(dock-height + 2rem)\`) so scrollable content is never sliced or trapped behind floating controls. Primary action triggers must remain anchored in the lower thumb zone.
|
|
591
599
|
- **Smooth State Transitions:** Tab switches, view toggles, and progress indicators must animate smoothly using \`var(--ease-primary)\` and \`var(--duration-normal)\` (or \`.view-transition\`). Interactive triggers must include \`.spring-interactive\` tactile press states.
|
|
592
600
|
|
|
@@ -603,10 +611,10 @@ You are the design governance engine for this codebase. Every UI decision must p
|
|
|
603
611
|
### 11. Fix-Forward & 2-Pass Revision Budget
|
|
604
612
|
- **Fix-Forward:** Resolve visual or ergonomic issues by updating \`./tokens.css\` or removing clutter\u2014**never** by adding wrapper elements, extra containers, or ad-hoc overrides.
|
|
605
613
|
- **Revision Budget:** Maximum **2 iterative revision passes** per feature. Track each pass in \`DESIGN.md\` Section 6.
|
|
606
|
-
- Log non-blocking enhancements into \`DESIGN.md\` Section 8 (**Polish Backlog**) rather than burning turns on infinite micro-tweaks.`}async function se(e){let{targetDir:t,agents:
|
|
607
|
-
`),n=!1,l=0,c=0,m="";for(let p=0;p<o.length;p++){let s=o[p],i=p+1,d=s.trim();/<(?:header|nav)\b/i.test(s)&&(n=!0),/<\/(?:header|nav)>/i.test(s)&&(n=!1);let u=s.includes("/* @design-exception")||s.includes("/* @design-signature")||s.includes("// @design-exception")||s.includes("// @design-signature");if(!g&&!u){Ke.test(s)&&r.push({file:a,rule:"tokens/no-hardcoded-color-radius",line:i,snippet:d,message:"Hardcoded color function (rgb, hsl, oklch) found outside tokens.css without @design-exception",severity:"error"});let b=s.match(_e);if(b)for(let S of b){let C=s.indexOf(S);C>0&&/[a-zA-Z0-9_-]/.test(s[C-1])||r.push({file:a,rule:"tokens/no-hardcoded-color-radius",line:i,snippet:d,message:`Hardcoded hex color '${S}' found outside tokens.css without @design-exception`,severity:"error"})}}s.includes("animate-ping")&&r.push({file:a,rule:"slop/no-animate-ping",line:i,snippet:d,message:'Banned attention-seeking animation "animate-ping" detected',severity:"error"}),qe.test(s)&&!u&&r.push({file:a,rule:"slop/no-ai-gradient",line:i,snippet:d,message:"Banned AI clich\xE9 gradient (purple/pink mesh) detected",severity:"error"});let v=s.toLowerCase();for(let b of Ve)if(v.includes(b)&&!s.includes("rule")&&!s.includes("banned")){r.push({file:a,rule:"copy/banned-phrases-and-leakage",line:i,snippet:d,message:`Self-referential or marketing copy clich\xE9 detected: "${b}"`,severity:"error"});break}!s.includes("regex")&&!s.includes("banned")&&!s.includes("Banned")&&!s.includes("Rule")&&(/^\s*0[1-9]\s*\/\s*[A-Z]/.test(d)||/>?\s*0[1-9]\s*\/\s*[A-Z]/.test(s))&&r.push({file:a,rule:"copy/banned-phrases-and-leakage",line:i,snippet:d,message:'Numbered slash eyebrow (e.g. "01 / ...") detected above headings or in UI markup',severity:"error"}),n&&Xe.test(s)&&!u&&!f&&r.push({file:a,rule:"slop/no-decorative-badges",line:i,snippet:d,message:"Banned decorative badge/pill/chip detected inside <header> or <nav>",severity:"error"}),!u&&!f&&!s.includes("rule")&&!s.includes("banned")&&(Je.test(s)?r.push({file:a,rule:"slop/no-fake-telemetry-cosplay",line:i,snippet:d,message:"Fake product tier/version badge (e.g. [PRO v2.4], [BETA]) detected",severity:"error"}):Ze.test(s)&&r.push({file:a,rule:"slop/no-fake-telemetry-cosplay",line:i,snippet:d,message:"Fake hardware telemetry or sci-fi cosplay copy detected",severity:"error"})),Ye.test(s)&&!u&&!s.includes('"zero" 0')&&!g&&!f&&r.push({file:a,rule:"slop/no-slashed-zero",line:i,snippet:d,message:'Banned slashed-zero numeric styling detected. Use open-oval zeros with "zero" 0',severity:"error"}),!g&&!f&&!u&&(et.test(s)&&r.push({file:a,rule:"a11y/no-micro-text",line:i,snippet:d,message:"Unreadable micro-text detected (< 13px). Maintain minimum 13px (0.8125rem) floor for human readability.",severity:"error"}),tt.test(s)&&r.push({file:a,rule:"a11y/no-micro-text",line:i,snippet:d,message:"Low-contrast dim text class detected. Use high-contrast var(--text-secondary) or var(--text-muted) instead of raw gray or low opacity.",severity:"error"})),We.test(s)&&!u&&!s.includes("no \u{1F680}")&&!s.includes("Banned")&&r.push({file:a,rule:"slop/no-emoji-icons",line:i,snippet:d,message:"Emoji character used as UI icon detected",severity:"error"}),Qe.test(s)&&!u&&!f&&(l++,c||(c=i,m=d))}l>3&&r.push({file:a,rule:"slop/excessive-uppercase-labels",line:c,snippet:m,message:`Excessive uppercase micro-labels detected (${l} occurrences, maximum allowed is 3). Cure UPPERCASE MICRO-LABEL disease by using normal sentence case.`,severity:"warning"})}import{fileURLToPath as nt}from"url";var z=new rt;z.name("agent-design-skills").description("v1.1 CLI and design-governance registry eliminating AI UI slop and enforcing cross-page unity").version("1.1.1");async function Se(e){let t=[];return(await q.pathExists(E.resolve(e,".agent"))||await q.pathExists(E.resolve(e,".agents")))&&t.push("antigravity"),await q.pathExists(E.resolve(e,".cursor"))&&t.push("cursor"),(await q.pathExists(E.resolve(e,"CLAUDE.md"))||await q.pathExists(E.resolve(e,"AGENTS.md")))&&t.push("claude-codex"),t.length>0?t:["antigravity"]}var st=[{value:"dark-obsidian-technical",label:"Dark Obsidian Technical",hint:"1px hairlines, carbon hue 250, forensic developer/settlement console"},{value:"swiss-typographic-grid",label:"Swiss Typographic Grid",hint:"Light, exposed 1px grid lines, Cabinet Grotesk / Space Grotesk"},{value:"kinetic-industrial-mono",label:"Kinetic Industrial Mono",hint:"Dark, tabular telemetry, JetBrains Mono, amber accents"},{value:"bento-modular-system",label:"Bento Modular System",hint:"Adaptive 12-col bento cells, Satoshi / General Sans"},{value:"spatial-glass-visionos",label:"Spatial Glass VisionOS",hint:"Translucent optical blur, Outfit / DM Sans, specular highlights"},{value:"editorial-serif-paper",label:"Editorial Serif Paper",hint:"Warm bone paper, broadsheet typography, high-craft publication"},{value:"quiet-luxury-atelier",label:"Quiet Luxury Atelier",hint:"Whisper-quiet prestige, Cormorant Garamond / DM Sans, warm ivory"},{value:"warm-artisan-craft",label:"Warm Artisan Craft",hint:"Earthy linen, Fraunces / Cabinet Grotesk, terracotta accents"},{value:"japanese-minimal-zen",label:"Japanese Minimal Zen",hint:"Ma negative space, Noto Serif Display / Work Sans, washi mist"},{value:"scandinavian-warm-minimal",label:"Scandinavian Warm Minimal",hint:"Oat/birch canvas, Familjen Grotesk / DM Sans, spruce accents"},{value:"neo-brutalism",label:"Neo-Brutalist Studio",hint:"Hard 2px borders, stark offset shadows, raw tactile accents"},{value:"retro-tactile-analog",label:"Retro Tactile Analog",hint:"Physical bevels, Space Mono / DM Sans, Teenage Engineering vibe"},{value:"y2k-acid-cyber",label:"Y2K Acid Cyber",hint:"Electric chartreuse on pitch black, VT323 / Syne Mono"},{value:"playful-clay-consumer",label:"Playful Clay Consumer",hint:"Tactile dual-layer shadows, Bricolage Grotesque / Plus Sans"},{value:"vaporwave-crt-terminal",label:"Vaporwave CRT Terminal",hint:"Phosphorescent cyan & magenta on indigo void, scanlines"},{value:"high-trust-fintech-clarity",label:"High-Trust Fintech Clarity",hint:"Enterprise navy, Sora / Public Sans, tabular numbers"},{value:"clinical-biotech-precision",label:"Clinical Biotech Precision",hint:"Sterile lab white, Geist / Space Mono, cold cyan"},{value:"civic-govtech-accessible",label:"Civic Govtech Accessible",hint:"WCAG AAA contrast, Atkinson Hyperlegible / DM Sans"}];z.command("init",{isDefault:!0}).description("Scaffold a design token contract, starter kit, and agent governance rules").option("-a, --agents <agents>",'Target agents (comma-separated or "all": antigravity, cursor, claude-codex, web-builders)').option("-f, --fast","Fast mode with sensible defaults (dark-obsidian-technical, antigravity)").option("-t, --archetype <archetype>","Canonical archetype ID").option("-s, --starter-kit <kit>","Pre-baked starter kit: dashboard, landing-waitlist, mobile-app, data-tool").option("-m, --mode <mode>","Installation mode: modular or single","modular").option("-F, --fonts <mode>",'Font selection mode: A, B, C, keep, or comma-separated "Display,Sans,Mono"').option("-d, --dir <dir>","Target directory",".").option("-y, --yes","Accept defaults without interactive prompts").action(async e=>{let t=E.resolve(process.cwd(),e.dir||"."),r=E.basename(t)||"my-project",a,g;if(e.fonts){let i=e.fonts.trim(),d=i.toUpperCase();if(d==="A"||d==="B"||d==="C")a=d;else if(i.toLowerCase()==="keep")a="keep";else if(i.includes(",")){let u=i.split(",").map(v=>v.trim());a="custom",g={display:u[0]||void 0,sans:u[1]||void 0,mono:u[2]||void 0,source:"user"}}else a="custom",g={display:i,sans:i,source:"user"}}let f=null;if(e.agents&&(e.agents.toLowerCase()==="all"?f=["antigravity","cursor","claude-codex","web-builders"]:f=e.agents.split(",").map(i=>i.trim())),e.fast||e.yes){k.intro(`${w.bgWhite(w.black(" \u26A1 agent-design-skills "))} ${w.dim("v1.1.0 [EXPRESS MODE]")}`);let i=k.spinner();i.start(`Compiling design system in ${t}...`);let d=e.starterKit||"dashboard",u=f||await Se(t),v={projectName:r,targetDir:t,agents:u,archetype:e.archetype||"dark-obsidian-technical",feeling:"urgent-precise",radius:"subtle",blur:"subtle-frost",mode:e.mode||"modular",starterKit:d,fontMode:a,fontOverride:g,customDirection:"Needs to feel like a high-precision developer settlement console, crisp 1px hairlines, zero marketing fluff",productBrief:"High-precision operational workspace and data reconciliation platform",fast:!0},b=await se(v);i.stop(`Scaffolded ${b.createdFiles.length} files successfully.`);for(let S of b.createdFiles)console.log(` ${w.green("\u2714")} ${w.dim(E.relative(t,S))}`);k.outro(w.green(`\u2728 Initialization complete for ${v.agents.join(", ")}. Token contract & starter preview active.`));return}console.clear(),k.intro(`${w.bgWhite(w.black(" \u26A1 agent-design-skills "))} ${w.dim("v1.1.0")}`);let y=await Se(t),o=await Z(t),n=await k.group({agents:()=>f?Promise.resolve(f):k.multiselect({message:"Which AI coding agent(s) are you using?",options:[{value:"antigravity",label:"Antigravity",hint:".agent/rules/ & .agent/skills/"},{value:"cursor",label:"Cursor",hint:".cursor/rules/"},{value:"claude-codex",label:"Codex / Claude Code",hint:"CLAUDE.md / AGENTS.md"},{value:"web-builders",label:"Web Builders (v0 / Bolt / Lovable)",hint:"DESIGN-PROMPT.md"}],initialValues:y,required:!0}),archetype:()=>e.archetype?Promise.resolve(e.archetype):k.select({message:"Choose a human-crafted design archetype:",options:st}),typography:async({results:i})=>{if(a||g)return a||"custom";let d=i.archetype||e.archetype||"dark-obsidian-technical",u=V[d]||V["dark-obsidian-technical"],v=[];if(o&&(o.display||o.sans||o.mono)){let b=[o.display,o.sans,o.mono].filter(Boolean).map(P).join(" / ");v.push({value:"keep",label:"Keep existing project fonts",hint:b})}return v.push({value:"A",label:`Pairing A (Default): ${u.A.display} + ${u.A.sans} + ${u.A.mono}`,hint:"Archetype primary pairing"},{value:"B",label:`Pairing B: ${u.B.display} + ${u.B.sans} + ${u.B.mono}`,hint:"Alternative character"},{value:"C",label:`Pairing C: ${u.C.display} + ${u.C.sans} + ${u.C.mono}`,hint:"Alternative character"},{value:"custom",label:"Custom font families (specify Display, Sans, Mono)",hint:"Type custom Google Fonts or Fontshare families"}),k.select({message:"Select typography & font pairing:",options:v,initialValue:o&&(o.display||o.sans||o.mono)?"keep":"A"})},starterKit:()=>k.select({message:"Choose a token-wired starter kit preview:",options:[{value:"dashboard",label:"High-Density Workspace Dashboard",hint:"Workspace shell, summary strip, data table, drawer"},{value:"landing-waitlist",label:"Editorial Landing & Waitlist",hint:"Narrative hero, live preview artifact, waitlist form"},{value:"mobile-app",label:"Mobile-First Application",hint:"375px\u2013430px frame, thumb nav, bottom sheet"},{value:"data-tool",label:"Split-Pane Query Explorer & Tool",hint:"Split query/inspector, \u2318K command bar, tabular nums"},{value:"none",label:"None (Blank Token Contract)",hint:"Pure tokens and governance rules only"}]}),mode:()=>k.select({message:"Installation mode for skills & rules:",options:[{value:"modular",label:"Modular Skills (Recommended)",hint:"Core rules + task-scoped reference guides"},{value:"single",label:"Single Master File",hint:"Combined master reference file"}]}),feeling:()=>k.select({message:"Select sensory motion & timing vector:",options:[{value:"urgent-precise",label:"Urgent & Precise (110ms / 180ms)",hint:"Forensic, snappy, zero bounce"},{value:"calm",label:"Calm & Measured (140ms / 240ms)",hint:"Literary ease, smooth"},{value:"playful-tactile",label:"Playful & Tactile (80ms / 150ms)",hint:"Punchy press states"},{value:"authoritative",label:"Authoritative (120ms / 200ms)",hint:"Institutional stability"}]}),radius:()=>k.select({message:"Select geometric corner radius scale:",options:[{value:"subtle",label:"Subtle (6px outer / 4px inner)",hint:"Standard technical scale"},{value:"sharp",label:"Sharp (0px outer / 0px inner)",hint:"Zero radius / architectural"},{value:"medium",label:"Medium (10px outer / 6px inner)",hint:"Soft modern SaaS"},{value:"high",label:"High (16px outer / 10px inner)",hint:"Friendly consumer scale"},{value:"pill",label:"Pill (9999px)",hint:"Capsule components"}]}),blur:()=>k.select({message:"Select surface blur depth:",options:[{value:"subtle-frost",label:"Subtle Frost (8px)",hint:"Hairline glass backdrops"},{value:"flat",label:"Flat (0px)",hint:"Zero blur, pure solid fills"},{value:"deep-glass",label:"Deep Glass (20px)",hint:"Heavy frosted glass"}]}),customDirection:()=>k.text({message:"Custom Creative Direction & Anti-Drift Mandate (Section 0):",placeholder:"Needs to feel like a high-precision developer settlement console, crisp 1px hairlines, zero marketing fluff",initialValue:"Needs to feel like a high-precision developer settlement console, crisp 1px hairlines, zero marketing fluff"})},{onCancel:()=>{k.cancel("Setup cancelled."),process.exit(0)}}),l=a||n.typography||"A",c=g;if(n.typography==="keep"&&!c&&o)c=o;else if(n.typography==="custom"&&!c){let i=await k.text({message:'Enter --font-display family (e.g. "Cabinet Grotesk" or "Cormorant Garamond"):',placeholder:"Sora",validate:v=>v?.trim()?void 0:"Display font family is required"});k.isCancel(i)&&(k.cancel("Setup cancelled."),process.exit(0));let d=await k.text({message:'Enter --font-sans family (e.g. "Instrument Sans" or "Public Sans"):',placeholder:"Instrument Sans",validate:v=>v?.trim()?void 0:"Sans font family is required"});k.isCancel(d)&&(k.cancel("Setup cancelled."),process.exit(0));let u=await k.text({message:'Enter --font-mono family (e.g. "Geist Mono" or "JetBrains Mono"):',placeholder:"JetBrains Mono",validate:v=>v?.trim()?void 0:"Mono font family is required"});k.isCancel(u)&&(k.cancel("Setup cancelled."),process.exit(0)),c={display:i.trim(),sans:d.trim(),mono:u.trim(),source:"user"}}let m=k.spinner();m.start("Compiling tokens and governance contract...");let p={projectName:r,targetDir:t,agents:n.agents||f||y,archetype:n.archetype,feeling:n.feeling,radius:n.radius,blur:n.blur,fontMode:l,fontOverride:c,mode:n.mode,starterKit:n.starterKit!=="none"?n.starterKit:void 0,customDirection:n.customDirection},s=await se(p);m.stop(`Compiled ${s.createdFiles.length} files successfully.`);for(let i of s.createdFiles)console.log(` ${w.green("\u2714")} ${w.dim(E.relative(t,i))}`);k.outro(`${w.green("\u2714")} Initialized ${w.bold(p.archetype)} for ${w.cyan(p.agents.join(", "))}`)});z.command("lint [dir]").description("Lint directory for hardcoded colors, AI slop, banned copy, and hash freeze integrity").action(async e=>{let t=E.resolve(process.cwd(),e||".");console.log(`${w.bgBlue(w.black(" LINT "))} Scanning ${w.bold(t)}...
|
|
608
|
-
`);let
|
|
609
|
-
`),process.exit(0);else{console.log(`${
|
|
610
|
-
`);for(let a of
|
|
611
|
-
`),process.exit(1)}});z.command("freeze [dir]").description("Calculate SHA-256 hashes of design tokens and rules, creating .design-skills.lock").action(async e=>{let t=
|
|
612
|
-
Created ${
|
|
614
|
+
- Log non-blocking enhancements into \`DESIGN.md\` Section 8 (**Polish Backlog**) rather than burning turns on infinite micro-tweaks.`}async function se(e){let{targetDir:t,agents:s}=e;if(await D.ensureDir(t),!e.fontOverride){let p=await Z(t);p&&(!e.fontMode||e.fontMode==="keep")&&(e={...e,fontMode:"keep",fontOverride:p})}let a=[],{css:g,json:f}=le(e),y=I.resolve(t,"tokens.css"),i=I.resolve(t,"tokens.json");await D.writeFile(y,g,"utf-8"),a.push(y),await D.writeJSON(i,f,{spaces:2}),a.push(i);let n=I.resolve(t,"DESIGN.md"),c;await D.pathExists(n)&&(c=await D.readFile(n,"utf-8"));let d=ce(e,c);if(await D.writeFile(n,d,"utf-8"),a.push(n),e.starterKit){let p=await Ue(),v=I.resolve(p,"starter-kits",e.starterKit,"template.html");if(await D.pathExists(v)){let r=I.resolve(t,"starter-preview.html");await D.copy(v,r),a.push(r)}}let m=He(e);for(let p of s)if(p==="antigravity"){let v=await pe(t,e,m);a.push(...v)}else if(p==="cursor"){let v=await ue(t,e,m);a.push(...v)}else if(p==="claude-codex"){let v=await ge(t,e,m);a.push(...v)}else if(p==="web-builders"){let v=await fe(t,e,m);a.push(v)}return{createdFiles:a}}import ke from"fs-extra";import J from"pathe";import R from"fs-extra";import K from"pathe";import je from"crypto";var ne=".design-skills.lock";async function ye(e){let t=await R.readFile(e,"utf-8");return je.createHash("sha256").update(t).digest("hex")}async function ve(e){let t=["tokens.css","tokens.json","DESIGN.md","DESIGN-PROMPT.md",".agent/rules/design-core.md",".agents/rules/design-core.md",".agent/skills/design-system/SKILL.md",".agents/skills/design-system/SKILL.md",".cursor/rules/00-design-core.mdc",".cursor/rules/design-core.mdc","CLAUDE.md","AGENTS.md"],s={};for(let f of t){let y=K.resolve(e,f);await R.pathExists(y)&&(s[f]=await ye(y))}let a={version:"1.1.0",generatedAt:new Date().toISOString(),hashes:s},g=K.resolve(e,ne);return await R.writeJSON(g,a,{spaces:2}),a}async function be(e){let t=K.resolve(e,ne);return await R.pathExists(t)?(await R.remove(t),!0):!1}async function we(e){let t=K.resolve(e,ne);if(!await R.pathExists(t))return{locked:!1,valid:!0,modifiedFiles:[]};let s=await R.readJSON(t),a=[];for(let[g,f]of Object.entries(s.hashes)){let y=K.resolve(e,g);if(!await R.pathExists(y)){a.push(`${g} (deleted)`);continue}await ye(y)!==f&&a.push(g)}return{locked:!0,valid:a.length===0,modifiedFiles:a}}var _e=["hover to reveal","click here","smooth animations","built with react","powered by react","ai-powered","supercharge","one-click","magical","say goodbye to"],Ve=/[\u{1F300}-\u{1F5FF}\u{1F600}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{1F900}-\u{1F9FF}\u{1FA70}-\u{1FAFF}]/u,We=/#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{4}|[0-9a-fA-F]{3})(?=[;,\s)'"`}\]]|$)/g,Ke=/\b(?:rgba?|hsla?|oklch)\s*\(/i,qe=/(?:from-purple|to-pink|from-indigo.*to-purple|from-cyan.*to-purple|radial-gradient\([^)]*(?:purple|#7[0-9a-f]{5}|oklch\([^)]*290\)))/i,Ye=/\[(PRO|BETA|v\d+\.\d+)\]/i,Ze=/\b(SUB-\d+MS|TEMPORAL ENGINE|MASTER CHRONOMETER|CHRONO SYNC|LOCAL REFERENCE|\d+\s*FPS|EPOCH)\b/i,Je=/\b(NOW PLAYING|•\s*PLAYING|HD\s*1080P|4K\s*HDR|120\s*FPS|HI-RES\s*AUDIO|LIVE\s*CINEMATIC|BESTSELLER|HOT\s*SALE|LIMITED\s*TIME)\b/i,Xe=/\babsolute\b[^"']*\b(?:top-(?:1|2|3|4|5|6|8)|top-\[[^\]]+\])\b[^"']*\b(?:left|right)-(?:1|2|3|4|5|6|8)\b|\babsolute\b[^"']*\b(?:left|right)-(?:1|2|3|4|5|6|8)\b[^"']*\b(?:top-(?:1|2|3|4|5|6|8)|top-\[[^\]]+\])\b/i,Qe=/\b(rounded-full|uppercase|tracking-[a-z0-9_-]+|text-xs|badge|pill|chip)\b/i,et=/slashed-zero|font-feature-settings:[^;]*["']zero["']\s*1/i,tt=/class(?:Name)?=["'][^"']*\b(badge|pill|chip|tag-chip|status-badge|header-badge)\b[^"']*["']/i,at=/(?:class(?:Name)?=["'][^"']*\buppercase\b[^"']*\btracking-[^"']*["']|class(?:Name)?=["'][^"']*\btracking-[^"']*\buppercase\b[^"']*["']|\btext-transform:\s*uppercase\b[^;]*letter-spacing)/i,rt=/(?:\btext-\[(?:8|9|10|11)px\]|\bfont-size:\s*(?:8|9|10|11)px\b)/i,st=/\b(text-zinc-500|text-slate-500|text-gray-500|opacity-30|opacity-40)\b/i,nt=/https?:\/\/[^\s"'`]+\.(?:png|jpe?g|webp|avif|svg)(?:\?[^\s"'`]*)?|https?:\/\/(?:images\.)?unsplash\.com\/[^\s"'`]+/gi;function it(e){let t=e.match(/(?:premium_)?photo-[a-zA-Z0-9_-]+/i);return t?t[0].toLowerCase():e.split("?")[0].split("#")[0].toLowerCase()}async function xe(e){let t=[],s=0,a=await we(e);if(a.locked&&!a.valid)for(let y of a.modifiedFiles)t.push({file:y,rule:"freeze/hash-integrity",line:1,snippet:y,message:`File was modified without running unfreeze: ${y}`,severity:"error"});let g=[".html",".css",".js",".ts",".jsx",".tsx",".vue",".svelte"];async function f(y){let i=await ke.readdir(y,{withFileTypes:!0});for(let n of i){let c=J.resolve(y,n.name);if(n.isDirectory()){if(["node_modules",".git","dist",".gemini",".turbo"].includes(n.name))continue;await f(c)}else if(n.isFile()){let d=J.extname(n.name).toLowerCase();g.includes(d)&&(await ot(c,e,t),s++)}}}return await f(e),{targetDir:e,violations:t,filesScanned:s,passed:t.filter(y=>y.severity==="error").length===0}}async function ot(e,t,s){let a=J.relative(t,e),g=J.basename(e)==="tokens.css",f=e.includes(".agent")||e.includes(".cursor")||e.includes("DESIGN.md")||e.includes("README.md")||e.includes("core"),i=(await ke.readFile(e,"utf-8")).split(`
|
|
615
|
+
`),n=!1,c=0,d=0,m="",p=new Map;for(let v=0;v<i.length;v++){let r=i[v],l=v+1,o=r.trim();/<(?:header|nav)\b/i.test(r)&&(n=!0),/<\/(?:header|nav)>/i.test(r)&&(n=!1);let u=r.includes("/* @design-exception")||r.includes("/* @design-signature")||r.includes("// @design-exception")||r.includes("// @design-signature");if(!g&&!u){Ke.test(r)&&s.push({file:a,rule:"tokens/no-hardcoded-color-radius",line:l,snippet:o,message:"Hardcoded color function (rgb, hsl, oklch) found outside tokens.css without @design-exception",severity:"error"});let b=r.match(We);if(b)for(let C of b){let A=r.indexOf(C);A>0&&/[a-zA-Z0-9_-]/.test(r[A-1])||s.push({file:a,rule:"tokens/no-hardcoded-color-radius",line:l,snippet:o,message:`Hardcoded hex color '${C}' found outside tokens.css without @design-exception`,severity:"error"})}}r.includes("animate-ping")&&s.push({file:a,rule:"slop/no-animate-ping",line:l,snippet:o,message:'Banned attention-seeking animation "animate-ping" detected',severity:"error"}),qe.test(r)&&!u&&s.push({file:a,rule:"slop/no-ai-gradient",line:l,snippet:o,message:"Banned AI clich\xE9 gradient (purple/pink mesh) detected",severity:"error"});let x=r.toLowerCase();for(let b of _e)if(x.includes(b)&&!r.includes("rule")&&!r.includes("banned")){s.push({file:a,rule:"copy/banned-phrases-and-leakage",line:l,snippet:o,message:`Self-referential or marketing copy clich\xE9 detected: "${b}"`,severity:"error"});break}if(!r.includes("regex")&&!r.includes("banned")&&!r.includes("Banned")&&!r.includes("Rule")&&(/^\s*0[1-9]\s*\/\s*[A-Z]/.test(o)||/>?\s*0[1-9]\s*\/\s*[A-Z]/.test(r))&&s.push({file:a,rule:"copy/banned-phrases-and-leakage",line:l,snippet:o,message:'Numbered slash eyebrow (e.g. "01 / ...") detected above headings or in UI markup',severity:"error"}),n&&tt.test(r)&&!u&&!f&&s.push({file:a,rule:"slop/no-decorative-badges",line:l,snippet:o,message:"Banned decorative badge/pill/chip detected inside <header> or <nav>",severity:"error"}),!u&&!f&&!r.includes("rule")&&!r.includes("banned")&&(Ye.test(r)?s.push({file:a,rule:"slop/no-fake-telemetry-cosplay",line:l,snippet:o,message:"Fake product tier/version badge (e.g. [PRO v2.4], [BETA]) detected",severity:"error"}):Ze.test(r)&&s.push({file:a,rule:"slop/no-fake-telemetry-cosplay",line:l,snippet:o,message:"Fake hardware telemetry or sci-fi cosplay copy detected",severity:"error"})),!u&&!f&&!r.includes("rule")&&!r.includes("banned")&&!r.includes("ban")){let b=Je.test(r),C=Xe.test(r)&&Qe.test(r);(b||C)&&s.push({file:a,rule:"slop/no-image-corner-badges",line:l,snippet:o,message:b?"Banned media/product overlay badge text detected. Keep media uncluttered without floating corner status pills.":"Floating corner badge/pill overlay detected. Never place floating status pills on top of cards, media, or product images.",severity:"error"})}if(!u&&!f&&!r.includes("rule")&&!r.includes("banned")){let b=r.match(nt);if(b)for(let C of b){let A=it(C);if(p.has(A)){let P=p.get(A);s.push({file:a,rule:"data/no-duplicate-image-urls",line:l,snippet:o,message:`Duplicate image asset detected ("${A}", originally defined on line ${P}). Every distinct record in a UI dataset must have a unique visual asset/URL.`,severity:"warning"})}else p.set(A,l)}}et.test(r)&&!u&&!r.includes('"zero" 0')&&!g&&!f&&s.push({file:a,rule:"slop/no-slashed-zero",line:l,snippet:o,message:'Banned slashed-zero numeric styling detected. Use open-oval zeros with "zero" 0',severity:"error"}),!g&&!f&&!u&&(rt.test(r)&&s.push({file:a,rule:"a11y/no-micro-text",line:l,snippet:o,message:"Unreadable micro-text detected (< 13px). Maintain minimum 13px (0.8125rem) floor for human readability.",severity:"error"}),st.test(r)&&s.push({file:a,rule:"a11y/no-micro-text",line:l,snippet:o,message:"Low-contrast dim text class detected. Use high-contrast var(--text-secondary) or var(--text-muted) instead of raw gray or low opacity.",severity:"error"})),Ve.test(r)&&!u&&!r.includes("no \u{1F680}")&&!r.includes("Banned")&&s.push({file:a,rule:"slop/no-emoji-icons",line:l,snippet:o,message:"Emoji character used as UI icon detected",severity:"error"}),at.test(r)&&!u&&!f&&(c++,d||(d=l,m=o))}c>3&&s.push({file:a,rule:"slop/excessive-uppercase-labels",line:d,snippet:m,message:`Excessive uppercase micro-labels detected (${c} occurrences, maximum allowed is 3). Cure UPPERCASE MICRO-LABEL disease by using normal sentence case.`,severity:"warning"})}import{fileURLToPath as dt}from"url";var z=new lt;z.name("agent-design-skills").description("v1.1 CLI and design-governance registry eliminating AI UI slop and enforcing cross-page unity").version("1.1.2");async function Se(e){let t=[];return(await q.pathExists(F.resolve(e,".agent"))||await q.pathExists(F.resolve(e,".agents")))&&t.push("antigravity"),await q.pathExists(F.resolve(e,".cursor"))&&t.push("cursor"),(await q.pathExists(F.resolve(e,"CLAUDE.md"))||await q.pathExists(F.resolve(e,"AGENTS.md")))&&t.push("claude-codex"),t.length>0?t:["antigravity"]}var ct=[{value:"dark-obsidian-technical",label:"Dark Obsidian Technical",hint:"1px hairlines, carbon hue 250, forensic developer/settlement console"},{value:"swiss-typographic-grid",label:"Swiss Typographic Grid",hint:"Light, exposed 1px grid lines, Cabinet Grotesk / Space Grotesk"},{value:"kinetic-industrial-mono",label:"Kinetic Industrial Mono",hint:"Dark, tabular telemetry, JetBrains Mono, amber accents"},{value:"bento-modular-system",label:"Bento Modular System",hint:"Adaptive 12-col bento cells, Satoshi / General Sans"},{value:"spatial-glass-visionos",label:"Spatial Glass VisionOS",hint:"Translucent optical blur, Outfit / DM Sans, specular highlights"},{value:"editorial-serif-paper",label:"Editorial Serif Paper",hint:"Warm bone paper, broadsheet typography, high-craft publication"},{value:"quiet-luxury-atelier",label:"Quiet Luxury Atelier",hint:"Whisper-quiet prestige, Cormorant Garamond / DM Sans, warm ivory"},{value:"warm-artisan-craft",label:"Warm Artisan Craft",hint:"Earthy linen, Fraunces / Cabinet Grotesk, terracotta accents"},{value:"japanese-minimal-zen",label:"Japanese Minimal Zen",hint:"Ma negative space, Noto Serif Display / Work Sans, washi mist"},{value:"scandinavian-warm-minimal",label:"Scandinavian Warm Minimal",hint:"Oat/birch canvas, Familjen Grotesk / DM Sans, spruce accents"},{value:"neo-brutalism",label:"Neo-Brutalist Studio",hint:"Hard 2px borders, stark offset shadows, raw tactile accents"},{value:"retro-tactile-analog",label:"Retro Tactile Analog",hint:"Physical bevels, Space Mono / DM Sans, Teenage Engineering vibe"},{value:"y2k-acid-cyber",label:"Y2K Acid Cyber",hint:"Electric chartreuse on pitch black, VT323 / Syne Mono"},{value:"playful-clay-consumer",label:"Playful Clay Consumer",hint:"Tactile dual-layer shadows, Bricolage Grotesque / Plus Sans"},{value:"vaporwave-crt-terminal",label:"Vaporwave CRT Terminal",hint:"Phosphorescent cyan & magenta on indigo void, scanlines"},{value:"high-trust-fintech-clarity",label:"High-Trust Fintech Clarity",hint:"Enterprise navy, Sora / Public Sans, tabular numbers"},{value:"clinical-biotech-precision",label:"Clinical Biotech Precision",hint:"Sterile lab white, Geist / Space Mono, cold cyan"},{value:"civic-govtech-accessible",label:"Civic Govtech Accessible",hint:"WCAG AAA contrast, Atkinson Hyperlegible / DM Sans"}];z.command("init",{isDefault:!0}).description("Scaffold a design token contract, starter kit, and agent governance rules").option("-a, --agents <agents>",'Target agents (comma-separated or "all": antigravity, cursor, claude-codex, web-builders)').option("-f, --fast","Fast mode with sensible defaults (dark-obsidian-technical, antigravity)").option("-t, --archetype <archetype>","Canonical archetype ID").option("-s, --starter-kit <kit>","Pre-baked starter kit: dashboard, landing-waitlist, mobile-app, data-tool").option("-m, --mode <mode>","Installation mode: modular or single","modular").option("-F, --fonts <mode>",'Font selection mode: A, B, C, keep, or comma-separated "Display,Sans,Mono"').option("-d, --dir <dir>","Target directory",".").option("-y, --yes","Accept defaults without interactive prompts").action(async e=>{let t=F.resolve(process.cwd(),e.dir||"."),s=F.basename(t)||"my-project",a,g;if(e.fonts){let r=e.fonts.trim(),l=r.toUpperCase();if(l==="A"||l==="B"||l==="C")a=l;else if(r.toLowerCase()==="keep")a="keep";else if(r.includes(",")){let o=r.split(",").map(u=>u.trim());a="custom",g={display:o[0]||void 0,sans:o[1]||void 0,mono:o[2]||void 0,source:"user"}}else a="custom",g={display:r,sans:r,source:"user"}}let f=null;if(e.agents&&(e.agents.toLowerCase()==="all"?f=["antigravity","cursor","claude-codex","web-builders"]:f=e.agents.split(",").map(r=>r.trim())),e.fast||e.yes){w.intro(`${k.bgWhite(k.black(" \u26A1 agent-design-skills "))} ${k.dim("v1.1.0 [EXPRESS MODE]")}`);let r=w.spinner();r.start(`Compiling design system in ${t}...`);let l=e.starterKit||"dashboard",o=f||await Se(t),u={projectName:s,targetDir:t,agents:o,archetype:e.archetype||"dark-obsidian-technical",feeling:"urgent-precise",radius:"subtle",blur:"subtle-frost",mode:e.mode||"modular",starterKit:l,fontMode:a,fontOverride:g,customDirection:"Needs to feel like a high-precision developer settlement console, crisp 1px hairlines, zero marketing fluff",productBrief:"High-precision operational workspace and data reconciliation platform",fast:!0},x=await se(u);r.stop(`Scaffolded ${x.createdFiles.length} files successfully.`);for(let b of x.createdFiles)console.log(` ${k.green("\u2714")} ${k.dim(F.relative(t,b))}`);w.outro(k.green(`\u2728 Initialization complete for ${u.agents.join(", ")}. Token contract & starter preview active.`));return}console.clear(),w.intro(`${k.bgWhite(k.black(" \u26A1 agent-design-skills "))} ${k.dim("v1.1.0")}`);let y=await Se(t),i=await Z(t),n=await w.group({agents:()=>f?Promise.resolve(f):w.multiselect({message:"Which AI coding agent(s) are you using?",options:[{value:"antigravity",label:"Antigravity",hint:".agent/rules/ & .agent/skills/"},{value:"cursor",label:"Cursor",hint:".cursor/rules/"},{value:"claude-codex",label:"Codex / Claude Code",hint:"CLAUDE.md / AGENTS.md"},{value:"web-builders",label:"Web Builders (v0 / Bolt / Lovable)",hint:"DESIGN-PROMPT.md"}],initialValues:y,required:!0}),archetype:()=>e.archetype?Promise.resolve(e.archetype):w.select({message:"Choose a human-crafted design archetype:",options:ct}),typography:async({results:r})=>{if(a||g)return a||"custom";let l=r.archetype||e.archetype||"dark-obsidian-technical",o=_[l]||_["dark-obsidian-technical"],u=[];if(i&&(i.display||i.sans||i.mono)){let x=[i.display,i.sans,i.mono].filter(Boolean).map(T).join(" / ");u.push({value:"keep",label:"Keep existing project fonts",hint:x})}return u.push({value:"A",label:`Pairing A (Default): ${o.A.display} + ${o.A.sans} + ${o.A.mono}`,hint:"Archetype primary pairing"},{value:"B",label:`Pairing B: ${o.B.display} + ${o.B.sans} + ${o.B.mono}`,hint:"Alternative character"},{value:"C",label:`Pairing C: ${o.C.display} + ${o.C.sans} + ${o.C.mono}`,hint:"Alternative character"},{value:"custom",label:"Custom font families (specify Display, Sans, Mono)",hint:"Type custom Google Fonts or Fontshare families"}),w.select({message:"Select typography & font pairing:",options:u,initialValue:i&&(i.display||i.sans||i.mono)?"keep":"A"})},starterKit:()=>w.select({message:"Choose a token-wired starter kit preview:",options:[{value:"dashboard",label:"High-Density Workspace Dashboard",hint:"Workspace shell, summary strip, data table, drawer"},{value:"landing-waitlist",label:"Editorial Landing & Waitlist",hint:"Narrative hero, live preview artifact, waitlist form"},{value:"mobile-app",label:"Mobile-First Application",hint:"375px\u2013430px frame, thumb nav, bottom sheet"},{value:"data-tool",label:"Split-Pane Query Explorer & Tool",hint:"Split query/inspector, \u2318K command bar, tabular nums"},{value:"none",label:"None (Blank Token Contract)",hint:"Pure tokens and governance rules only"}]}),mode:()=>w.select({message:"Installation mode for skills & rules:",options:[{value:"modular",label:"Modular Skills (Recommended)",hint:"Core rules + task-scoped reference guides"},{value:"single",label:"Single Master File",hint:"Combined master reference file"}]}),feeling:()=>w.select({message:"Select sensory motion & timing vector:",options:[{value:"urgent-precise",label:"Urgent & Precise (110ms / 180ms)",hint:"Forensic, snappy, zero bounce"},{value:"calm",label:"Calm & Measured (140ms / 240ms)",hint:"Literary ease, smooth"},{value:"playful-tactile",label:"Playful & Tactile (80ms / 150ms)",hint:"Punchy press states"},{value:"authoritative",label:"Authoritative (120ms / 200ms)",hint:"Institutional stability"}]}),radius:()=>w.select({message:"Select geometric corner radius scale:",options:[{value:"subtle",label:"Subtle (6px outer / 4px inner)",hint:"Standard technical scale"},{value:"sharp",label:"Sharp (0px outer / 0px inner)",hint:"Zero radius / architectural"},{value:"medium",label:"Medium (10px outer / 6px inner)",hint:"Soft modern SaaS"},{value:"high",label:"High (16px outer / 10px inner)",hint:"Friendly consumer scale"},{value:"pill",label:"Pill (9999px)",hint:"Capsule components"}]}),blur:()=>w.select({message:"Select surface blur depth:",options:[{value:"subtle-frost",label:"Subtle Frost (8px)",hint:"Hairline glass backdrops"},{value:"flat",label:"Flat (0px)",hint:"Zero blur, pure solid fills"},{value:"deep-glass",label:"Deep Glass (20px)",hint:"Heavy frosted glass"}]}),customDirection:()=>w.text({message:"Custom Creative Direction & Anti-Drift Mandate (Section 0):",placeholder:"Needs to feel like a high-precision developer settlement console, crisp 1px hairlines, zero marketing fluff",initialValue:"Needs to feel like a high-precision developer settlement console, crisp 1px hairlines, zero marketing fluff"})},{onCancel:()=>{w.cancel("Setup cancelled."),process.exit(0)}}),c=a||n.typography||"A",d=g;if(n.typography==="keep"&&!d&&i)d=i;else if(n.typography==="custom"&&!d){let r=await w.text({message:'Enter --font-display family (e.g. "Cabinet Grotesk" or "Cormorant Garamond"):',placeholder:"Sora",validate:u=>u?.trim()?void 0:"Display font family is required"});w.isCancel(r)&&(w.cancel("Setup cancelled."),process.exit(0));let l=await w.text({message:'Enter --font-sans family (e.g. "Instrument Sans" or "Public Sans"):',placeholder:"Instrument Sans",validate:u=>u?.trim()?void 0:"Sans font family is required"});w.isCancel(l)&&(w.cancel("Setup cancelled."),process.exit(0));let o=await w.text({message:'Enter --font-mono family (e.g. "Geist Mono" or "JetBrains Mono"):',placeholder:"JetBrains Mono",validate:u=>u?.trim()?void 0:"Mono font family is required"});w.isCancel(o)&&(w.cancel("Setup cancelled."),process.exit(0)),d={display:r.trim(),sans:l.trim(),mono:o.trim(),source:"user"}}let m=w.spinner();m.start("Compiling tokens and governance contract...");let p={projectName:s,targetDir:t,agents:n.agents||f||y,archetype:n.archetype,feeling:n.feeling,radius:n.radius,blur:n.blur,fontMode:c,fontOverride:d,mode:n.mode,starterKit:n.starterKit!=="none"?n.starterKit:void 0,customDirection:n.customDirection},v=await se(p);m.stop(`Compiled ${v.createdFiles.length} files successfully.`);for(let r of v.createdFiles)console.log(` ${k.green("\u2714")} ${k.dim(F.relative(t,r))}`);w.outro(`${k.green("\u2714")} Initialized ${k.bold(p.archetype)} for ${k.cyan(p.agents.join(", "))}`)});z.command("lint [dir]").description("Lint directory for hardcoded colors, AI slop, banned copy, and hash freeze integrity").action(async e=>{let t=F.resolve(process.cwd(),e||".");console.log(`${k.bgBlue(k.black(" LINT "))} Scanning ${k.bold(t)}...
|
|
616
|
+
`);let s=await xe(t);if(s.violations.length===0)console.log(`${k.green("\u2714 Pass:")} Scanned ${s.filesScanned} files. Zero design slop or token contract violations found!
|
|
617
|
+
`),process.exit(0);else{console.log(`${k.red("\u2716 Violations detected:")} (${s.violations.length} total)
|
|
618
|
+
`);for(let a of s.violations){let g=a.severity==="error"?k.bgRed(k.black(" ERR ")):k.bgYellow(k.black(" WARN "));console.log(`${g} ${k.bold(a.file)}:${a.line} [${k.cyan(a.rule)}]`),console.log(` ${k.dim(a.message)}`),a.snippet&&console.log(` ${k.dim(">")} ${a.snippet.slice(0,80)}`),console.log("")}console.log(`${k.red("Lint failed.")} Please resolve all errors or annotate with /* @design-exception: [reason] */.
|
|
619
|
+
`),process.exit(1)}});z.command("freeze [dir]").description("Calculate SHA-256 hashes of design tokens and rules, creating .design-skills.lock").action(async e=>{let t=F.resolve(process.cwd(),e||"."),s=w.spinner();s.start(`Freezing design contract in ${t}...`);let a=await ve(t);s.stop(`Freeze complete. Locked ${Object.keys(a.hashes).length} files.`);for(let[g,f]of Object.entries(a.hashes))console.log(` ${k.green("\u{1F512}")} ${g} ${k.dim(`(${f.slice(0,12)}...)`)}`);console.log(`
|
|
620
|
+
Created ${k.bold(".design-skills.lock")}. Modifications will fail lint until unfreeze is run.`)});z.command("unfreeze [dir]").description("Remove .design-skills.lock to allow modifying design tokens and rules").action(async e=>{let t=F.resolve(process.cwd(),e||"."),s=await be(t);console.log(s?`${k.green("\u2714")} Removed ${k.bold(".design-skills.lock")}. Design files are now unlocked for editing.`:`${k.yellow("\u2139")} No active .design-skills.lock found in ${t}.`)});var pt=!!(process.argv[1]&&process.argv[1]!=="[eval]"&&(F.resolve(process.argv[1])===F.resolve(dt(import.meta.url))||process.argv[1].endsWith("index.js")||process.argv[1].endsWith("agent-design-skills")||process.argv[1].endsWith("design-skills")));pt&&z.parse();export{se as compileDesignSystem,ve as freezeProject,xe as lintDirectory,be as unfreezeProject};
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ Generative models produce predictable UI clichés that compromise professional c
|
|
|
19
19
|
| **Glowing Outlines** | Neon borders with `box-shadow: 0 0 15px rgba(120, 0, 255, 0.5)` | Crisp 1px borders (`var(--border-hairline)`) with specular top highlights (`var(--highlight-specular)`) |
|
|
20
20
|
| **Floating Badges** | Pill chips containing `"✨ AI-Powered"`, `"⚡ Supercharged"`, or `"Magic"` | Informative technical status pills referencing actual system state (e.g., `MERKLE LOG VERIFIED`) |
|
|
21
21
|
| **Card & Header Badges** | Pill badges, status chips, or uppercase tag boxes inside app headers, navbars, hero sections, or card headers (e.g., `PRO v2.4`, `STABLE`, `SUB-10MS`, `60 FPS`) | Cards must use plain text headings or no header at all. Tags/badges are ONLY permitted inside repeating data table cells or list rows to indicate item-level record status (strictly max 1 badge per row) |
|
|
22
|
+
| **Media & Image Corner Badges** | Floating `position: absolute` top-left or top-right status pills, tier tags, or promo badges on images/videos/art/products (e.g., `• PLAYING`, `NOW PLAYING`, `HD 1080P`, `4K HDR`, `LIVE`, `NEW`, `BESTSELLER`, `FEATURED`, `HOT`, `IN STOCK`) | Keep media completely uncluttered. For active playback, use a single centered play/pause icon overlay or a quiet row indicator—never a corner text pill. For product/content metadata, render clean plain text (`var(--text-secondary)`) below the image alongside title/price. Only permitted overlay: quiet bottom-right duration timestamp (`3:51`) or single subtle top-right hover icon |
|
|
22
23
|
| **Nested Bordered Cards (Box-in-a-Box)** | Nesting smaller bordered cards inside a bordered card container (e.g., sub-cards trapped inside a parent card) | Choose ONE container level: Grouped panel with borderless rows divided ONLY by a quiet 1px line (`border-bottom: 1px solid var(--border-hairline)`), or open canvas grid. Unbox hero elements directly onto canvas |
|
|
23
24
|
| **Empty-Space Panic Widgets** | Inventing fake progress bars, format tags, or telemetry to fill empty vertical space | Allow asymmetrical columns and breathing whitespace (`align-items: start`). Whitespace is a luxury feature, never a bug to fill with widgets |
|
|
24
25
|
| **Fake Brand & Telemetry Cosplay** | Inventing fake brand names, fake tier badges (`[PRO v2.4]`, `[BETA]`), fake hardware telemetry (`60 FPS`, `SUB-10MS`), and unrequested Unix `EPOCH` readouts | Focused, professional software copy designed by domain experts without sci-fi roleplay or hardware cosplay |
|
|
@@ -30,6 +31,17 @@ Generative models produce predictable UI clichés that compromise professional c
|
|
|
30
31
|
| **Fake Status Dots** | Green/amber/red static colored dots in headers or footers as decorative accents | Colored status dots (static or animated) are banned unless wired to a real, user-toggleable connection state |
|
|
31
32
|
| **Emoji Icons** | Using emojis (🚀, 💡, 🔥, ✨, 🧠, ⚡) inside buttons, cards, or titles | Crisp inline SVGs or clean monospaced characters from `var(--font-mono)` |
|
|
32
33
|
| **Floating Orbs** | Blurred colored circles floating in the background without layout purpose | Grounded, structured architectural grid surfaces aligned to `--container-max` |
|
|
34
|
+
| **Duplicate Sample Asset URLs** | Copy-pasting the exact same image/avatar URL across multiple mock records | Every distinct record in a UI dataset must have a unique visual asset/URL — never reuse the exact same image URL across two different records |
|
|
35
|
+
|
|
36
|
+
### Clean Media & Artwork Law (Never Overlay Corner Status Pills on Images, Artwork, or Video Thumbnails)
|
|
37
|
+
1. **Keep Media Uncluttered:** NEVER place floating `position: absolute` top-left or top-right status pills, tier tags, or promotional badges on top of album art, video thumbnails, avatars, or e-commerce product photography (e.g., ban `• PLAYING`, `NOW PLAYING`, `HD 1080P`, `4K HDR`, `LIVE`, `NEW`, `BESTSELLER`, `FEATURED`, `HOT`, `IN STOCK`).
|
|
38
|
+
2. **How to Show Active or Metadata States Instead:**
|
|
39
|
+
- **Active Media / Playback:** Use a single centered icon overlay (Play/Pause/Equalizer) on the thumbnail or a quiet indicator inside the text row—never a corner text pill (`• PLAYING`).
|
|
40
|
+
- **Product / Content Metadata:** For tags like `"New Arrival"`, `"Limited Edition"`, or discounts, render them as clean, quiet plain text (`var(--text-secondary)`) below the image alongside the title/price—never as a colored sticker slapped onto the corner of the photograph.
|
|
41
|
+
- **Only Permitted Media Overlay:** A plain bottom-right numeric video duration timestamp (`3:51`) or a single subtle top-right icon action (like a quiet heart/bookmark icon on hover).
|
|
42
|
+
|
|
43
|
+
### Universal Asset Uniqueness in Sample Data
|
|
44
|
+
- **Unique Assets Per Record:** Every distinct record in a UI dataset must have a unique visual asset/URL (e.g., distinct Unsplash photo IDs for different avatars, albums, products, or articles) — never lazily duplicate or copy-paste the exact same image URL across multiple records in sample data fixtures.
|
|
33
45
|
|
|
34
46
|
---
|
|
35
47
|
|
|
@@ -103,8 +103,15 @@ Every generated screen must respect these strict viewport budgets:
|
|
|
103
103
|
- **Empty-State Handoff:** When a data view has zero records, the table controls hide and the empty-state container absorbs the single primary CTA.
|
|
104
104
|
- **Animation Budget ($\le 2$):** No more than 2 decorative animated elements may be active simultaneously in the viewport. `[aria-busy="true"]` loading skeletons are functional and exempt.
|
|
105
105
|
- **Metric Strip Architecture:** Strictly ban 3 equal-width stat boxes in a row. Workspaces must use an inline horizontal metric strip with 1px vertical hairlines (`var(--border-hairline)`) or an asymmetric 2-pane split.
|
|
106
|
+
- **Universal Container Cardinality & Overview Row Discipline (Match Data Slice to Container Intent):** In overview screens, summary sections, or any section with directional navigation (`< >` / `View all`), constrain the rendered items to a **single row** that matches the grid column count (e.g., `.slice(0, columns)` or a single-row `flex overflow-x-auto` track). Never dump an entire 10–20 item mock array into a summary shelf causing accidental multi-row walls of cards; reserve multi-row wrapping strictly for dedicated full-index or catalog views.
|
|
106
107
|
- **Context Boundary (Operational vs. Marketing):** Active app consoles must render live operational data (batch volume, unreconciled variance, pending row count). Never embed static marketing or compliance statements (e.g. SOC2 certifications or throughput capacity claims) inside workspace views.
|
|
107
108
|
- **Badge & Indicator Discipline (Zero Unrequested Badges Law):** NEVER place pill badges, status chips, or uppercase tag boxes inside app headers, navbars, hero sections, or card headers (e.g., ban `PRO v2.4`, `STABLE`, `SUB-10MS`, `60 FPS`). Cards must use plain text headings or no header at all. Tags/badges are ONLY permitted inside repeating data table cells or list rows to indicate item-level record status (e.g., `Settled`, `Discrepancy`, `Active`), strictly capped at max 1 badge per row.
|
|
109
|
+
- **Clean Media & Artwork Law (Never Overlay Corner Status Pills on Images, Artwork, or Video Thumbnails):**
|
|
110
|
+
1. **Keep Media Uncluttered:** NEVER place floating `position: absolute` top-left or top-right status pills, tier tags, or promotional badges on top of album art, video thumbnails, avatars, or e-commerce product photography (e.g., ban `• PLAYING`, `NOW PLAYING`, `HD 1080P`, `4K HDR`, `LIVE`, `NEW`, `BESTSELLER`, `FEATURED`, `HOT`, `IN STOCK`).
|
|
111
|
+
2. **How to Show Active or Metadata States Instead:**
|
|
112
|
+
- For active media/playback: Use a single centered icon overlay (Play/Pause/Equalizer) on the thumbnail or a quiet indicator inside the text row—never a corner text pill (`• PLAYING`).
|
|
113
|
+
- For product/content metadata (like `"New Arrival"`, `"Limited Edition"`, or discounts): Render it as clean, quiet plain text (`var(--text-secondary)`) below the image alongside the title/price—never as a colored sticker slapped onto the corner of the photograph.
|
|
114
|
+
- **Only Permitted Media Overlay:** A plain bottom-right numeric video duration timestamp (`3:51`) or a single subtle top-right icon action (like a quiet heart/bookmark icon on hover).
|
|
108
115
|
- **Human Eyesight & Readability Floor (No Micro-Print):**
|
|
109
116
|
1. **Never use font sizes below `13px` (`0.8125rem`).** Ban Tailwind micro-classes (`text-[9px]`, `text-[10px]`, `text-[11px]`).
|
|
110
117
|
2. **Comfortable Secondary Text (`14px–15px`):** Sub-labels (metadata beneath headings, secondary descriptions beneath primary titles), navigation tabs, and buttons MUST be `0.875rem–0.9375rem` (`14px–15px`) in high-contrast `var(--text-secondary)`—never `11px` dim gray.
|
|
@@ -62,15 +62,21 @@ All numbers, financial quantities, telemetry counters, metrics, and timestamps m
|
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
|
-
## 4. Keyboard Navigation &
|
|
65
|
+
## 4. Keyboard Navigation, Accessibility & Composite Input Focus
|
|
66
66
|
|
|
67
|
-
- Never suppress focus outlines without providing a token-bound replacement:
|
|
67
|
+
- **Universal Input Reset & Focus Visibility:** Never suppress focus outlines on interactive controls without providing a token-bound replacement, and delegate composite input focus to the outer container:
|
|
68
68
|
```css
|
|
69
|
-
:
|
|
70
|
-
|
|
71
|
-
outline
|
|
69
|
+
/* Universal Input Reset: Prevent inner rectangular outlines inside composite input wrappers */
|
|
70
|
+
input, textarea, select {
|
|
71
|
+
outline: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
button:focus-visible, a:focus-visible, [role="button"]:focus-visible, [role="tab"]:focus-visible {
|
|
75
|
+
outline: 2px solid var(--accent-primary);
|
|
76
|
+
outline-offset: 2px;
|
|
72
77
|
}
|
|
73
78
|
```
|
|
79
|
+
- **Universal Composite Input Focus Law:** For form fields and composite inputs (inputs with icons, prefixes, search bars, or action buttons), never allow a raw inner `<input>` focus box to clip inside a rounded wrapper; use `outline: none` on the inner input and apply focus feedback (`border-color` or ring) to the outer field container via `:focus-within`.
|
|
74
80
|
- Table headers must include `scope="col"`.
|
|
75
81
|
- Sorting headers must declare `aria-sort="ascending" | "descending" | "none"`.
|
|
76
82
|
- Interactive action triggers must use `<button>` elements, never clickable `<div>` or `<span>` elements without full keyboard event handlers and ARIA semantics.
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
outline: none;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
.kbd-
|
|
63
|
+
.kbd-key {
|
|
64
64
|
font-family: var(--font-mono);
|
|
65
|
-
font-size:
|
|
65
|
+
font-size: var(--text-xs);
|
|
66
66
|
background-color: var(--bg-elevated);
|
|
67
67
|
border: 1px solid var(--border-subtle);
|
|
68
|
-
border-radius: var(--radius-
|
|
68
|
+
border-radius: var(--radius-inner);
|
|
69
69
|
padding: 0.15rem 0.4rem;
|
|
70
70
|
color: var(--text-subtle);
|
|
71
71
|
}
|
|
@@ -227,7 +227,7 @@
|
|
|
227
227
|
background-color: var(--bg-sunken);
|
|
228
228
|
border: 1px solid var(--border-subtle);
|
|
229
229
|
font-family: var(--font-mono);
|
|
230
|
-
font-size:
|
|
230
|
+
font-size: var(--text-xs);
|
|
231
231
|
display: inline-flex;
|
|
232
232
|
align-items: center;
|
|
233
233
|
justify-content: center;
|
|
@@ -268,7 +268,7 @@
|
|
|
268
268
|
|
|
269
269
|
<div class="query-input-box">
|
|
270
270
|
<input type="text" id="query-input" class="query-input" value="SELECT * FROM ledger_audit WHERE delta != 0 ORDER BY timestamp DESC" aria-label="Query input">
|
|
271
|
-
<
|
|
271
|
+
<kbd class="kbd-key">⌘K</kbd>
|
|
272
272
|
</div>
|
|
273
273
|
|
|
274
274
|
<div>
|