lucent-ui 0.11.0 → 0.12.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 CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),p=require("react"),At={primary:{background:"var(--lucent-accent-default)",color:"var(--lucent-text-on-accent)",border:"1px solid transparent"},secondary:{background:"color-mix(in srgb, var(--lucent-accent-default) 14%, var(--lucent-surface-secondary))",color:"var(--lucent-text-primary)",border:"1px solid transparent"},outline:{background:"var(--lucent-surface)",color:"var(--lucent-text-primary)",border:"1px solid var(--lucent-border-default)"},ghost:{background:"transparent",color:"var(--lucent-text-primary)",border:"1px solid transparent"},danger:{background:"var(--lucent-danger-default)",color:"#ffffff",border:"1px solid var(--lucent-danger-default)"}},zt={sm:{height:"34px",padding:"0 var(--lucent-space-3)",fontSize:"var(--lucent-font-size-sm)"},md:{height:"42px",padding:"0 var(--lucent-space-4)",fontSize:"var(--lucent-font-size-md)"},lg:{height:"48px",padding:"0 var(--lucent-space-5)",fontSize:"var(--lucent-font-size-lg)"}},De=p.forwardRef(({variant:e="primary",size:n="md",loading:a=!1,fullWidth:o=!1,spread:r=!1,leftIcon:i,rightIcon:s,chevron:l=!1,disableHoverStyles:c=!1,bordered:u=!0,children:f,disabled:d,style:y,...h},w)=>{const v=d??a;return t.jsxs("button",{ref:w,disabled:v,"aria-busy":a,style:{display:"inline-flex",alignItems:"center",justifyContent:r?"space-between":"center",gap:"var(--lucent-space-2)",fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:1,letterSpacing:"0.01em",borderRadius:"var(--lucent-radius-lg)",cursor:v?"not-allowed":"pointer",width:o?"100%":void 0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), border-color var(--lucent-duration-fast) var(--lucent-easing-default), box-shadow var(--lucent-duration-fast) var(--lucent-easing-default), transform 80ms var(--lucent-easing-default)",whiteSpace:"nowrap",boxSizing:"border-box",outline:"none",margin:0,...zt[n],...At[e],...y,...v&&{background:"color-mix(in srgb, var(--lucent-surface-secondary) 70%, var(--lucent-border-default))",color:"color-mix(in srgb, var(--lucent-text-disabled) 50%, var(--lucent-border-default))",borderColor:"transparent"},...u===!1&&{border:"none"}},onMouseEnter:g=>{var b;!v&&!c&&Rt(g.currentTarget,e,u),(b=h.onMouseEnter)==null||b.call(h,g)},onMouseLeave:g=>{var b;!v&&!c&&Lt(g.currentTarget,e,u),(b=h.onMouseLeave)==null||b.call(h,g)},onMouseDown:g=>{var b;if(!v){const k=e==="danger"?"var(--lucent-danger-default)":"var(--lucent-accent-default)";g.currentTarget.style.transform="translateY(1px)",g.currentTarget.style.boxShadow=`0 0 0 2px var(--lucent-surface), 0 0 0 4px ${k}`,g.currentTarget.dataset.pressed="1"}(b=h.onMouseDown)==null||b.call(h,g)},onMouseUp:g=>{var b;g.currentTarget.style.transform="",g.currentTarget.style.boxShadow="",delete g.currentTarget.dataset.pressed,(b=h.onMouseUp)==null||b.call(h,g)},onFocus:g=>{var b;g.currentTarget.dataset.pressed||(g.currentTarget.style.boxShadow="0 0 0 3px var(--lucent-accent-subtle)"),(b=h.onFocus)==null||b.call(h,g)},onBlur:g=>{var b;g.currentTarget.style.boxShadow="",(b=h.onBlur)==null||b.call(h,g)},...h,children:[i,a?t.jsx(Pt,{}):f,!a&&s,!a&&l&&t.jsx(qt,{size:n})]})});De.displayName="Button";const Et={primary:"0 4px 14px -2px var(--lucent-accent-subtle)",secondary:"0 4px 14px -2px var(--lucent-accent-subtle)",outline:"0 4px 14px -2px var(--lucent-accent-subtle)",ghost:"0 4px 14px -2px var(--lucent-accent-subtle)",danger:"0 4px 14px -2px var(--lucent-danger-subtle)"};function Rt(e,n,a){e.style.transform="translateY(-1px)",e.style.boxShadow=Et[n],n==="primary"?e.style.background="var(--lucent-accent-hover)":n==="secondary"?e.style.background="color-mix(in srgb, var(--lucent-accent-default) 10%, var(--lucent-surface-secondary))":n==="outline"?e.style.background="color-mix(in srgb, var(--lucent-accent-default) 10%, var(--lucent-surface))":n==="ghost"?e.style.background="color-mix(in srgb, var(--lucent-accent-default) 8%, var(--lucent-surface))":n==="danger"&&(e.style.background="var(--lucent-danger-hover)",a!==!1&&(e.style.borderColor="var(--lucent-danger-hover)"))}function Lt(e,n,a){e.style.transform="",e.style.boxShadow="",n==="primary"?e.style.background="var(--lucent-accent-default)":n==="secondary"?e.style.background="var(--lucent-surface-secondary)":n==="outline"?e.style.background="var(--lucent-surface)":n==="ghost"?e.style.background="transparent":n==="danger"&&(e.style.background="var(--lucent-danger-default)",a!==!1&&(e.style.borderColor="var(--lucent-danger-default)"))}const Bt={sm:12,md:14,lg:16};function qt({size:e}){const n=Bt[e];return t.jsx("svg",{width:n,height:n,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,style:{flexShrink:0,marginLeft:-2},children:t.jsx("polyline",{points:"6 9 12 15 18 9"})})}function Pt(){return t.jsxs("svg",{width:14,height:14,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,strokeLinecap:"round","aria-hidden":!0,style:{animation:"lucent-spin 0.7s linear infinite",flexShrink:0},children:[t.jsx("style",{children:"@keyframes lucent-spin { to { transform: rotate(360deg); } }"}),t.jsx("path",{d:"M12 2a10 10 0 0 1 10 10"})]})}const Ft={id:"button",name:"Button",tier:"atom",domain:"neutral",specVersion:"1.0",description:"A clickable control that triggers an action. The primary interactive primitive in Lucent UI.",designIntent:'Buttons communicate available actions. Variant conveys hierarchy: use "primary" for the single most important action in a view, "secondary" for supporting actions, "ghost" for low-emphasis actions in dense UIs, and "danger" exclusively for destructive or irreversible operations. Size should match surrounding content density — prefer "md" as the default and reserve "sm" for toolbars or tables.',props:[{name:"variant",type:"enum",required:!1,default:"primary",description:"Visual style conveying action hierarchy.",enumValues:["primary","secondary","ghost","danger"]},{name:"size",type:"enum",required:!1,default:"md",description:"Controls height and padding.",enumValues:["sm","md","lg"]},{name:"children",type:"ReactNode",required:!0,description:"Button label or content."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and applies disabled styling."},{name:"loading",type:"boolean",required:!1,default:"false",description:"Shows a spinner and prevents interaction while an async action is in progress."},{name:"fullWidth",type:"boolean",required:!1,default:"false",description:"Stretches the button to fill its container width."},{name:"bordered",type:"boolean",required:!1,default:"true",description:"When false removes the button border entirely, producing a flat look."},{name:"leftIcon",type:"ReactNode",required:!1,description:"Icon element rendered before the label."},{name:"rightIcon",type:"ReactNode",required:!1,description:"Icon element rendered after the label."},{name:"onClick",type:"function",required:!1,description:"Called when the button is clicked and not disabled or loading."},{name:"type",type:"enum",required:!1,default:"button",description:"Native button type attribute.",enumValues:["button","submit","reset"]}],usageExamples:[{title:"Primary action",code:'<Button variant="primary" onClick={handleSave}>Save changes</Button>'},{title:"Destructive action",code:'<Button variant="danger" onClick={handleDelete}>Delete account</Button>'},{title:"Loading state",code:'<Button variant="primary" loading={isSaving}>Save changes</Button>'},{title:"With icon",code:'<Button variant="secondary" leftIcon={<PlusIcon />}>Add member</Button>'},{title:"Ghost in toolbar",code:'<Button variant="ghost" size="sm">Edit</Button>'},{title:"Full-width submit",code:'<Button variant="primary" type="submit" fullWidth>Sign in</Button>'},{title:"Borderless primary",code:'<Button variant="primary" bordered={false}>Flat primary</Button>'}],compositionGraph:[],accessibility:{role:"button",ariaAttributes:["aria-disabled","aria-busy"],keyboardInteractions:["Enter — activates the button","Space — activates the button"]}},Nt={sm:"32px",md:"40px",lg:"46px"},Ye={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-md)"},te={sm:"var(--lucent-space-2)",md:"var(--lucent-space-3)",lg:"var(--lucent-space-3)"},Ke={sm:"28px",md:"var(--lucent-space-10)",lg:"var(--lucent-space-10)"},Y=p.forwardRef(({size:e="md",label:n,helperText:a,errorText:o,leftElement:r,rightElement:i,prefix:s,suffix:l,id:c,style:u,...f},d)=>{const y=c??`lucent-input-${Math.random().toString(36).slice(2,7)}`,h=!!o,w=!!f.disabled,[v,g]=p.useState(!1),[b,k]=p.useState(!1),D=w?"transparent":h?"var(--lucent-danger-default)":v?"var(--lucent-focus-ring)":b?"var(--lucent-border-strong)":"var(--lucent-border-default)",S=v?`0 0 0 3px ${h?"var(--lucent-danger-subtle)":"var(--lucent-accent-subtle)"}`:"none",x={display:"flex",alignItems:"center",color:w?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",fontSize:Ye[e],fontFamily:"var(--lucent-font-family-base)",whiteSpace:"nowrap",userSelect:"none",flexShrink:0},z={...x,paddingLeft:te[e],paddingRight:"2px"},q={...x,paddingLeft:"2px",paddingRight:te[e]};return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%",...u},children:[n&&t.jsx("label",{htmlFor:y,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:w?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:n}),t.jsxs("div",{style:{display:"flex",alignItems:"stretch",height:Nt[e],border:`1px solid ${D}`,borderRadius:"var(--lucent-radius-lg)",boxShadow:S,background:w?"var(--lucent-surface-secondary)":"var(--lucent-surface)",overflow:"hidden",cursor:w?"not-allowed":void 0,transition:["border-color var(--lucent-duration-fast) var(--lucent-easing-default)","box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", ")},onMouseEnter:()=>{w||k(!0)},onMouseLeave:()=>k(!1),children:[s&&t.jsx("span",{style:z,children:s}),t.jsxs("div",{style:{position:"relative",flex:1,display:"flex",alignItems:"center",minWidth:0},children:[r&&t.jsx("span",{style:{position:"absolute",left:te[e],color:w?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",display:"flex",alignItems:"center",pointerEvents:"none"},children:r}),t.jsx("input",{ref:d,id:y,"aria-invalid":h,"aria-describedby":h?`${y}-error`:a?`${y}-helper`:void 0,style:{width:"100%",height:"100%",paddingLeft:r?Ke[e]:te[e],paddingRight:i?Ke[e]:te[e],fontSize:Ye[e],fontFamily:"var(--lucent-font-family-base)",color:w?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",background:"transparent",border:"none",outline:"none",cursor:w?"not-allowed":void 0,boxSizing:"border-box"},onFocus:T=>{var C;g(!0),(C=f.onFocus)==null||C.call(f,T)},onBlur:T=>{var C;g(!1),(C=f.onBlur)==null||C.call(f,T)},...f}),i&&t.jsx("span",{style:{position:"absolute",right:te[e],color:w?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",display:"flex",alignItems:"center"},children:i})]}),l&&t.jsx("span",{style:q,children:l})]}),h&&t.jsx("span",{id:`${y}-error`,role:"alert",style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-danger-text)",fontFamily:"var(--lucent-font-family-base)"},children:o}),!h&&a&&t.jsx("span",{id:`${y}-helper`,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:a})]})});Y.displayName="Input";const $t={id:"input",name:"Input",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A single-line text field with optional label, helper text, and error state.",designIntent:"Always pair with a visible label — never rely on placeholder text alone as it disappears on input and is inaccessible. Use errorText (not helperText) to surface validation failures; the component applies danger styling automatically. leftElement and rightElement accept icons or small controls (e.g. currency symbol, clear button).",props:[{name:"type",type:"enum",required:!1,default:"text",description:"HTML input type.",enumValues:["text","number","password","email","tel","url","search"]},{name:"label",type:"string",required:!1,description:"Visible label rendered above the input."},{name:"helperText",type:"string",required:!1,description:"Supplementary hint shown below the input."},{name:"errorText",type:"string",required:!1,description:"Validation error message. When set, input renders in error state."},{name:"leftElement",type:"ReactNode",required:!1,description:"Icon or adornment rendered inside the left edge."},{name:"rightElement",type:"ReactNode",required:!1,description:"Icon or adornment rendered inside the right edge."},{name:"placeholder",type:"string",required:!1,description:"Placeholder text. Use as a hint, not a label."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the input."},{name:"value",type:"string",required:!1,description:"Controlled value."},{name:"onChange",type:"function",required:!1,description:"Change handler."}],usageExamples:[{title:"Basic",code:'<Input label="Email" type="email" placeholder="you@example.com" />'},{title:"With helper text",code:'<Input label="Username" helperText="3–20 characters, letters and numbers only" />'},{title:"Error state",code:'<Input label="Password" type="password" value={value} errorText="Must be at least 8 characters" />'},{title:"With icon",code:'<Input label="Search" leftElement={<SearchIcon />} placeholder="Search…" />'}],compositionGraph:[],accessibility:{role:"textbox",ariaAttributes:["aria-invalid","aria-describedby","aria-label"],keyboardInteractions:["Tab — focuses the input"]}},dt=p.forwardRef(({label:e,helperText:n,errorText:a,autoResize:o=!1,maxLength:r,showCount:i=!1,id:s,value:l,onChange:c,disabled:u,style:f,...d},y)=>{const h=p.useRef(null),w=y??h,v=s??`lucent-textarea-${Math.random().toString(36).slice(2,7)}`,g=!!a,b=!!u,k=typeof l=="string"?l.length:0;p.useEffect(()=>{if(!o)return;const S=w.current;S&&(S.style.height="auto",S.style.height=`${S.scrollHeight}px`)},[l,o,w]);const D=b?"transparent":g?"var(--lucent-danger-default)":"var(--lucent-border-default)";return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%"},children:[e&&t.jsx("label",{htmlFor:v,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:b?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:e}),t.jsx("textarea",{ref:w,id:v,maxLength:r,value:l,onChange:c,disabled:u,"aria-invalid":g,"aria-describedby":g?`${v}-error`:n?`${v}-helper`:void 0,style:{width:"100%",minHeight:"100px",padding:"var(--lucent-space-3)",fontSize:"var(--lucent-font-size-md)",fontFamily:"var(--lucent-font-family-base)",color:b?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",background:b?"var(--lucent-surface-secondary)":"var(--lucent-surface)",border:`1px solid ${D}`,borderRadius:"var(--lucent-radius-lg)",outline:"none",resize:o?"none":"vertical",boxSizing:"border-box",lineHeight:"var(--lucent-line-height-base)",cursor:b?"not-allowed":void 0,transition:["border-color var(--lucent-duration-fast) var(--lucent-easing-default)","box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", "),...f},onMouseEnter:S=>{var x;!b&&S.currentTarget!==document.activeElement&&(S.currentTarget.style.borderColor=g?"var(--lucent-danger-default)":"var(--lucent-border-strong)"),(x=d.onMouseEnter)==null||x.call(d,S)},onMouseLeave:S=>{var x;!b&&S.currentTarget!==document.activeElement&&(S.currentTarget.style.borderColor=g?"var(--lucent-danger-default)":"var(--lucent-border-default)"),(x=d.onMouseLeave)==null||x.call(d,S)},onFocus:S=>{var x;b||(S.currentTarget.style.borderColor=g?"var(--lucent-danger-default)":"var(--lucent-focus-ring)",S.currentTarget.style.boxShadow=`0 0 0 3px ${g?"var(--lucent-danger-subtle)":"var(--lucent-accent-subtle)"}`,(x=d.onFocus)==null||x.call(d,S))},onBlur:S=>{var x;b||(S.currentTarget.style.borderColor=g?"var(--lucent-danger-default)":"var(--lucent-border-default)",S.currentTarget.style.boxShadow="none",(x=d.onBlur)==null||x.call(d,S))},...d}),t.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start"},children:[t.jsxs("div",{children:[g&&t.jsx("span",{id:`${v}-error`,role:"alert",style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-danger-text)",fontFamily:"var(--lucent-font-family-base)"},children:a}),!g&&n&&t.jsx("span",{id:`${v}-helper`,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:n})]}),(i||r)&&t.jsxs("span",{style:{fontSize:"var(--lucent-font-size-xs)",color:r&&k>=r?"var(--lucent-danger-text)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-mono)",flexShrink:0,marginLeft:"var(--lucent-space-2)"},children:[k,r?`/${r}`:""]})]})]})});dt.displayName="Textarea";const Wt={id:"textarea",name:"Textarea",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A multi-line text input with optional auto-resize and character count.",designIntent:"Use autoResize for open-ended fields (bio, description) where content length is unpredictable. Use maxLength + showCount for fields with hard limits (tweet-style). Behaves identically to Input for label/helper/error patterns.",props:[{name:"label",type:"string",required:!1,description:"Visible label above the textarea."},{name:"helperText",type:"string",required:!1,description:"Hint text shown below."},{name:"errorText",type:"string",required:!1,description:"Validation error. Triggers error styling."},{name:"autoResize",type:"boolean",required:!1,default:"false",description:"Grows with content, disables manual resize handle."},{name:"maxLength",type:"number",required:!1,description:"Character limit. Displays counter when set."},{name:"showCount",type:"boolean",required:!1,default:"false",description:"Always show character counter even without maxLength."},{name:"value",type:"string",required:!1,description:"Controlled value."},{name:"onChange",type:"function",required:!1,description:"Change handler."},{name:"placeholder",type:"string",required:!1,description:"Placeholder text."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the textarea."}],usageExamples:[{title:"Basic",code:'<Textarea label="Bio" placeholder="Tell us about yourself…" />'},{title:"Auto-resize",code:'<Textarea label="Description" autoResize value={value} onChange={e => setValue(e.target.value)} />'},{title:"With character count",code:'<Textarea label="Tweet" maxLength={280} showCount value={value} onChange={e => setValue(e.target.value)} />'},{title:"Error state",code:'<Textarea label="Notes" errorText="Required" value="" />'}],compositionGraph:[],accessibility:{role:"textbox",ariaAttributes:["aria-multiline","aria-invalid","aria-describedby"],keyboardInteractions:["Tab — focuses the textarea"]}},Ot={neutral:{bg:"var(--lucent-surface-secondary)",color:"var(--lucent-text-secondary)",border:"var(--lucent-border-default)"},accent:{bg:"var(--lucent-accent-default)",color:"var(--lucent-text-on-accent)",border:"var(--lucent-accent-default)"},success:{bg:"var(--lucent-success-subtle)",color:"var(--lucent-success-text)",border:"var(--lucent-success-subtle)"},warning:{bg:"var(--lucent-warning-subtle)",color:"var(--lucent-warning-text)",border:"var(--lucent-warning-subtle)"},danger:{bg:"var(--lucent-danger-subtle)",color:"var(--lucent-danger-text)",border:"var(--lucent-danger-subtle)"},info:{bg:"var(--lucent-info-subtle)",color:"var(--lucent-info-text)",border:"var(--lucent-info-subtle)"}},Vt={sm:{fontSize:"var(--lucent-font-size-xs)",padding:"0 var(--lucent-space-2)",height:"18px"},md:{fontSize:"var(--lucent-font-size-sm)",padding:"0 var(--lucent-space-2)",height:"22px"}};function Ht({variant:e="neutral",size:n="md",dot:a=!1,children:o,style:r}){const i=Ot[e],s=Vt[n];return t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",height:s.height,padding:s.padding,fontSize:s.fontSize,fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:1,borderRadius:"var(--lucent-radius-full)",background:i.bg,color:i.color,border:`1px solid ${i.border}`,whiteSpace:"nowrap",boxSizing:"border-box",...r},children:[a&&t.jsx("span",{style:{width:6,height:6,borderRadius:"var(--lucent-radius-full)",background:"currentColor",flexShrink:0}}),o]})}const Gt={id:"badge",name:"Badge",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A small inline label for status, count, or category.",designIntent:'Badges communicate status or category at a glance. Match variant to semantic meaning — never use "danger" for non-critical states or "success" for neutral counts. Use dot=true when a single colour indicator is enough context (e.g. online status). Keep badge text short: 1–3 words maximum.',props:[{name:"variant",type:"enum",required:!1,default:"neutral",description:"Colour scheme conveying semantic meaning.",enumValues:["neutral","success","warning","danger","info","accent"]},{name:"size",type:"enum",required:!1,default:"md",description:"Controls height and font size.",enumValues:["sm","md"]},{name:"dot",type:"boolean",required:!1,default:"false",description:"Prepends a coloured dot indicator."},{name:"children",type:"ReactNode",required:!0,description:"Badge label."}],usageExamples:[{title:"Status",code:'<Badge variant="success" dot>Active</Badge>'},{title:"Count",code:'<Badge variant="danger">12</Badge>'},{title:"Category",code:'<Badge variant="info">Beta</Badge>'},{title:"Neutral tag",code:"<Badge>Draft</Badge>"}],compositionGraph:[],accessibility:{role:"status",notes:"Use aria-label on the parent element when badge meaning depends on context."}},Ut={xs:24,sm:32,md:40,lg:56,xl:80},_t={xs:"var(--lucent-font-size-xs)",sm:"var(--lucent-font-size-xs)",md:"var(--lucent-font-size-sm)",lg:"var(--lucent-font-size-lg)",xl:"var(--lucent-font-size-xl)"};function Yt(e,n){var o,r,i;if(n)return n.slice(0,2).toUpperCase();const a=e.trim().split(/\s+/);return a.length===1?(((o=a[0])==null?void 0:o[0])??"").toUpperCase():((((r=a[0])==null?void 0:r[0])??"")+(((i=a[a.length-1])==null?void 0:i[0])??"")).toUpperCase()}function Kt({src:e,alt:n,size:a="md",initials:o,style:r,...i}){const s=Ut[a],l=Yt(n,o),c={width:s,height:s,borderRadius:"var(--lucent-radius-full)",flexShrink:0,display:"inline-flex",alignItems:"center",justifyContent:"center",overflow:"hidden",boxSizing:"border-box",userSelect:"none",...r};return e?t.jsx("img",{src:e,alt:n,width:s,height:s,style:{...c,objectFit:"cover"},...i}):t.jsx("span",{role:"img","aria-label":n,style:{...c,background:"var(--lucent-accent-default)",color:"var(--lucent-text-on-accent)",fontSize:_t[a],fontWeight:"var(--lucent-font-weight-semibold)",fontFamily:"var(--lucent-font-family-base)"},children:l})}const Xt={id:"avatar",name:"Avatar",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A circular user image with initials fallback.",designIntent:"Always provide alt for accessibility — it is used to derive initials automatically when src is absent or fails. Use initials prop to override auto-derived initials (e.g. for non-Latin names). Size xs/sm suit table rows and compact lists; md is the default for comment threads; lg/xl for profile headers.",props:[{name:"src",type:"string",required:!1,description:"Image URL. Falls back to initials if omitted or fails to load."},{name:"alt",type:"string",required:!0,description:"Alt text and source for auto-derived initials."},{name:"size",type:"enum",required:!1,default:"md",description:"Diameter of the avatar.",enumValues:["xs","sm","md","lg","xl"]},{name:"initials",type:"string",required:!1,description:"Override auto-derived initials (max 2 characters)."}],usageExamples:[{title:"With image",code:'<Avatar src="/avatars/jane.jpg" alt="Jane Doe" />'},{title:"Initials fallback",code:'<Avatar alt="Jane Doe" />'},{title:"Large profile",code:'<Avatar src={user.avatar} alt={user.name} size="lg" />'},{title:"Custom initials",code:'<Avatar alt="张伟" initials="张" size="md" />'}],compositionGraph:[],accessibility:{role:"img",ariaAttributes:["aria-label"],notes:'When src is present, renders as <img> with alt. When showing initials, renders as <span role="img" aria-label>.'}},Jt={xs:12,sm:16,md:24,lg:36},Zt={xs:2.5,sm:2.5,md:2,lg:2};function ut({size:e="md",label:n="Loading…",color:a}){const o=Jt[e],r=Zt[e];return t.jsxs("span",{role:"status","aria-label":n,style:{display:"inline-flex",alignItems:"center",justifyContent:"center"},children:[t.jsxs("svg",{width:o,height:o,viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,style:{animation:"lucent-spin 0.7s linear infinite",color:a??"currentColor"},children:[t.jsx("style",{children:"@keyframes lucent-spin { to { transform: rotate(360deg); } }"}),t.jsx("circle",{cx:12,cy:12,r:10,stroke:"currentColor",strokeWidth:r,strokeOpacity:.2}),t.jsx("path",{d:"M12 2a10 10 0 0 1 10 10",stroke:"currentColor",strokeWidth:r,strokeLinecap:"round"})]}),t.jsx("span",{style:{position:"absolute",width:1,height:1,overflow:"hidden",clip:"rect(0,0,0,0)",whiteSpace:"nowrap"},children:n})]})}const Qt={id:"spinner",name:"Spinner",tier:"atom",domain:"neutral",specVersion:"0.1",description:"An animated loading indicator for async operations.",designIntent:"Use Spinner for indeterminate loading states of short duration (< 3s). For full-page or skeleton-level loading, prefer Skeleton instead. The label prop is visually hidden but read by screen readers — always set it to a meaningful description of what is loading.",props:[{name:"size",type:"enum",required:!1,default:"md",description:"Spinner diameter.",enumValues:["xs","sm","md","lg"]},{name:"label",type:"string",required:!1,default:"Loading…",description:"Visually hidden accessible label."},{name:"color",type:"string",required:!1,description:"Override colour (CSS value). Defaults to currentColor."}],usageExamples:[{title:"Default",code:"<Spinner />"},{title:"Inside button",code:'<Button loading><Spinner size="sm" label="Saving…" /></Button>'},{title:"Full-page overlay",code:`<div style={{ display: 'grid', placeItems: 'center', minHeight: '100vh' }}><Spinner size="lg" label="Loading dashboard…" /></div>`}],compositionGraph:[],accessibility:{role:"status",ariaAttributes:["aria-label"],notes:'The visible SVG is aria-hidden. The label is conveyed via a visually-hidden span inside role="status".'}};function en({orientation:e="horizontal",label:n,spacing:a="var(--lucent-space-4)",style:o}){return e==="vertical"?t.jsx("span",{role:"separator","aria-orientation":"vertical",style:{display:"inline-block",width:"1px",alignSelf:"stretch",background:"var(--lucent-border-default)",margin:`0 ${a}`,flexShrink:0,...o}}):n?t.jsxs("div",{role:"separator","aria-label":n,style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",margin:`${a} 0`,...o},children:[t.jsx("span",{style:{flex:1,height:"1px",background:"var(--lucent-border-default)"}}),t.jsx("span",{style:{fontSize:"var(--lucent-font-size-xs)",fontFamily:"var(--lucent-font-family-base)",color:"var(--lucent-text-secondary)",whiteSpace:"nowrap",letterSpacing:"var(--lucent-letter-spacing-wide)",textTransform:"uppercase"},children:n}),t.jsx("span",{style:{flex:1,height:"1px",background:"var(--lucent-border-default)"}})]}):t.jsx("hr",{role:"separator",style:{border:"none",borderTop:"1px solid var(--lucent-border-default)",margin:`${a} 0`,width:"100%",...o}})}const tn={id:"divider",name:"Divider",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A visual separator between content sections, horizontal or vertical.",designIntent:'Use horizontal Divider to separate sections in a layout. Use vertical Divider inline between sibling elements (e.g. nav links, toolbar buttons). Use the label prop for "OR" separators in auth flows or form sections — never use a plain text node next to a divider for this.',props:[{name:"orientation",type:"enum",required:!1,default:"horizontal",description:"Direction of the divider line.",enumValues:["horizontal","vertical"]},{name:"label",type:"string",required:!1,description:'Optional centered label (horizontal only). Common use: "OR", "AND", section titles.'},{name:"spacing",type:"string",required:!1,default:"var(--lucent-space-4)",description:"Margin on the axis perpendicular to the line."}],usageExamples:[{title:"Section separator",code:"<Divider />"},{title:"With label",code:'<Divider label="OR" />'},{title:"Vertical in nav",code:`<nav style={{ display: 'flex', alignItems: 'center' }}><a>Home</a><Divider orientation="vertical" /><a>About</a></nav>`}],compositionGraph:[],accessibility:{role:"separator",ariaAttributes:["aria-orientation","aria-label"]}},nn={sm:14,md:16},an=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),f=require("react"),At={primary:{background:"var(--lucent-accent-default)",color:"var(--lucent-text-on-accent)",border:"1px solid transparent"},secondary:{background:"color-mix(in srgb, var(--lucent-accent-default) 14%, var(--lucent-surface-secondary))",color:"var(--lucent-text-primary)",border:"1px solid transparent"},outline:{background:"var(--lucent-surface)",color:"var(--lucent-text-primary)",border:"1px solid var(--lucent-border-default)"},ghost:{background:"transparent",color:"var(--lucent-text-primary)",border:"1px solid transparent"},danger:{background:"var(--lucent-danger-default)",color:"#ffffff",border:"1px solid var(--lucent-danger-default)"}},Et={xs:{height:"26px",padding:"0 var(--lucent-space-2)",fontSize:"var(--lucent-font-size-xs)"},sm:{height:"34px",padding:"0 var(--lucent-space-3)",fontSize:"var(--lucent-font-size-sm)"},md:{height:"42px",padding:"0 var(--lucent-space-4)",fontSize:"var(--lucent-font-size-md)"},lg:{height:"48px",padding:"0 var(--lucent-space-5)",fontSize:"var(--lucent-font-size-lg)"}},De=f.forwardRef(({variant:e="primary",size:n="md",loading:a=!1,fullWidth:o=!1,spread:r=!1,leftIcon:i,rightIcon:s,chevron:l=!1,disableHoverStyles:c=!1,bordered:d=!0,children:p,disabled:m,style:h,...u},S)=>{const y=m??a;return t.jsxs("button",{ref:S,disabled:y,"aria-busy":a,style:{display:"inline-flex",alignItems:"center",justifyContent:r?"space-between":"center",gap:"var(--lucent-space-2)",fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:1,letterSpacing:"0.01em",borderRadius:"var(--lucent-radius-lg)",cursor:y?"not-allowed":"pointer",width:o?"100%":void 0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), border-color var(--lucent-duration-fast) var(--lucent-easing-default), box-shadow var(--lucent-duration-fast) var(--lucent-easing-default), transform 80ms var(--lucent-easing-default)",whiteSpace:"nowrap",boxSizing:"border-box",outline:"none",margin:0,...Et[n],...At[e],...h,...y&&{background:"color-mix(in srgb, var(--lucent-surface-secondary) 70%, var(--lucent-border-default))",color:"color-mix(in srgb, var(--lucent-text-disabled) 50%, var(--lucent-border-default))",borderColor:"transparent"},...d===!1&&{border:"none"}},onMouseEnter:b=>{var v;!y&&!c&&Lt(b.currentTarget,e,d),(v=u.onMouseEnter)==null||v.call(u,b)},onMouseLeave:b=>{var v;!y&&!c&&Bt(b.currentTarget,e,d),(v=u.onMouseLeave)==null||v.call(u,b)},onMouseDown:b=>{var v;if(!y){const w=e==="danger"?"var(--lucent-danger-default)":"var(--lucent-accent-default)";b.currentTarget.style.transform="translateY(1px)",b.currentTarget.style.boxShadow=`0 0 0 2px var(--lucent-surface), 0 0 0 4px ${w}`,b.currentTarget.dataset.pressed="1"}(v=u.onMouseDown)==null||v.call(u,b)},onMouseUp:b=>{var v;b.currentTarget.style.transform="",b.currentTarget.style.boxShadow="",delete b.currentTarget.dataset.pressed,(v=u.onMouseUp)==null||v.call(u,b)},onFocus:b=>{var v;b.currentTarget.dataset.pressed||(b.currentTarget.style.boxShadow="0 0 0 3px var(--lucent-accent-subtle)"),(v=u.onFocus)==null||v.call(u,b)},onBlur:b=>{var v;b.currentTarget.style.boxShadow="",(v=u.onBlur)==null||v.call(u,b)},...u,children:[i,a?t.jsx(Ft,{}):p,!a&&s,!a&&l&&t.jsx(Pt,{size:n})]})});De.displayName="Button";const Rt={primary:"0 4px 14px -2px var(--lucent-accent-subtle)",secondary:"0 4px 14px -2px var(--lucent-accent-subtle)",outline:"0 4px 14px -2px var(--lucent-accent-subtle)",ghost:"0 4px 14px -2px var(--lucent-accent-subtle)",danger:"0 4px 14px -2px var(--lucent-danger-subtle)"};function Lt(e,n,a){e.style.transform="translateY(-1px)",e.style.boxShadow=Rt[n],n==="primary"?e.style.background="var(--lucent-accent-hover)":n==="secondary"?e.style.background="color-mix(in srgb, var(--lucent-accent-default) 10%, var(--lucent-surface-secondary))":n==="outline"?e.style.background="color-mix(in srgb, var(--lucent-accent-default) 10%, var(--lucent-surface))":n==="ghost"?e.style.background="color-mix(in srgb, var(--lucent-accent-default) 8%, var(--lucent-surface))":n==="danger"&&(e.style.background="var(--lucent-danger-hover)",a!==!1&&(e.style.borderColor="var(--lucent-danger-hover)"))}function Bt(e,n,a){e.style.transform="",e.style.boxShadow="",n==="primary"?e.style.background="var(--lucent-accent-default)":n==="secondary"?e.style.background="var(--lucent-surface-secondary)":n==="outline"?e.style.background="var(--lucent-surface)":n==="ghost"?e.style.background="transparent":n==="danger"&&(e.style.background="var(--lucent-danger-default)",a!==!1&&(e.style.borderColor="var(--lucent-danger-default)"))}const qt={xs:10,sm:12,md:14,lg:16};function Pt({size:e}){const n=qt[e];return t.jsx("svg",{width:n,height:n,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,style:{flexShrink:0,marginLeft:-2},children:t.jsx("polyline",{points:"6 9 12 15 18 9"})})}function Ft(){return t.jsxs("svg",{width:14,height:14,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,strokeLinecap:"round","aria-hidden":!0,style:{animation:"lucent-spin 0.7s linear infinite",flexShrink:0},children:[t.jsx("style",{children:"@keyframes lucent-spin { to { transform: rotate(360deg); } }"}),t.jsx("path",{d:"M12 2a10 10 0 0 1 10 10"})]})}const Nt={id:"button",name:"Button",tier:"atom",domain:"neutral",specVersion:"1.0",description:"A clickable control that triggers an action. The primary interactive primitive in Lucent UI.",designIntent:'Buttons communicate available actions. Variant conveys hierarchy: use "primary" for the single most important action in a view, "secondary" for supporting actions, "ghost" for low-emphasis actions in dense UIs, "outline" for bordered buttons with no fill, and "danger" exclusively for destructive or irreversible operations. Size should match surrounding content density — prefer "md" as the default, "sm" for toolbars or tables, and "xs" for compact UIs like customizer panels.',props:[{name:"variant",type:"enum",required:!1,default:"primary",description:"Visual style conveying action hierarchy.",enumValues:["primary","secondary","outline","ghost","danger"]},{name:"size",type:"enum",required:!1,default:"md",description:"Controls height and padding.",enumValues:["xs","sm","md","lg"]},{name:"children",type:"ReactNode",required:!0,description:"Button label or content."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and applies disabled styling."},{name:"loading",type:"boolean",required:!1,default:"false",description:"Shows a spinner and prevents interaction while an async action is in progress."},{name:"fullWidth",type:"boolean",required:!1,default:"false",description:"Stretches the button to fill its container width."},{name:"bordered",type:"boolean",required:!1,default:"true",description:"When false removes the button border entirely, producing a flat look."},{name:"leftIcon",type:"ReactNode",required:!1,description:"Icon element rendered before the label."},{name:"rightIcon",type:"ReactNode",required:!1,description:"Icon element rendered after the label."},{name:"chevron",type:"boolean",required:!1,default:"false",description:"Appends a chevron-down icon after the label. Useful for dropdown triggers."},{name:"spread",type:"boolean",required:!1,default:"false",description:"Spaces content to the edges (justify-content: space-between). Useful with fullWidth + rightIcon/chevron."},{name:"onClick",type:"function",required:!1,description:"Called when the button is clicked and not disabled or loading."},{name:"type",type:"enum",required:!1,default:"button",description:"Native button type attribute.",enumValues:["button","submit","reset"]}],usageExamples:[{title:"Primary action",code:'<Button variant="primary" onClick={handleSave}>Save changes</Button>'},{title:"Destructive action",code:'<Button variant="danger" onClick={handleDelete}>Delete account</Button>'},{title:"Loading state",code:'<Button variant="primary" loading={isSaving}>Save changes</Button>'},{title:"With icon",code:'<Button variant="secondary" leftIcon={<PlusIcon />}>Add member</Button>'},{title:"Ghost in toolbar",code:'<Button variant="ghost" size="sm">Edit</Button>'},{title:"Full-width submit",code:'<Button variant="primary" type="submit" fullWidth>Sign in</Button>'},{title:"Outline with swatch",code:`<Button size="xs" variant="outline" leftIcon={<span style={{ width: 8, height: 8, borderRadius: '50%', background: '#6366f1' }} />}>Indigo</Button>`},{title:"Dropdown trigger",code:'<Button variant="outline" chevron>Options</Button>'}],compositionGraph:[],accessibility:{role:"button",ariaAttributes:["aria-disabled","aria-busy"],keyboardInteractions:["Enter — activates the button","Space — activates the button"]}},$t={sm:"32px",md:"40px",lg:"46px"},Ye={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-md)"},ne={sm:"var(--lucent-space-2)",md:"var(--lucent-space-3)",lg:"var(--lucent-space-3)"},Ke={sm:"28px",md:"var(--lucent-space-10)",lg:"var(--lucent-space-10)"},K=f.forwardRef(({size:e="md",label:n,helperText:a,errorText:o,leftElement:r,rightElement:i,prefix:s,suffix:l,id:c,style:d,...p},m)=>{const h=c??`lucent-input-${Math.random().toString(36).slice(2,7)}`,u=!!o,S=!!p.disabled,[y,b]=f.useState(!1),[v,w]=f.useState(!1),j=S?"transparent":u?"var(--lucent-danger-default)":y?"var(--lucent-focus-ring)":v?"var(--lucent-border-strong)":"var(--lucent-border-default)",T=y?`0 0 0 3px ${u?"var(--lucent-danger-subtle)":"var(--lucent-accent-subtle)"}`:"none",x={display:"flex",alignItems:"center",color:S?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",fontSize:Ye[e],fontFamily:"var(--lucent-font-family-base)",whiteSpace:"nowrap",userSelect:"none",flexShrink:0},M={...x,paddingLeft:ne[e],paddingRight:"2px"},F={...x,paddingLeft:"2px",paddingRight:ne[e]};return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%",...d},children:[n&&t.jsx("label",{htmlFor:h,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:S?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:n}),t.jsxs("div",{style:{display:"flex",alignItems:"stretch",height:$t[e],border:`1px solid ${j}`,borderRadius:"var(--lucent-radius-lg)",boxShadow:T,background:S?"var(--lucent-surface-secondary)":"var(--lucent-surface)",overflow:"hidden",cursor:S?"not-allowed":void 0,transition:["border-color var(--lucent-duration-fast) var(--lucent-easing-default)","box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", ")},onMouseEnter:()=>{S||w(!0)},onMouseLeave:()=>w(!1),children:[s&&t.jsx("span",{style:M,children:s}),t.jsxs("div",{style:{position:"relative",flex:1,display:"flex",alignItems:"center",minWidth:0},children:[r&&t.jsx("span",{style:{position:"absolute",left:ne[e],color:S?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",display:"flex",alignItems:"center",pointerEvents:"none"},children:r}),t.jsx("input",{ref:m,id:h,"aria-invalid":u,"aria-describedby":u?`${h}-error`:a?`${h}-helper`:void 0,style:{width:"100%",height:"100%",paddingLeft:r?Ke[e]:ne[e],paddingRight:i?Ke[e]:ne[e],fontSize:Ye[e],fontFamily:"var(--lucent-font-family-base)",color:S?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",background:"transparent",border:"none",outline:"none",cursor:S?"not-allowed":void 0,boxSizing:"border-box"},onFocus:k=>{var z;b(!0),(z=p.onFocus)==null||z.call(p,k)},onBlur:k=>{var z;b(!1),(z=p.onBlur)==null||z.call(p,k)},...p}),i&&t.jsx("span",{style:{position:"absolute",right:ne[e],color:S?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",display:"flex",alignItems:"center"},children:i})]}),l&&t.jsx("span",{style:F,children:l})]}),u&&t.jsx("span",{id:`${h}-error`,role:"alert",style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-danger-text)",fontFamily:"var(--lucent-font-family-base)"},children:o}),!u&&a&&t.jsx("span",{id:`${h}-helper`,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:a})]})});K.displayName="Input";const Wt={id:"input",name:"Input",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A single-line text field with optional label, helper text, and error state.",designIntent:"Always pair with a visible label — never rely on placeholder text alone as it disappears on input and is inaccessible. Use errorText (not helperText) to surface validation failures; the component applies danger styling automatically. leftElement and rightElement accept icons or small controls (e.g. currency symbol, clear button).",props:[{name:"type",type:"enum",required:!1,default:"text",description:"HTML input type.",enumValues:["text","number","password","email","tel","url","search"]},{name:"label",type:"string",required:!1,description:"Visible label rendered above the input."},{name:"helperText",type:"string",required:!1,description:"Supplementary hint shown below the input."},{name:"errorText",type:"string",required:!1,description:"Validation error message. When set, input renders in error state."},{name:"leftElement",type:"ReactNode",required:!1,description:"Icon or adornment rendered inside the left edge."},{name:"rightElement",type:"ReactNode",required:!1,description:"Icon or adornment rendered inside the right edge."},{name:"placeholder",type:"string",required:!1,description:"Placeholder text. Use as a hint, not a label."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the input."},{name:"value",type:"string",required:!1,description:"Controlled value."},{name:"onChange",type:"function",required:!1,description:"Change handler."}],usageExamples:[{title:"Basic",code:'<Input label="Email" type="email" placeholder="you@example.com" />'},{title:"With helper text",code:'<Input label="Username" helperText="3–20 characters, letters and numbers only" />'},{title:"Error state",code:'<Input label="Password" type="password" value={value} errorText="Must be at least 8 characters" />'},{title:"With icon",code:'<Input label="Search" leftElement={<SearchIcon />} placeholder="Search…" />'}],compositionGraph:[],accessibility:{role:"textbox",ariaAttributes:["aria-invalid","aria-describedby","aria-label"],keyboardInteractions:["Tab — focuses the input"]}},dt=f.forwardRef(({label:e,helperText:n,errorText:a,autoResize:o=!1,maxLength:r,showCount:i=!1,id:s,value:l,onChange:c,disabled:d,style:p,...m},h)=>{const u=f.useRef(null),S=h??u,y=s??`lucent-textarea-${Math.random().toString(36).slice(2,7)}`,b=!!a,v=!!d,w=typeof l=="string"?l.length:0;f.useEffect(()=>{if(!o)return;const T=S.current;T&&(T.style.height="auto",T.style.height=`${T.scrollHeight}px`)},[l,o,S]);const j=v?"transparent":b?"var(--lucent-danger-default)":"var(--lucent-border-default)";return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%"},children:[e&&t.jsx("label",{htmlFor:y,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:v?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:e}),t.jsx("textarea",{ref:S,id:y,maxLength:r,value:l,onChange:c,disabled:d,"aria-invalid":b,"aria-describedby":b?`${y}-error`:n?`${y}-helper`:void 0,style:{width:"100%",minHeight:"100px",padding:"var(--lucent-space-3)",fontSize:"var(--lucent-font-size-md)",fontFamily:"var(--lucent-font-family-base)",color:v?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",background:v?"var(--lucent-surface-secondary)":"var(--lucent-surface)",border:`1px solid ${j}`,borderRadius:"var(--lucent-radius-lg)",outline:"none",resize:o?"none":"vertical",boxSizing:"border-box",lineHeight:"var(--lucent-line-height-base)",cursor:v?"not-allowed":void 0,transition:["border-color var(--lucent-duration-fast) var(--lucent-easing-default)","box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", "),...p},onMouseEnter:T=>{var x;!v&&T.currentTarget!==document.activeElement&&(T.currentTarget.style.borderColor=b?"var(--lucent-danger-default)":"var(--lucent-border-strong)"),(x=m.onMouseEnter)==null||x.call(m,T)},onMouseLeave:T=>{var x;!v&&T.currentTarget!==document.activeElement&&(T.currentTarget.style.borderColor=b?"var(--lucent-danger-default)":"var(--lucent-border-default)"),(x=m.onMouseLeave)==null||x.call(m,T)},onFocus:T=>{var x;v||(T.currentTarget.style.borderColor=b?"var(--lucent-danger-default)":"var(--lucent-focus-ring)",T.currentTarget.style.boxShadow=`0 0 0 3px ${b?"var(--lucent-danger-subtle)":"var(--lucent-accent-subtle)"}`,(x=m.onFocus)==null||x.call(m,T))},onBlur:T=>{var x;v||(T.currentTarget.style.borderColor=b?"var(--lucent-danger-default)":"var(--lucent-border-default)",T.currentTarget.style.boxShadow="none",(x=m.onBlur)==null||x.call(m,T))},...m}),t.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start"},children:[t.jsxs("div",{children:[b&&t.jsx("span",{id:`${y}-error`,role:"alert",style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-danger-text)",fontFamily:"var(--lucent-font-family-base)"},children:a}),!b&&n&&t.jsx("span",{id:`${y}-helper`,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:n})]}),(i||r)&&t.jsxs("span",{style:{fontSize:"var(--lucent-font-size-xs)",color:r&&w>=r?"var(--lucent-danger-text)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-mono)",flexShrink:0,marginLeft:"var(--lucent-space-2)"},children:[w,r?`/${r}`:""]})]})]})});dt.displayName="Textarea";const Ot={id:"textarea",name:"Textarea",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A multi-line text input with optional auto-resize and character count.",designIntent:"Use autoResize for open-ended fields (bio, description) where content length is unpredictable. Use maxLength + showCount for fields with hard limits (tweet-style). Behaves identically to Input for label/helper/error patterns.",props:[{name:"label",type:"string",required:!1,description:"Visible label above the textarea."},{name:"helperText",type:"string",required:!1,description:"Hint text shown below."},{name:"errorText",type:"string",required:!1,description:"Validation error. Triggers error styling."},{name:"autoResize",type:"boolean",required:!1,default:"false",description:"Grows with content, disables manual resize handle."},{name:"maxLength",type:"number",required:!1,description:"Character limit. Displays counter when set."},{name:"showCount",type:"boolean",required:!1,default:"false",description:"Always show character counter even without maxLength."},{name:"value",type:"string",required:!1,description:"Controlled value."},{name:"onChange",type:"function",required:!1,description:"Change handler."},{name:"placeholder",type:"string",required:!1,description:"Placeholder text."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the textarea."}],usageExamples:[{title:"Basic",code:'<Textarea label="Bio" placeholder="Tell us about yourself…" />'},{title:"Auto-resize",code:'<Textarea label="Description" autoResize value={value} onChange={e => setValue(e.target.value)} />'},{title:"With character count",code:'<Textarea label="Tweet" maxLength={280} showCount value={value} onChange={e => setValue(e.target.value)} />'},{title:"Error state",code:'<Textarea label="Notes" errorText="Required" value="" />'}],compositionGraph:[],accessibility:{role:"textbox",ariaAttributes:["aria-multiline","aria-invalid","aria-describedby"],keyboardInteractions:["Tab — focuses the textarea"]}},Vt={neutral:{bg:"var(--lucent-surface-secondary)",color:"var(--lucent-text-secondary)",border:"var(--lucent-border-default)"},accent:{bg:"var(--lucent-accent-default)",color:"var(--lucent-text-on-accent)",border:"var(--lucent-accent-default)"},success:{bg:"var(--lucent-success-subtle)",color:"var(--lucent-success-text)",border:"var(--lucent-success-subtle)"},warning:{bg:"var(--lucent-warning-subtle)",color:"var(--lucent-warning-text)",border:"var(--lucent-warning-subtle)"},danger:{bg:"var(--lucent-danger-subtle)",color:"var(--lucent-danger-text)",border:"var(--lucent-danger-subtle)"},info:{bg:"var(--lucent-info-subtle)",color:"var(--lucent-info-text)",border:"var(--lucent-info-subtle)"}},Ht={sm:{fontSize:"var(--lucent-font-size-xs)",padding:"0 var(--lucent-space-2)",height:"18px"},md:{fontSize:"var(--lucent-font-size-sm)",padding:"0 var(--lucent-space-2)",height:"22px"}};function Gt({variant:e="neutral",size:n="md",dot:a=!1,children:o,style:r}){const i=Vt[e],s=Ht[n];return t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",height:s.height,padding:s.padding,fontSize:s.fontSize,fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:1,borderRadius:"var(--lucent-radius-full)",background:i.bg,color:i.color,border:`1px solid ${i.border}`,whiteSpace:"nowrap",boxSizing:"border-box",...r},children:[a&&t.jsx("span",{style:{width:6,height:6,borderRadius:"var(--lucent-radius-full)",background:"currentColor",flexShrink:0}}),o]})}const Ut={id:"badge",name:"Badge",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A small inline label for status, count, or category.",designIntent:'Badges communicate status or category at a glance. Match variant to semantic meaning — never use "danger" for non-critical states or "success" for neutral counts. Use dot=true when a single colour indicator is enough context (e.g. online status). Keep badge text short: 1–3 words maximum.',props:[{name:"variant",type:"enum",required:!1,default:"neutral",description:"Colour scheme conveying semantic meaning.",enumValues:["neutral","success","warning","danger","info","accent"]},{name:"size",type:"enum",required:!1,default:"md",description:"Controls height and font size.",enumValues:["sm","md"]},{name:"dot",type:"boolean",required:!1,default:"false",description:"Prepends a coloured dot indicator."},{name:"children",type:"ReactNode",required:!0,description:"Badge label."}],usageExamples:[{title:"Status",code:'<Badge variant="success" dot>Active</Badge>'},{title:"Count",code:'<Badge variant="danger">12</Badge>'},{title:"Category",code:'<Badge variant="info">Beta</Badge>'},{title:"Neutral tag",code:"<Badge>Draft</Badge>"}],compositionGraph:[],accessibility:{role:"status",notes:"Use aria-label on the parent element when badge meaning depends on context."}},_t={xs:24,sm:32,md:40,lg:56,xl:80},Yt={xs:"var(--lucent-font-size-xs)",sm:"var(--lucent-font-size-xs)",md:"var(--lucent-font-size-sm)",lg:"var(--lucent-font-size-lg)",xl:"var(--lucent-font-size-xl)"};function Kt(e,n){var o,r,i;if(n)return n.slice(0,2).toUpperCase();const a=e.trim().split(/\s+/);return a.length===1?(((o=a[0])==null?void 0:o[0])??"").toUpperCase():((((r=a[0])==null?void 0:r[0])??"")+(((i=a[a.length-1])==null?void 0:i[0])??"")).toUpperCase()}function Xt({src:e,alt:n,size:a="md",initials:o,style:r,...i}){const s=_t[a],l=Kt(n,o),c={width:s,height:s,borderRadius:"var(--lucent-radius-full)",flexShrink:0,display:"inline-flex",alignItems:"center",justifyContent:"center",overflow:"hidden",boxSizing:"border-box",userSelect:"none",...r};return e?t.jsx("img",{src:e,alt:n,width:s,height:s,style:{...c,objectFit:"cover"},...i}):t.jsx("span",{role:"img","aria-label":n,style:{...c,background:"var(--lucent-accent-default)",color:"var(--lucent-text-on-accent)",fontSize:Yt[a],fontWeight:"var(--lucent-font-weight-semibold)",fontFamily:"var(--lucent-font-family-base)"},children:l})}const Jt={id:"avatar",name:"Avatar",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A circular user image with initials fallback.",designIntent:"Always provide alt for accessibility — it is used to derive initials automatically when src is absent or fails. Use initials prop to override auto-derived initials (e.g. for non-Latin names). Size xs/sm suit table rows and compact lists; md is the default for comment threads; lg/xl for profile headers.",props:[{name:"src",type:"string",required:!1,description:"Image URL. Falls back to initials if omitted or fails to load."},{name:"alt",type:"string",required:!0,description:"Alt text and source for auto-derived initials."},{name:"size",type:"enum",required:!1,default:"md",description:"Diameter of the avatar.",enumValues:["xs","sm","md","lg","xl"]},{name:"initials",type:"string",required:!1,description:"Override auto-derived initials (max 2 characters)."}],usageExamples:[{title:"With image",code:'<Avatar src="/avatars/jane.jpg" alt="Jane Doe" />'},{title:"Initials fallback",code:'<Avatar alt="Jane Doe" />'},{title:"Large profile",code:'<Avatar src={user.avatar} alt={user.name} size="lg" />'},{title:"Custom initials",code:'<Avatar alt="张伟" initials="张" size="md" />'}],compositionGraph:[],accessibility:{role:"img",ariaAttributes:["aria-label"],notes:'When src is present, renders as <img> with alt. When showing initials, renders as <span role="img" aria-label>.'}},Zt={xs:12,sm:16,md:24,lg:36},Qt={xs:2.5,sm:2.5,md:2,lg:2};function ut({size:e="md",label:n="Loading…",color:a}){const o=Zt[e],r=Qt[e];return t.jsxs("span",{role:"status","aria-label":n,style:{display:"inline-flex",alignItems:"center",justifyContent:"center"},children:[t.jsxs("svg",{width:o,height:o,viewBox:"0 0 24 24",fill:"none","aria-hidden":!0,style:{animation:"lucent-spin 0.7s linear infinite",color:a??"currentColor"},children:[t.jsx("style",{children:"@keyframes lucent-spin { to { transform: rotate(360deg); } }"}),t.jsx("circle",{cx:12,cy:12,r:10,stroke:"currentColor",strokeWidth:r,strokeOpacity:.2}),t.jsx("path",{d:"M12 2a10 10 0 0 1 10 10",stroke:"currentColor",strokeWidth:r,strokeLinecap:"round"})]}),t.jsx("span",{style:{position:"absolute",width:1,height:1,overflow:"hidden",clip:"rect(0,0,0,0)",whiteSpace:"nowrap"},children:n})]})}const en={id:"spinner",name:"Spinner",tier:"atom",domain:"neutral",specVersion:"0.1",description:"An animated loading indicator for async operations.",designIntent:"Use Spinner for indeterminate loading states of short duration (< 3s). For full-page or skeleton-level loading, prefer Skeleton instead. The label prop is visually hidden but read by screen readers — always set it to a meaningful description of what is loading.",props:[{name:"size",type:"enum",required:!1,default:"md",description:"Spinner diameter.",enumValues:["xs","sm","md","lg"]},{name:"label",type:"string",required:!1,default:"Loading…",description:"Visually hidden accessible label."},{name:"color",type:"string",required:!1,description:"Override colour (CSS value). Defaults to currentColor."}],usageExamples:[{title:"Default",code:"<Spinner />"},{title:"Inside button",code:'<Button loading><Spinner size="sm" label="Saving…" /></Button>'},{title:"Full-page overlay",code:`<div style={{ display: 'grid', placeItems: 'center', minHeight: '100vh' }}><Spinner size="lg" label="Loading dashboard…" /></div>`}],compositionGraph:[],accessibility:{role:"status",ariaAttributes:["aria-label"],notes:'The visible SVG is aria-hidden. The label is conveyed via a visually-hidden span inside role="status".'}};function tn({orientation:e="horizontal",label:n,spacing:a="var(--lucent-space-4)",style:o}){return e==="vertical"?t.jsx("span",{role:"separator","aria-orientation":"vertical",style:{display:"inline-block",width:"1px",alignSelf:"stretch",background:"var(--lucent-border-default)",margin:`0 ${a}`,flexShrink:0,...o}}):n?t.jsxs("div",{role:"separator","aria-label":n,style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",margin:`${a} 0`,...o},children:[t.jsx("span",{style:{flex:1,height:"1px",background:"var(--lucent-border-default)"}}),t.jsx("span",{style:{fontSize:"var(--lucent-font-size-xs)",fontFamily:"var(--lucent-font-family-base)",color:"var(--lucent-text-secondary)",whiteSpace:"nowrap",letterSpacing:"var(--lucent-letter-spacing-wide)",textTransform:"uppercase"},children:n}),t.jsx("span",{style:{flex:1,height:"1px",background:"var(--lucent-border-default)"}})]}):t.jsx("hr",{role:"separator",style:{border:"none",borderTop:"1px solid var(--lucent-border-default)",margin:`${a} 0`,width:"100%",...o}})}const nn={id:"divider",name:"Divider",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A visual separator between content sections, horizontal or vertical.",designIntent:'Use horizontal Divider to separate sections in a layout. Use vertical Divider inline between sibling elements (e.g. nav links, toolbar buttons). Use the label prop for "OR" separators in auth flows or form sections — never use a plain text node next to a divider for this.',props:[{name:"orientation",type:"enum",required:!1,default:"horizontal",description:"Direction of the divider line.",enumValues:["horizontal","vertical"]},{name:"label",type:"string",required:!1,description:'Optional centered label (horizontal only). Common use: "OR", "AND", section titles.'},{name:"spacing",type:"string",required:!1,default:"var(--lucent-space-4)",description:"Margin on the axis perpendicular to the line."}],usageExamples:[{title:"Section separator",code:"<Divider />"},{title:"With label",code:'<Divider label="OR" />'},{title:"Vertical in nav",code:`<nav style={{ display: 'flex', alignItems: 'center' }}><a>Home</a><Divider orientation="vertical" /><a>About</a></nav>`}],compositionGraph:[],accessibility:{role:"separator",ariaAttributes:["aria-orientation","aria-label"]}},an={sm:14,md:16},rn=`
2
2
  @keyframes lucent-cb-pop {
3
3
  0% { transform: scale(1); }
4
4
  35% { transform: scale(0.82); }
@@ -10,7 +10,7 @@
10
10
  60% { transform: scale(1.15) rotate(2deg); }
11
11
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
12
12
  }
13
- `,Ie=p.forwardRef(({label:e,size:n="md",indeterminate:a=!1,checked:o,defaultChecked:r,disabled:i,id:s,onChange:l,style:c,...u},f)=>{const d=p.useRef(null),y=s??`lucent-checkbox-${Math.random().toString(36).slice(2,7)}`,h=nn[n],w=o!==void 0,[v,g]=p.useState(r??!1),b=w?!!o:v,k=p.useRef(b),[D,S]=p.useState(0);p.useEffect(()=>{!i&&k.current!==b&&(k.current=b,S(C=>C+1))},[b,i]);const x=p.useCallback(C=>{d.current=C,typeof f=="function"?f(C):f&&(f.current=C)},[f]);p.useEffect(()=>{d.current&&(d.current.indeterminate=a)},[a]);const z=C=>{w||g(C.target.checked),l==null||l(C)},q=i?"var(--lucent-text-disabled)":"var(--lucent-text-on-accent)",T={width:h,height:h,borderRadius:"4px",border:`1.5px solid ${i?"transparent":b||a?"var(--lucent-accent-default)":"var(--lucent-border-strong)"}`,background:i?"var(--lucent-surface-secondary)":b||a?"var(--lucent-accent-default)":"var(--lucent-surface)",display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), border-color var(--lucent-duration-fast) var(--lucent-easing-default)",animation:D>0?"lucent-cb-pop 220ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards":void 0};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:an}),t.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",cursor:i?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:n==="sm"?"var(--lucent-font-size-sm)":"var(--lucent-font-size-md)",color:i?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",userSelect:"none",...c},children:[t.jsx("input",{ref:x,type:"checkbox",id:y,checked:w?o:v,disabled:i,onChange:z,style:{position:"absolute",opacity:0,width:0,height:0,margin:0,pointerEvents:"none"},...u}),t.jsxs("span",{"aria-hidden":!0,style:T,children:[b&&!a&&t.jsx("svg",{width:h-4,height:h-4,viewBox:"0 0 10 10",fill:"none",style:{animation:"lucent-cb-mark 200ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards"},children:t.jsx("path",{d:"M1.5 5L4 7.5L8.5 2.5",stroke:q,strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})}),a&&t.jsx("svg",{width:h-4,height:h-4,viewBox:"0 0 10 10",fill:"none",style:{animation:"lucent-cb-mark 200ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards"},children:t.jsx("path",{d:"M2 5H8",stroke:q,strokeWidth:1.5,strokeLinecap:"round"})})]},D),e]})]})});Ie.displayName="Checkbox";const rn={id:"checkbox",name:"Checkbox",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A binary selection control for boolean values or multi-select lists.",designIntent:'Checkboxes represent independent boolean choices — they do not affect each other. Use a Checkbox for settings that take effect immediately (e.g. "Remember me") or for selecting multiple items from a list. When only one option may be active at a time, use Radio instead. The indeterminate state communicates a "select all" parent whose children are partially checked — never use it for a third logical state.',props:[{name:"checked",type:"boolean",required:!1,description:"Controlled checked state. Pair with onChange for controlled usage."},{name:"defaultChecked",type:"boolean",required:!1,default:"false",description:"Initial checked state for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called when the checked state changes."},{name:"label",type:"string",required:!1,description:"Visible label rendered beside the checkbox."},{name:"indeterminate",type:"boolean",required:!1,default:"false",description:"Displays a dash to indicate a partially-checked parent state."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the control."},{name:"size",type:"enum",required:!1,default:"md",description:"Size of the checkbox box.",enumValues:["sm","md"]}],usageExamples:[{title:"Controlled",code:'<Checkbox checked={agreed} onChange={e => setAgreed(e.target.checked)} label="I agree to the terms" />'},{title:"Uncontrolled",code:'<Checkbox defaultChecked label="Send me updates" />'},{title:"Indeterminate",code:'<Checkbox indeterminate label="Select all" />'},{title:"Disabled",code:'<Checkbox disabled label="Unavailable option" />'}],compositionGraph:[],accessibility:{role:"checkbox",ariaAttributes:["aria-checked","aria-disabled"],keyboardInteractions:["Space — toggles checked state"]}},on=`
13
+ `,Ie=f.forwardRef(({label:e,size:n="md",indeterminate:a=!1,checked:o,defaultChecked:r,disabled:i,id:s,onChange:l,style:c,...d},p)=>{const m=f.useRef(null),h=s??`lucent-checkbox-${Math.random().toString(36).slice(2,7)}`,u=an[n],S=o!==void 0,[y,b]=f.useState(r??!1),v=S?!!o:y,w=f.useRef(v),[j,T]=f.useState(0);f.useEffect(()=>{!i&&w.current!==v&&(w.current=v,T(z=>z+1))},[v,i]);const x=f.useCallback(z=>{m.current=z,typeof p=="function"?p(z):p&&(p.current=z)},[p]);f.useEffect(()=>{m.current&&(m.current.indeterminate=a)},[a]);const M=z=>{S||b(z.target.checked),l==null||l(z)},F=i?"var(--lucent-text-disabled)":"var(--lucent-text-on-accent)",k={width:u,height:u,borderRadius:"4px",border:`1.5px solid ${i?"transparent":v||a?"var(--lucent-accent-default)":"var(--lucent-border-strong)"}`,background:i?"var(--lucent-surface-secondary)":v||a?"var(--lucent-accent-default)":"var(--lucent-surface)",display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), border-color var(--lucent-duration-fast) var(--lucent-easing-default)",animation:j>0?"lucent-cb-pop 220ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards":void 0};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:rn}),t.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",cursor:i?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:n==="sm"?"var(--lucent-font-size-sm)":"var(--lucent-font-size-md)",color:i?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",userSelect:"none",...c},children:[t.jsx("input",{ref:x,type:"checkbox",id:h,checked:S?o:y,disabled:i,onChange:M,style:{position:"absolute",opacity:0,width:0,height:0,margin:0,pointerEvents:"none"},...d}),t.jsxs("span",{"aria-hidden":!0,style:k,children:[v&&!a&&t.jsx("svg",{width:u-4,height:u-4,viewBox:"0 0 10 10",fill:"none",style:{animation:"lucent-cb-mark 200ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards"},children:t.jsx("path",{d:"M1.5 5L4 7.5L8.5 2.5",stroke:F,strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"})}),a&&t.jsx("svg",{width:u-4,height:u-4,viewBox:"0 0 10 10",fill:"none",style:{animation:"lucent-cb-mark 200ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards"},children:t.jsx("path",{d:"M2 5H8",stroke:F,strokeWidth:1.5,strokeLinecap:"round"})})]},j),e]})]})});Ie.displayName="Checkbox";const on={id:"checkbox",name:"Checkbox",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A binary selection control for boolean values or multi-select lists.",designIntent:'Checkboxes represent independent boolean choices — they do not affect each other. Use a Checkbox for settings that take effect immediately (e.g. "Remember me") or for selecting multiple items from a list. When only one option may be active at a time, use Radio instead. The indeterminate state communicates a "select all" parent whose children are partially checked — never use it for a third logical state.',props:[{name:"checked",type:"boolean",required:!1,description:"Controlled checked state. Pair with onChange for controlled usage."},{name:"defaultChecked",type:"boolean",required:!1,default:"false",description:"Initial checked state for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called when the checked state changes."},{name:"label",type:"string",required:!1,description:"Visible label rendered beside the checkbox."},{name:"indeterminate",type:"boolean",required:!1,default:"false",description:"Displays a dash to indicate a partially-checked parent state."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the control."},{name:"size",type:"enum",required:!1,default:"md",description:"Size of the checkbox box.",enumValues:["sm","md"]}],usageExamples:[{title:"Controlled",code:'<Checkbox checked={agreed} onChange={e => setAgreed(e.target.checked)} label="I agree to the terms" />'},{title:"Uncontrolled",code:'<Checkbox defaultChecked label="Send me updates" />'},{title:"Indeterminate",code:'<Checkbox indeterminate label="Select all" />'},{title:"Disabled",code:'<Checkbox disabled label="Unavailable option" />'}],compositionGraph:[],accessibility:{role:"checkbox",ariaAttributes:["aria-checked","aria-disabled"],keyboardInteractions:["Space — toggles checked state"]}},sn=`
14
14
  @keyframes lucent-radio-pop {
15
15
  0% { transform: scale(1); }
16
16
  35% { transform: scale(0.82); }
@@ -22,7 +22,7 @@
22
22
  60% { transform: scale(1.2); }
23
23
  100% { opacity: 1; transform: scale(1); }
24
24
  }
25
- `,pt=p.createContext(null);function ft({name:e,value:n,onChange:a,disabled:o,orientation:r="vertical",label:i,children:s}){return t.jsx(pt.Provider,{value:{name:e,value:n,onChange:a,disabled:o??!1},children:t.jsx("div",{role:"radiogroup","aria-label":i,style:{display:"flex",flexDirection:r==="vertical"?"column":"row",gap:r==="vertical"?"var(--lucent-space-3)":"var(--lucent-space-4)",flexWrap:"wrap"},children:s})})}const sn={sm:14,md:16};function ln({value:e,label:n,size:a="md",disabled:o,id:r,onChange:i,checked:s,...l}){const c=p.useContext(pt),u=r??`lucent-radio-${Math.random().toString(36).slice(2,7)}`,f=sn[a],d=o??(c==null?void 0:c.disabled)??!1,y=c?c.value===e:!!s,h=p.useRef(y),[w,v]=p.useState(0);p.useEffect(()=>{!d&&h.current!==y&&(h.current=y,v(D=>D+1))},[y,d]);const g=D=>{c==null||c.onChange(e),i==null||i(D)},b={width:f/2,height:f/2,borderRadius:"50%",background:d?"var(--lucent-text-disabled)":"var(--lucent-text-on-accent)",animation:y?"lucent-radio-dot 200ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards":void 0,opacity:y?1:0},k={width:f,height:f,borderRadius:"50%",border:`1.5px solid ${d?"transparent":y?"var(--lucent-accent-default)":"var(--lucent-border-strong)"}`,background:d?"var(--lucent-surface-secondary)":y?"var(--lucent-accent-default)":"var(--lucent-surface)",display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), border-color var(--lucent-duration-fast) var(--lucent-easing-default)",animation:w>0?"lucent-radio-pop 220ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards":void 0};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:on}),t.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",cursor:d?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:a==="sm"?"var(--lucent-font-size-sm)":"var(--lucent-font-size-md)",color:d?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",userSelect:"none"},children:[t.jsx("input",{type:"radio",id:u,value:e,name:(c==null?void 0:c.name)??l.name,checked:y,disabled:d,onChange:g,style:{position:"absolute",opacity:0,width:0,height:0,margin:0,pointerEvents:"none"},...l}),t.jsx("span",{"aria-hidden":!0,style:k,children:t.jsx("span",{style:b})},w),n]})]})}function cn({defaultValue:e="",onChange:n,...a}){const[o,r]=p.useState(e);return t.jsx(ft,{...a,value:o,onChange:i=>{r(i),n==null||n(i)}})}const dn={id:"radio",name:"Radio",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A mutually exclusive selection control. Use RadioGroup to manage a set of options.",designIntent:"Radio buttons enforce a single selection from a small set of options (typically 2–6). Always wrap Radio in a RadioGroup so name and selection state are shared automatically. For larger option sets (7+) prefer a Select. For independent true/false choices, use a Checkbox. RadioGroup orientation should match how the options relate — vertical for distinct choices, horizontal for brief inline options (e.g. Yes / No).",props:[{name:"value",type:"string",required:!0,description:"The value submitted when this radio is selected."},{name:"label",type:"string",required:!1,description:"Visible label rendered beside the radio button."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction. Inherits group-level disabled when inside RadioGroup."},{name:"size",type:"enum",required:!1,default:"md",description:"Size of the radio button circle.",enumValues:["sm","md"]}],usageExamples:[{title:"Controlled RadioGroup",code:`
25
+ `,pt=f.createContext(null);function ft({name:e,value:n,onChange:a,disabled:o,orientation:r="vertical",label:i,children:s}){return t.jsx(pt.Provider,{value:{name:e,value:n,onChange:a,disabled:o??!1},children:t.jsx("div",{role:"radiogroup","aria-label":i,style:{display:"flex",flexDirection:r==="vertical"?"column":"row",gap:r==="vertical"?"var(--lucent-space-3)":"var(--lucent-space-4)",flexWrap:"wrap"},children:s})})}const ln={sm:14,md:16};function cn({value:e,label:n,size:a="md",disabled:o,id:r,onChange:i,checked:s,...l}){const c=f.useContext(pt),d=r??`lucent-radio-${Math.random().toString(36).slice(2,7)}`,p=ln[a],m=o??(c==null?void 0:c.disabled)??!1,h=c?c.value===e:!!s,u=f.useRef(h),[S,y]=f.useState(0);f.useEffect(()=>{!m&&u.current!==h&&(u.current=h,y(j=>j+1))},[h,m]);const b=j=>{c==null||c.onChange(e),i==null||i(j)},v={width:p/2,height:p/2,borderRadius:"50%",background:m?"var(--lucent-text-disabled)":"var(--lucent-text-on-accent)",animation:h?"lucent-radio-dot 200ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards":void 0,opacity:h?1:0},w={width:p,height:p,borderRadius:"50%",border:`1.5px solid ${m?"transparent":h?"var(--lucent-accent-default)":"var(--lucent-border-strong)"}`,background:m?"var(--lucent-surface-secondary)":h?"var(--lucent-accent-default)":"var(--lucent-surface)",display:"inline-flex",alignItems:"center",justifyContent:"center",flexShrink:0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), border-color var(--lucent-duration-fast) var(--lucent-easing-default)",animation:S>0?"lucent-radio-pop 220ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards":void 0};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:sn}),t.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",cursor:m?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:a==="sm"?"var(--lucent-font-size-sm)":"var(--lucent-font-size-md)",color:m?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",userSelect:"none"},children:[t.jsx("input",{type:"radio",id:d,value:e,name:(c==null?void 0:c.name)??l.name,checked:h,disabled:m,onChange:b,style:{position:"absolute",opacity:0,width:0,height:0,margin:0,pointerEvents:"none"},...l}),t.jsx("span",{"aria-hidden":!0,style:w,children:t.jsx("span",{style:v})},S),n]})]})}function dn({defaultValue:e="",onChange:n,...a}){const[o,r]=f.useState(e);return t.jsx(ft,{...a,value:o,onChange:i=>{r(i),n==null||n(i)}})}const un={id:"radio",name:"Radio",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A mutually exclusive selection control. Use RadioGroup to manage a set of options.",designIntent:"Radio buttons enforce a single selection from a small set of options (typically 2–6). Always wrap Radio in a RadioGroup so name and selection state are shared automatically. For larger option sets (7+) prefer a Select. For independent true/false choices, use a Checkbox. RadioGroup orientation should match how the options relate — vertical for distinct choices, horizontal for brief inline options (e.g. Yes / No).",props:[{name:"value",type:"string",required:!0,description:"The value submitted when this radio is selected."},{name:"label",type:"string",required:!1,description:"Visible label rendered beside the radio button."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction. Inherits group-level disabled when inside RadioGroup."},{name:"size",type:"enum",required:!1,default:"md",description:"Size of the radio button circle.",enumValues:["sm","md"]}],usageExamples:[{title:"Controlled RadioGroup",code:`
26
26
  <RadioGroup name="plan" value={plan} onChange={setPlan}>
27
27
  <Radio value="free" label="Free" />
28
28
  <Radio value="pro" label="Pro" />
@@ -36,23 +36,23 @@
36
36
  <RadioGroup name="tier" value="basic" onChange={() => {}} disabled>
37
37
  <Radio value="basic" label="Basic" />
38
38
  <Radio value="advanced" label="Advanced" />
39
- </RadioGroup>`.trim()}],compositionGraph:[{componentId:"radio-group",componentName:"RadioGroup",role:"container",required:!0},{componentId:"radio",componentName:"Radio",role:"item",required:!0}],accessibility:{role:"radio",ariaAttributes:["aria-checked","aria-disabled"],keyboardInteractions:["Arrow keys — move selection within the group","Space — selects the focused radio"]}},un={sm:{track:[28,16],thumb:12},md:{track:[36,20],thumb:16},lg:{track:[44,24],thumb:20}},Xe="cubic-bezier(0.34, 1.56, 0.64, 1)",pn=`
39
+ </RadioGroup>`.trim()}],compositionGraph:[{componentId:"radio-group",componentName:"RadioGroup",role:"container",required:!0},{componentId:"radio",componentName:"Radio",role:"item",required:!0}],accessibility:{role:"radio",ariaAttributes:["aria-checked","aria-disabled"],keyboardInteractions:["Arrow keys — move selection within the group","Space — selects the focused radio"]}},pn={sm:{track:[28,16],thumb:12},md:{track:[36,20],thumb:16},lg:{track:[44,24],thumb:20}},Xe="cubic-bezier(0.34, 1.56, 0.64, 1)",fn=`
40
40
  @keyframes lucent-toggle-pop {
41
41
  0% { transform: scale(1); }
42
42
  35% { transform: scale(0.94); }
43
43
  70% { transform: scale(1.06); }
44
44
  100% { transform: scale(1); }
45
45
  }
46
- `;function fn({label:e,size:n="md",checked:a,defaultChecked:o,disabled:r,id:i,onChange:s,style:l,...c}){const u=i??`lucent-toggle-${Math.random().toString(36).slice(2,7)}`,f=a!==void 0,[d,y]=p.useState(o??!1),h=f?!!a:d,w=p.useRef(h),[v,g]=p.useState(0);p.useEffect(()=>{!r&&w.current!==h&&(w.current=h,g(z=>z+1))},[h,r]);const{track:[b,k],thumb:D}=un[n],S=h?b-D-2:2,x=z=>{f||y(z.target.checked),s==null||s(z)};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:pn}),t.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",cursor:r?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",color:r?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",userSelect:"none",...l},children:[t.jsx("input",{type:"checkbox",role:"switch",id:u,checked:f?a:d,disabled:r,onChange:x,"aria-checked":h,style:{position:"absolute",opacity:0,width:0,height:0,margin:0,pointerEvents:"none"},...c}),t.jsx("span",{"aria-hidden":!0,style:{position:"relative",width:b,height:k,borderRadius:k/2,background:r?"var(--lucent-surface-secondary)":h?"var(--lucent-accent-default)":"var(--lucent-border-strong)",flexShrink:0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)",animation:v>0?`lucent-toggle-pop 240ms ${Xe} forwards`:void 0},children:t.jsx("span",{style:{position:"absolute",top:2,left:S,width:D,height:D,borderRadius:"50%",background:"#ffffff",boxShadow:"0 1px 3px rgb(0 0 0 / 0.2)",transition:`left 260ms ${Xe}`}})},v),e]})]})}const hn={id:"toggle",name:"Toggle",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A sliding switch for immediately-applied binary settings.",designIntent:'Toggles are for settings that take effect the moment they are flipped — no Save button needed. If the action requires a confirmation step or only applies on form submit, use a Checkbox instead. The "on" state is visually represented by the accent colour so the meaning is clear without relying on text alone. Keep the label short (2–4 words) and phrase it as the enabled state (e.g. "Dark mode", not "Enable dark mode").',props:[{name:"checked",type:"boolean",required:!1,description:"Controlled on/off state. Pair with onChange for controlled usage."},{name:"defaultChecked",type:"boolean",required:!1,default:"false",description:"Initial state for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called when the toggle is flipped."},{name:"label",type:"string",required:!1,description:"Visible label rendered beside the toggle."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls the track and thumb size.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the control."}],usageExamples:[{title:"Controlled",code:'<Toggle checked={darkMode} onChange={e => setDarkMode(e.target.checked)} label="Dark mode" />'},{title:"Uncontrolled",code:'<Toggle defaultChecked label="Email notifications" />'},{title:"Sizes",code:`<Toggle size="sm" label="Compact" />
46
+ `;function hn({label:e,size:n="md",checked:a,defaultChecked:o,disabled:r,id:i,onChange:s,style:l,...c}){const d=i??`lucent-toggle-${Math.random().toString(36).slice(2,7)}`,p=a!==void 0,[m,h]=f.useState(o??!1),u=p?!!a:m,S=f.useRef(u),[y,b]=f.useState(0);f.useEffect(()=>{!r&&S.current!==u&&(S.current=u,b(M=>M+1))},[u,r]);const{track:[v,w],thumb:j}=pn[n],T=u?v-j-2:2,x=M=>{p||h(M.target.checked),s==null||s(M)};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:fn}),t.jsxs("label",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",cursor:r?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",color:r?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",userSelect:"none",...l},children:[t.jsx("input",{type:"checkbox",role:"switch",id:d,checked:p?a:m,disabled:r,onChange:x,"aria-checked":u,style:{position:"absolute",opacity:0,width:0,height:0,margin:0,pointerEvents:"none"},...c}),t.jsx("span",{"aria-hidden":!0,style:{position:"relative",width:v,height:w,borderRadius:w/2,background:r?"var(--lucent-surface-secondary)":u?"var(--lucent-accent-default)":"var(--lucent-border-strong)",flexShrink:0,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)",animation:y>0?`lucent-toggle-pop 240ms ${Xe} forwards`:void 0},children:t.jsx("span",{style:{position:"absolute",top:2,left:T,width:j,height:j,borderRadius:"50%",background:"#ffffff",boxShadow:"0 1px 3px rgb(0 0 0 / 0.2)",transition:`left 260ms ${Xe}`}})},y),e]})]})}const mn={id:"toggle",name:"Toggle",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A sliding switch for immediately-applied binary settings.",designIntent:'Toggles are for settings that take effect the moment they are flipped — no Save button needed. If the action requires a confirmation step or only applies on form submit, use a Checkbox instead. The "on" state is visually represented by the accent colour so the meaning is clear without relying on text alone. Keep the label short (2–4 words) and phrase it as the enabled state (e.g. "Dark mode", not "Enable dark mode").',props:[{name:"checked",type:"boolean",required:!1,description:"Controlled on/off state. Pair with onChange for controlled usage."},{name:"defaultChecked",type:"boolean",required:!1,default:"false",description:"Initial state for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called when the toggle is flipped."},{name:"label",type:"string",required:!1,description:"Visible label rendered beside the toggle."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls the track and thumb size.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the control."}],usageExamples:[{title:"Controlled",code:'<Toggle checked={darkMode} onChange={e => setDarkMode(e.target.checked)} label="Dark mode" />'},{title:"Uncontrolled",code:'<Toggle defaultChecked label="Email notifications" />'},{title:"Sizes",code:`<Toggle size="sm" label="Compact" />
47
47
  <Toggle size="md" label="Default" />
48
- <Toggle size="lg" label="Large" />`},{title:"Disabled",code:'<Toggle disabled label="Unavailable setting" />'}],compositionGraph:[],accessibility:{role:"switch",ariaAttributes:["aria-checked","aria-disabled"],keyboardInteractions:["Space — toggles the switch state"]}},mn={sm:"32px",md:"40px",lg:"46px"},gn={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-lg)"},Je={sm:"var(--lucent-space-2)",md:"var(--lucent-space-3)",lg:"var(--lucent-space-3)"},Me=p.forwardRef(({options:e,size:n="md",label:a,helperText:o,errorText:r,placeholder:i,disabled:s,id:l,style:c,...u},f)=>{const d=l??`lucent-select-${Math.random().toString(36).slice(2,7)}`,y=!!r,h=!!s,[w,v]=p.useState(!1),[g,b]=p.useState(!1),k=h?"transparent":y?"var(--lucent-danger-default)":w?"var(--lucent-focus-ring)":g?"var(--lucent-border-strong)":"var(--lucent-border-default)",D=w?`0 0 0 3px ${y?"var(--lucent-danger-subtle)":"var(--lucent-accent-subtle)"}`:"none";return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%",...c},children:[a&&t.jsx("label",{htmlFor:d,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:h?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:a}),t.jsxs("div",{style:{position:"relative",display:"flex",alignItems:"center",height:mn[n],border:`1px solid ${k}`,borderRadius:"var(--lucent-radius-lg)",boxShadow:D,background:h?"var(--lucent-surface-secondary)":"var(--lucent-surface)",cursor:h?"not-allowed":"pointer",transition:["border-color var(--lucent-duration-fast) var(--lucent-easing-default)","box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", ")},onMouseEnter:()=>{h||b(!0)},onMouseLeave:()=>b(!1),children:[t.jsxs("select",{ref:f,id:d,disabled:s,"aria-invalid":y,"aria-describedby":y?`${d}-error`:o?`${d}-helper`:void 0,style:{width:"100%",height:"100%",padding:`0 var(--lucent-space-8) 0 ${Je[n]}`,fontSize:gn[n],fontFamily:"var(--lucent-font-family-base)",color:h?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",background:"transparent",border:"none",borderRadius:"var(--lucent-radius-lg)",outline:"none",appearance:"none",cursor:h?"not-allowed":"pointer",boxSizing:"border-box"},onFocus:S=>{var x;v(!0),(x=u.onFocus)==null||x.call(u,S)},onBlur:S=>{var x;v(!1),(x=u.onBlur)==null||x.call(u,S)},...u,children:[i&&t.jsx("option",{value:"",disabled:!0,children:i}),e.map(S=>t.jsx("option",{value:S.value,disabled:S.disabled,children:S.label},S.value))]}),t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",right:Je[n],pointerEvents:"none",color:h?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",display:"flex",alignItems:"center"},children:t.jsx("svg",{width:14,height:14,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",children:t.jsx("polyline",{points:"6 9 12 15 18 9"})})})]}),y&&t.jsx("span",{id:`${d}-error`,role:"alert",style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-danger-text)",fontFamily:"var(--lucent-font-family-base)"},children:r}),!y&&o&&t.jsx("span",{id:`${d}-helper`,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:o})]})});Me.displayName="Select";const bn={id:"select",name:"Select",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A dropdown for choosing one option from a list.",designIntent:"Select is best for 5–15 options where showing all at once would be too noisy. For fewer than 5 options, prefer RadioGroup (always-visible, faster to scan). For search-filtered or async options, a Combobox (Wave 3) is more appropriate. Always provide a placeholder when no default is sensible — this communicates the field is required and prevents silent zero-state submissions.",props:[{name:"options",type:"array",required:!0,description:"Array of { value, label, disabled? } option objects."},{name:"value",type:"string",required:!1,description:"Controlled selected value. Pair with onChange."},{name:"onChange",type:"function",required:!1,description:"Called when the selected value changes."},{name:"placeholder",type:"string",required:!1,description:"Disabled first option shown when no value is selected."},{name:"label",type:"string",required:!1,description:"Visible label rendered above the select."},{name:"helperText",type:"string",required:!1,description:"Supplementary hint shown below the select."},{name:"errorText",type:"string",required:!1,description:"Validation error message. Replaces helperText and applies error styling."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls the height of the select control.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction."}],usageExamples:[{title:"Controlled",code:`
48
+ <Toggle size="lg" label="Large" />`},{title:"Disabled",code:'<Toggle disabled label="Unavailable setting" />'}],compositionGraph:[],accessibility:{role:"switch",ariaAttributes:["aria-checked","aria-disabled"],keyboardInteractions:["Space — toggles the switch state"]}},gn={sm:"32px",md:"40px",lg:"46px"},bn={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-lg)"},Je={sm:"var(--lucent-space-2)",md:"var(--lucent-space-3)",lg:"var(--lucent-space-3)"},Me=f.forwardRef(({options:e,size:n="md",label:a,helperText:o,errorText:r,placeholder:i,disabled:s,id:l,style:c,...d},p)=>{const m=l??`lucent-select-${Math.random().toString(36).slice(2,7)}`,h=!!r,u=!!s,[S,y]=f.useState(!1),[b,v]=f.useState(!1),w=u?"transparent":h?"var(--lucent-danger-default)":S?"var(--lucent-focus-ring)":b?"var(--lucent-border-strong)":"var(--lucent-border-default)",j=S?`0 0 0 3px ${h?"var(--lucent-danger-subtle)":"var(--lucent-accent-subtle)"}`:"none";return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%",...c},children:[a&&t.jsx("label",{htmlFor:m,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:u?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:a}),t.jsxs("div",{style:{position:"relative",display:"flex",alignItems:"center",height:gn[n],border:`1px solid ${w}`,borderRadius:"var(--lucent-radius-lg)",boxShadow:j,background:u?"var(--lucent-surface-secondary)":"var(--lucent-surface)",cursor:u?"not-allowed":"pointer",transition:["border-color var(--lucent-duration-fast) var(--lucent-easing-default)","box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", ")},onMouseEnter:()=>{u||v(!0)},onMouseLeave:()=>v(!1),children:[t.jsxs("select",{ref:p,id:m,disabled:s,"aria-invalid":h,"aria-describedby":h?`${m}-error`:o?`${m}-helper`:void 0,style:{width:"100%",height:"100%",padding:`0 var(--lucent-space-8) 0 ${Je[n]}`,fontSize:bn[n],fontFamily:"var(--lucent-font-family-base)",color:u?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",background:"transparent",border:"none",borderRadius:"var(--lucent-radius-lg)",outline:"none",appearance:"none",cursor:u?"not-allowed":"pointer",boxSizing:"border-box"},onFocus:T=>{var x;y(!0),(x=d.onFocus)==null||x.call(d,T)},onBlur:T=>{var x;y(!1),(x=d.onBlur)==null||x.call(d,T)},...d,children:[i&&t.jsx("option",{value:"",disabled:!0,children:i}),e.map(T=>t.jsx("option",{value:T.value,disabled:T.disabled,children:T.label},T.value))]}),t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",right:Je[n],pointerEvents:"none",color:u?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",display:"flex",alignItems:"center"},children:t.jsx("svg",{width:14,height:14,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",children:t.jsx("polyline",{points:"6 9 12 15 18 9"})})})]}),h&&t.jsx("span",{id:`${m}-error`,role:"alert",style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-danger-text)",fontFamily:"var(--lucent-font-family-base)"},children:r}),!h&&o&&t.jsx("span",{id:`${m}-helper`,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:o})]})});Me.displayName="Select";const vn={id:"select",name:"Select",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A dropdown for choosing one option from a list.",designIntent:"Select is best for 5–15 options where showing all at once would be too noisy. For fewer than 5 options, prefer RadioGroup (always-visible, faster to scan). For search-filtered or async options, a Combobox (Wave 3) is more appropriate. Always provide a placeholder when no default is sensible — this communicates the field is required and prevents silent zero-state submissions.",props:[{name:"options",type:"array",required:!0,description:"Array of { value, label, disabled? } option objects."},{name:"value",type:"string",required:!1,description:"Controlled selected value. Pair with onChange."},{name:"onChange",type:"function",required:!1,description:"Called when the selected value changes."},{name:"placeholder",type:"string",required:!1,description:"Disabled first option shown when no value is selected."},{name:"label",type:"string",required:!1,description:"Visible label rendered above the select."},{name:"helperText",type:"string",required:!1,description:"Supplementary hint shown below the select."},{name:"errorText",type:"string",required:!1,description:"Validation error message. Replaces helperText and applies error styling."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls the height of the select control.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction."}],usageExamples:[{title:"Controlled",code:`
49
49
  <Select
50
50
  label="Country"
51
51
  placeholder="Choose a country"
52
52
  options={countries}
53
53
  value={country}
54
54
  onChange={e => setCountry(e.target.value)}
55
- />`.trim()},{title:"With validation error",code:'<Select label="Role" options={roles} errorText="Please select a role" />'},{title:"With helper text",code:'<Select label="Timezone" options={timezones} helperText="Used for scheduling notifications" />'}],compositionGraph:[],accessibility:{role:"combobox",ariaAttributes:["aria-invalid","aria-describedby"],keyboardInteractions:["Enter / Space — opens the option list","Arrow keys — navigate options","Escape — closes the list"]}},vn={neutral:{bg:"var(--lucent-surface-secondary)",color:"var(--lucent-text-secondary)",border:"var(--lucent-border-default)",dismissHover:"var(--lucent-border-strong)"},accent:{bg:"var(--lucent-accent-subtle)",color:"var(--lucent-accent-active)",border:"var(--lucent-accent-subtle)",dismissHover:"var(--lucent-accent-default)"},success:{bg:"var(--lucent-success-subtle)",color:"var(--lucent-success-text)",border:"var(--lucent-success-subtle)",dismissHover:"var(--lucent-success-default)"},warning:{bg:"var(--lucent-warning-subtle)",color:"var(--lucent-warning-text)",border:"var(--lucent-warning-subtle)",dismissHover:"var(--lucent-warning-default)"},danger:{bg:"var(--lucent-danger-subtle)",color:"var(--lucent-danger-text)",border:"var(--lucent-danger-subtle)",dismissHover:"var(--lucent-danger-default)"},info:{bg:"var(--lucent-info-subtle)",color:"var(--lucent-info-text)",border:"var(--lucent-info-subtle)",dismissHover:"var(--lucent-info-default)"}},yn={sm:{fontSize:"var(--lucent-font-size-xs)",height:"20px",padding:"0 var(--lucent-space-2)",iconSize:10,gap:"var(--lucent-space-1)"},md:{fontSize:"var(--lucent-font-size-sm)",height:"24px",padding:"0 var(--lucent-space-2)",iconSize:12,gap:"var(--lucent-space-1)"}};function xn({children:e,variant:n="neutral",size:a="md",onDismiss:o,disabled:r}){const i=vn[n],s=yn[a];return t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:s.gap,height:s.height,padding:o?"0 var(--lucent-space-1) 0 var(--lucent-space-2)":s.padding,fontSize:s.fontSize,fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:1,borderRadius:"var(--lucent-radius-full)",background:i.bg,color:i.color,border:`1px solid ${i.border}`,whiteSpace:"nowrap",boxSizing:"border-box",opacity:r?.5:1},children:[e,o&&t.jsx("button",{type:"button",onClick:r?void 0:o,disabled:r,"aria-label":"Dismiss",style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:s.iconSize+4,height:s.iconSize+4,padding:0,border:"none",borderRadius:"var(--lucent-radius-full)",background:"transparent",color:"inherit",cursor:r?"not-allowed":"pointer",flexShrink:0,lineHeight:1},onMouseEnter:l=>{r||(l.currentTarget.style.background=i.dismissHover+"33")},onMouseLeave:l=>{l.currentTarget.style.background="transparent"},children:t.jsx("svg",{width:s.iconSize,height:s.iconSize,viewBox:"0 0 10 10",fill:"none",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",children:t.jsx("path",{d:"M2 2L8 8M8 2L2 8"})})})]})}const wn={id:"tag",name:"Tag",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A dismissible label for applied filters, selected values, or categorisation.",designIntent:"Tags represent user-applied selections that can be removed — filters, multi-select values, categories. They differ from Badge in that they are interactive: provide onDismiss when the user should be able to remove the tag. Without onDismiss they render as a static pill (identical to Badge in purpose). Use semantic variants to match meaning; default to neutral for user-generated content where no semantic applies.",props:[{name:"children",type:"ReactNode",required:!0,description:"Tag label content."},{name:"variant",type:"enum",required:!1,default:"neutral",description:"Colour scheme conveying semantic meaning.",enumValues:["neutral","accent","success","warning","danger","info"]},{name:"size",type:"enum",required:!1,default:"md",description:"Controls height and font size.",enumValues:["sm","md"]},{name:"onDismiss",type:"function",required:!1,description:"When provided, renders an × button that calls this handler on click."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Dims the tag and prevents the dismiss action."}],usageExamples:[{title:"Dismissible filter",code:"<Tag onDismiss={() => removeFilter('react')}>React</Tag>"},{title:"Multi-select value",code:'<Tag variant="accent" onDismiss={() => deselect(id)}>Jane Doe</Tag>'},{title:"Static category",code:'<Tag variant="info">Beta</Tag>'},{title:"Danger (removable)",code:'<Tag variant="danger" onDismiss={handleRemove}>Blocked</Tag>'}],compositionGraph:[],accessibility:{role:"group",notes:'The dismiss button has aria-label="Dismiss" and is keyboard-focusable.',keyboardInteractions:["Enter / Space — activates the dismiss button when focused"]}},W=5,kn={top:{bottom:"100%",left:"50%",transform:"translateX(-50%)",marginBottom:W+3},bottom:{top:"100%",left:"50%",transform:"translateX(-50%)",marginTop:W+3},left:{right:"100%",top:"50%",transform:"translateY(-50%)",marginRight:W+3},right:{left:"100%",top:"50%",transform:"translateY(-50%)",marginLeft:W+3}},Sn={top:{bottom:-W,left:"50%",transform:"translateX(-50%)",borderWidth:`${W}px ${W}px 0 ${W}px`,borderColor:"var(--lucent-text-primary) transparent transparent transparent"},bottom:{top:-W,left:"50%",transform:"translateX(-50%)",borderWidth:`0 ${W}px ${W}px ${W}px`,borderColor:"transparent transparent var(--lucent-text-primary) transparent"},left:{right:-W,top:"50%",transform:"translateY(-50%)",borderWidth:`${W}px 0 ${W}px ${W}px`,borderColor:"transparent transparent transparent var(--lucent-text-primary)"},right:{left:-W,top:"50%",transform:"translateY(-50%)",borderWidth:`${W}px ${W}px ${W}px 0`,borderColor:"transparent var(--lucent-text-primary) transparent transparent"}};function Tn({content:e,children:n,placement:a="top",delay:o=300}){const[r,i]=p.useState(!1),s=p.useRef(null),l=()=>{s.current=setTimeout(()=>i(!0),o)},c=()=>{s.current&&clearTimeout(s.current),i(!1)};return e?t.jsxs("span",{style:{position:"relative",display:"inline-flex"},onMouseEnter:l,onMouseLeave:c,onFocus:l,onBlur:c,children:[n,r&&t.jsxs("span",{role:"tooltip",style:{position:"absolute",...kn[a],background:"var(--lucent-text-primary)",color:"var(--lucent-bg-base)",padding:"5px 10px",borderRadius:"var(--lucent-radius-md)",fontSize:"var(--lucent-font-size-xs)",fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:"var(--lucent-line-height-base)",whiteSpace:"nowrap",zIndex:9999,pointerEvents:"none",boxShadow:"var(--lucent-shadow-md)"},children:[e,t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",width:0,height:0,borderStyle:"solid",...Sn[a]}})]})]}):t.jsx(t.Fragment,{children:n})}const jn={id:"tooltip",name:"Tooltip",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A transient label that appears on hover or focus to explain an element.",designIntent:'Tooltips surface supplementary context that would clutter the UI if shown permanently — keyboard shortcut hints, icon button labels, truncated text expansions. They must never contain critical information (errors, required actions) because they are invisible until hovered. Keep content to one short phrase; avoid wrapping. Use placement to avoid viewport edges — "top" is the default and works in most cases.',props:[{name:"content",type:"ReactNode",required:!0,description:"Text or element shown inside the tooltip. Keep it short (under 80 chars)."},{name:"children",type:"ReactNode",required:!0,description:"The element that triggers the tooltip on hover/focus."},{name:"placement",type:"enum",required:!1,default:"top",description:"Position of the tooltip relative to the trigger.",enumValues:["top","bottom","left","right"]},{name:"delay",type:"number",required:!1,default:"300",description:"Milliseconds before the tooltip appears. Prevents flicker on fast cursor movement."}],usageExamples:[{title:"Icon button label",code:'<Tooltip content="Copy to clipboard"><IconButton icon={<CopyIcon />} /></Tooltip>'},{title:"Keyboard shortcut hint",code:'<Tooltip content="⌘K"><Button variant="ghost">Search</Button></Tooltip>'},{title:"Bottom placement",code:'<Tooltip content="Opens in a new tab" placement="bottom"><a href="…">Link</a></Tooltip>'},{title:"No delay (instant)",code:'<Tooltip content="Delete" delay={0}><Button variant="ghost">🗑</Button></Tooltip>'}],compositionGraph:[],accessibility:{role:"tooltip",ariaAttributes:['role="tooltip"'],notes:'The tooltip is shown on both hover and focus, making it accessible to keyboard users. Content is exposed via role="tooltip".'}},Cn={xs:12,sm:14,md:16,lg:20,xl:24};function Dn({children:e,size:n="md",label:a,color:o,style:r}){const i=Cn[n];return t.jsx("span",{role:a?"img":void 0,"aria-label":a,"aria-hidden":a?void 0:!0,style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:i,height:i,flexShrink:0,color:o??"currentColor",...r},children:e})}const In={id:"icon",name:"Icon",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A sized, accessible wrapper for any SVG or icon-set component.",designIntent:"Icon is intentionally icon-set agnostic — pass any SVG or third-party icon as children and it handles sizing and accessibility automatically. Use label for standalone icons that convey meaning without adjacent text (e.g. a close button). Omit label for decorative icons next to text, where the text already provides context. colour inherits from the parent by default via currentColor — override only when the icon must differ from its surrounding text.",props:[{name:"children",type:"ReactNode",required:!0,description:"The icon to render — any SVG element or icon-set component."},{name:"size",type:"enum",required:!1,default:"md",description:"Constrains the icon to a fixed square (xs=12, sm=14, md=16, lg=20, xl=24).",enumValues:["xs","sm","md","lg","xl"]},{name:"label",type:"string",required:!1,description:"Accessible label (aria-label). Provide for meaningful standalone icons; omit for decorative ones."},{name:"color",type:"string",required:!1,description:"CSS colour value. Defaults to currentColor (inherits from parent)."}],usageExamples:[{title:"Decorative (next to text)",code:'<Icon size="md"><SearchIcon /></Icon>'},{title:"Meaningful (standalone)",code:'<Icon size="lg" label="Close dialog"><XIcon /></Icon>'},{title:"Coloured",code:'<Icon color="var(--lucent-danger-default)"><AlertIcon /></Icon>'},{title:"Inside a button",code:'<Button leftIcon={<Icon size="sm"><PlusIcon /></Icon>}>Add item</Button>'}],compositionGraph:[],accessibility:{role:"img",ariaAttributes:["aria-label","aria-hidden"],notes:'aria-hidden="true" is applied automatically when no label is given, hiding the icon from screen readers.'}},Mn={primary:"var(--lucent-text-primary)",secondary:"var(--lucent-text-secondary)",disabled:"var(--lucent-text-disabled)",inverse:"var(--lucent-text-inverse)",onAccent:"var(--lucent-text-on-accent)",success:"var(--lucent-success-text)",warning:"var(--lucent-warning-text)",danger:"var(--lucent-danger-text)",info:"var(--lucent-info-text)"},An={xs:"var(--lucent-font-size-xs)",sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-lg)",xl:"var(--lucent-font-size-xl)","2xl":"var(--lucent-font-size-2xl)","3xl":"var(--lucent-font-size-3xl)"},zn={regular:"var(--lucent-font-weight-regular)",medium:"var(--lucent-font-weight-medium)",semibold:"var(--lucent-font-weight-semibold)",bold:"var(--lucent-font-weight-bold)"},En={tight:"var(--lucent-line-height-tight)",base:"var(--lucent-line-height-base)",relaxed:"var(--lucent-line-height-relaxed)"},Rn={base:"var(--lucent-font-family-base)",mono:"var(--lucent-font-family-mono)",display:"var(--lucent-font-family-display)"};function B({as:e="p",size:n="md",weight:a="regular",color:o="primary",align:r="left",lineHeight:i="base",family:s="base",truncate:l=!1,children:c,style:u,...f}){const d={fontSize:An[n],fontWeight:zn[a],color:Mn[o],textAlign:r,lineHeight:En[i],fontFamily:Rn[s],margin:0,...l&&{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},...u},y=e;return t.jsx(y,{style:d,...f,children:c})}const Ln={id:"text",name:"Text",tier:"atom",domain:"neutral",specVersion:"0.1",description:"Polymorphic typography primitive that maps semantic HTML elements to design-system type scales.",designIntent:"Text is the single source of truth for typography in Lucent UI. Rather than hard-coding font sizes and colors directly in components, every piece of rendered text should pass through this atom. The `as` prop controls the HTML element (and therefore semantic meaning), while `size`, `weight`, `color`, and `lineHeight` control appearance independently — decoupling semantics from style. Use `truncate` only in constrained-width containers where overflow must be prevented; it applies overflow: hidden + text-overflow: ellipsis. The `family` prop enables inline code or monospaced content without switching components.",props:[{name:"as",type:"enum",required:!1,default:"p",description:"HTML element to render. Controls semantic meaning independently of visual style.",enumValues:["p","h1","h2","h3","h4","h5","h6","span","div","label","strong","em","code"]},{name:"size",type:"enum",required:!1,default:"md",description:"Font size from the type scale. Maps to the corresponding --lucent-font-size-* token.",enumValues:["xs","sm","md","lg","xl","2xl","3xl"]},{name:"weight",type:"enum",required:!1,default:"regular",description:"Font weight. Maps to --lucent-font-weight-* tokens.",enumValues:["regular","medium","semibold","bold"]},{name:"color",type:"enum",required:!1,default:"primary",description:"Semantic text color. All values adapt automatically in light and dark themes.",enumValues:["primary","secondary","disabled","inverse","onAccent","success","warning","danger","info"]},{name:"align",type:"enum",required:!1,default:"left",description:"Text alignment.",enumValues:["left","center","right"]},{name:"lineHeight",type:"enum",required:!1,default:"base",description:"Line height. tight=1.25, base=1.5, relaxed=1.75.",enumValues:["tight","base","relaxed"]},{name:"family",type:"enum",required:!1,default:"base",description:"Font family. Use mono for code or tabular data. Use display (Unbounded) for headings and marketing copy.",enumValues:["base","mono","display"]},{name:"truncate",type:"boolean",required:!1,default:"false",description:"Clips overflow text with an ellipsis. Requires the container to have a constrained width."},{name:"children",type:"ReactNode",required:!0,description:"The text content to render."},{name:"style",type:"object",required:!1,description:"Inline style overrides. Applied after computed token styles."}],usageExamples:[{title:"Heading",code:'<Text as="h1" size="3xl" weight="bold">Page title</Text>'},{title:"Body paragraph",code:'<Text size="md" color="secondary">Supporting copy goes here.</Text>'},{title:"Label",code:'<Text as="label" size="sm" weight="medium" htmlFor="email">Email</Text>'},{title:"Inline code",code:'<Text as="code" family="mono" size="sm">const x = 1;</Text>'},{title:"Truncated",code:"<Text truncate style={{ maxWidth: 200 }}>Very long text that will be clipped</Text>"},{title:"Status color",code:'<Text color="danger" size="xs">This field is required</Text>'}],compositionGraph:[],accessibility:{notes:'The rendered element determines the implicit ARIA role. Use heading elements (h1–h6) for document headings so screen readers can navigate the page structure. Use `as="label"` with `htmlFor` to associate labels with form controls. Decorative text needs no additional ARIA.'}};function Bn({children:e,href:n,isActive:a=!1,icon:o,disabled:r=!1,onClick:i,as:s,style:l}){const c=s??"a";return t.jsxs(c,{href:r?void 0:n,onClick:r?void 0:i,"aria-current":a?"page":void 0,"aria-disabled":r||void 0,style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-2) var(--lucent-space-3) var(--lucent-space-2) var(--lucent-space-4)",borderRadius:"var(--lucent-radius-md)",background:r?"transparent":a?"var(--lucent-accent-default)":"transparent",color:r?"var(--lucent-text-disabled)":a?"var(--lucent-text-on-accent)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:a?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",textDecoration:"none",cursor:r?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), color var(--lucent-duration-fast) var(--lucent-easing-default)",userSelect:"none",boxSizing:"border-box",...l},onMouseEnter:u=>{!r&&!a&&(u.currentTarget.style.background="var(--lucent-surface-secondary)")},onMouseLeave:u=>{!r&&!a&&(u.currentTarget.style.background="transparent")},children:[o!=null&&t.jsx("span",{style:{display:"flex",flexShrink:0,color:"inherit"},children:o}),e]})}const qn={sm:"3px",md:"4px",lg:"5px"},Pn={sm:"14px",md:"18px",lg:"22px"},Fn=`
55
+ />`.trim()},{title:"With validation error",code:'<Select label="Role" options={roles} errorText="Please select a role" />'},{title:"With helper text",code:'<Select label="Timezone" options={timezones} helperText="Used for scheduling notifications" />'}],compositionGraph:[],accessibility:{role:"combobox",ariaAttributes:["aria-invalid","aria-describedby"],keyboardInteractions:["Enter / Space — opens the option list","Arrow keys — navigate options","Escape — closes the list"]}},yn={neutral:{bg:"var(--lucent-surface-secondary)",color:"var(--lucent-text-secondary)",border:"var(--lucent-border-default)",dismissHover:"var(--lucent-border-strong)"},accent:{bg:"var(--lucent-accent-subtle)",color:"var(--lucent-accent-active)",border:"var(--lucent-accent-subtle)",dismissHover:"var(--lucent-accent-default)"},success:{bg:"var(--lucent-success-subtle)",color:"var(--lucent-success-text)",border:"var(--lucent-success-subtle)",dismissHover:"var(--lucent-success-default)"},warning:{bg:"var(--lucent-warning-subtle)",color:"var(--lucent-warning-text)",border:"var(--lucent-warning-subtle)",dismissHover:"var(--lucent-warning-default)"},danger:{bg:"var(--lucent-danger-subtle)",color:"var(--lucent-danger-text)",border:"var(--lucent-danger-subtle)",dismissHover:"var(--lucent-danger-default)"},info:{bg:"var(--lucent-info-subtle)",color:"var(--lucent-info-text)",border:"var(--lucent-info-subtle)",dismissHover:"var(--lucent-info-default)"}},xn={sm:{fontSize:"var(--lucent-font-size-xs)",height:"20px",padding:"0 var(--lucent-space-3)",iconSize:10,gap:"var(--lucent-space-1)"},md:{fontSize:"var(--lucent-font-size-sm)",height:"24px",padding:"0 var(--lucent-space-3)",iconSize:12,gap:"var(--lucent-space-1)"},lg:{fontSize:"var(--lucent-font-size-md)",height:"28px",padding:"0 var(--lucent-space-4)",iconSize:14,gap:"var(--lucent-space-2)"}};function ht({children:e,variant:n="neutral",size:a="md",onDismiss:o,disabled:r}){const i=yn[n],s=xn[a],[l,c]=f.useState(!1),d=!r&&o;return t.jsxs("span",{onMouseEnter:()=>{r||c(!0)},onMouseLeave:()=>c(!1),style:{display:"inline-flex",alignItems:"center",gap:s.gap,height:s.height,padding:o?`0 var(--lucent-space-2) 0 ${s.padding.split(" ")[1]}`:s.padding,fontSize:s.fontSize,fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:1,borderRadius:"var(--lucent-radius-lg)",background:i.bg,color:i.color,border:`1px solid ${l&&!r?i.dismissHover:i.border}`,whiteSpace:"nowrap",boxSizing:"border-box",opacity:r?.5:1,transform:l&&d?"translateY(-1px)":"none",boxShadow:l&&d?`0 2px 4px ${i.dismissHover}22`:"none",transition:"transform var(--lucent-duration-fast) var(--lucent-easing-default), box-shadow var(--lucent-duration-fast) var(--lucent-easing-default), border-color var(--lucent-duration-fast) var(--lucent-easing-default)",cursor:d?"pointer":"default"},children:[e,o&&t.jsx("button",{type:"button",onClick:r?void 0:p=>{p.stopPropagation(),o==null||o()},disabled:r,"aria-label":"Dismiss",style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:s.iconSize+4,height:s.iconSize+4,padding:0,border:"none",borderRadius:"var(--lucent-radius-lg)",background:"transparent",color:"inherit",cursor:r?"not-allowed":"pointer",flexShrink:0,lineHeight:1},onMouseEnter:p=>{r||(p.currentTarget.style.background=i.dismissHover+"33")},onMouseLeave:p=>{p.currentTarget.style.background="transparent"},children:t.jsx("svg",{width:s.iconSize,height:s.iconSize,viewBox:"0 0 10 10",fill:"none",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",children:t.jsx("path",{d:"M2 2L8 8M8 2L2 8"})})})]})}const wn={id:"tag",name:"Tag",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A dismissible label for applied filters, selected values, or categorisation.",designIntent:"Tags represent user-applied selections that can be removed — filters, multi-select values, categories. They differ from Badge in that they are interactive: provide onDismiss when the user should be able to remove the tag. Without onDismiss they render as a static pill (identical to Badge in purpose). Use semantic variants to match meaning; default to neutral for user-generated content where no semantic applies.",props:[{name:"children",type:"ReactNode",required:!0,description:"Tag label content."},{name:"variant",type:"enum",required:!1,default:"neutral",description:"Colour scheme conveying semantic meaning.",enumValues:["neutral","accent","success","warning","danger","info"]},{name:"size",type:"enum",required:!1,default:"md",description:"Controls height and font size.",enumValues:["sm","md","lg"]},{name:"onDismiss",type:"function",required:!1,description:"When provided, renders an × button that calls this handler on click."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Dims the tag and prevents the dismiss action."}],usageExamples:[{title:"Dismissible filter",code:"<Tag onDismiss={() => removeFilter('react')}>React</Tag>"},{title:"Multi-select value",code:'<Tag variant="accent" onDismiss={() => deselect(id)}>Jane Doe</Tag>'},{title:"Static category",code:'<Tag variant="info">Beta</Tag>'},{title:"Danger (removable)",code:'<Tag variant="danger" onDismiss={handleRemove}>Blocked</Tag>'}],compositionGraph:[],accessibility:{role:"group",notes:'The dismiss button has aria-label="Dismiss" and is keyboard-focusable.',keyboardInteractions:["Enter / Space — activates the dismiss button when focused"]}},H=5,kn={top:{bottom:"100%",left:"50%",transform:"translateX(-50%)",marginBottom:H+3},bottom:{top:"100%",left:"50%",transform:"translateX(-50%)",marginTop:H+3},left:{right:"100%",top:"50%",transform:"translateY(-50%)",marginRight:H+3},right:{left:"100%",top:"50%",transform:"translateY(-50%)",marginLeft:H+3}},Sn={top:{bottom:-H,left:"50%",transform:"translateX(-50%)",borderWidth:`${H}px ${H}px 0 ${H}px`,borderColor:"var(--lucent-text-primary) transparent transparent transparent"},bottom:{top:-H,left:"50%",transform:"translateX(-50%)",borderWidth:`0 ${H}px ${H}px ${H}px`,borderColor:"transparent transparent var(--lucent-text-primary) transparent"},left:{right:-H,top:"50%",transform:"translateY(-50%)",borderWidth:`${H}px 0 ${H}px ${H}px`,borderColor:"transparent transparent transparent var(--lucent-text-primary)"},right:{left:-H,top:"50%",transform:"translateY(-50%)",borderWidth:`${H}px ${H}px ${H}px 0`,borderColor:"transparent var(--lucent-text-primary) transparent transparent"}};function Tn({content:e,children:n,placement:a="top",delay:o=300}){const[r,i]=f.useState(!1),s=f.useRef(null),l=()=>{s.current=setTimeout(()=>i(!0),o)},c=()=>{s.current&&clearTimeout(s.current),i(!1)};return e?t.jsxs("span",{style:{position:"relative",display:"inline-flex"},onMouseEnter:l,onMouseLeave:c,onFocus:l,onBlur:c,children:[n,r&&t.jsxs("span",{role:"tooltip",style:{position:"absolute",...kn[a],background:"var(--lucent-text-primary)",color:"var(--lucent-bg-base)",padding:"5px 10px",borderRadius:"var(--lucent-radius-md)",fontSize:"var(--lucent-font-size-xs)",fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-medium)",lineHeight:"var(--lucent-line-height-base)",whiteSpace:"nowrap",zIndex:9999,pointerEvents:"none",boxShadow:"var(--lucent-shadow-md)"},children:[e,t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",width:0,height:0,borderStyle:"solid",...Sn[a]}})]})]}):t.jsx(t.Fragment,{children:n})}const jn={id:"tooltip",name:"Tooltip",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A transient label that appears on hover or focus to explain an element.",designIntent:'Tooltips surface supplementary context that would clutter the UI if shown permanently — keyboard shortcut hints, icon button labels, truncated text expansions. They must never contain critical information (errors, required actions) because they are invisible until hovered. Keep content to one short phrase; avoid wrapping. Use placement to avoid viewport edges — "top" is the default and works in most cases.',props:[{name:"content",type:"ReactNode",required:!0,description:"Text or element shown inside the tooltip. Keep it short (under 80 chars)."},{name:"children",type:"ReactNode",required:!0,description:"The element that triggers the tooltip on hover/focus."},{name:"placement",type:"enum",required:!1,default:"top",description:"Position of the tooltip relative to the trigger.",enumValues:["top","bottom","left","right"]},{name:"delay",type:"number",required:!1,default:"300",description:"Milliseconds before the tooltip appears. Prevents flicker on fast cursor movement."}],usageExamples:[{title:"Icon button label",code:'<Tooltip content="Copy to clipboard"><IconButton icon={<CopyIcon />} /></Tooltip>'},{title:"Keyboard shortcut hint",code:'<Tooltip content="⌘K"><Button variant="ghost">Search</Button></Tooltip>'},{title:"Bottom placement",code:'<Tooltip content="Opens in a new tab" placement="bottom"><a href="…">Link</a></Tooltip>'},{title:"No delay (instant)",code:'<Tooltip content="Delete" delay={0}><Button variant="ghost">🗑</Button></Tooltip>'}],compositionGraph:[],accessibility:{role:"tooltip",ariaAttributes:['role="tooltip"'],notes:'The tooltip is shown on both hover and focus, making it accessible to keyboard users. Content is exposed via role="tooltip".'}},Cn={xs:12,sm:14,md:16,lg:20,xl:24};function Dn({children:e,size:n="md",label:a,color:o,style:r}){const i=Cn[n];return t.jsx("span",{role:a?"img":void 0,"aria-label":a,"aria-hidden":a?void 0:!0,style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:i,height:i,flexShrink:0,color:o??"currentColor",...r},children:e})}const In={id:"icon",name:"Icon",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A sized, accessible wrapper for any SVG or icon-set component.",designIntent:"Icon is intentionally icon-set agnostic — pass any SVG or third-party icon as children and it handles sizing and accessibility automatically. Use label for standalone icons that convey meaning without adjacent text (e.g. a close button). Omit label for decorative icons next to text, where the text already provides context. colour inherits from the parent by default via currentColor — override only when the icon must differ from its surrounding text.",props:[{name:"children",type:"ReactNode",required:!0,description:"The icon to render — any SVG element or icon-set component."},{name:"size",type:"enum",required:!1,default:"md",description:"Constrains the icon to a fixed square (xs=12, sm=14, md=16, lg=20, xl=24).",enumValues:["xs","sm","md","lg","xl"]},{name:"label",type:"string",required:!1,description:"Accessible label (aria-label). Provide for meaningful standalone icons; omit for decorative ones."},{name:"color",type:"string",required:!1,description:"CSS colour value. Defaults to currentColor (inherits from parent)."}],usageExamples:[{title:"Decorative (next to text)",code:'<Icon size="md"><SearchIcon /></Icon>'},{title:"Meaningful (standalone)",code:'<Icon size="lg" label="Close dialog"><XIcon /></Icon>'},{title:"Coloured",code:'<Icon color="var(--lucent-danger-default)"><AlertIcon /></Icon>'},{title:"Inside a button",code:'<Button leftIcon={<Icon size="sm"><PlusIcon /></Icon>}>Add item</Button>'}],compositionGraph:[],accessibility:{role:"img",ariaAttributes:["aria-label","aria-hidden"],notes:'aria-hidden="true" is applied automatically when no label is given, hiding the icon from screen readers.'}},Mn={primary:"var(--lucent-text-primary)",secondary:"var(--lucent-text-secondary)",disabled:"var(--lucent-text-disabled)",inverse:"var(--lucent-text-inverse)",onAccent:"var(--lucent-text-on-accent)",success:"var(--lucent-success-text)",warning:"var(--lucent-warning-text)",danger:"var(--lucent-danger-text)",info:"var(--lucent-info-text)"},zn={xs:"var(--lucent-font-size-xs)",sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-lg)",xl:"var(--lucent-font-size-xl)","2xl":"var(--lucent-font-size-2xl)","3xl":"var(--lucent-font-size-3xl)"},An={regular:"var(--lucent-font-weight-regular)",medium:"var(--lucent-font-weight-medium)",semibold:"var(--lucent-font-weight-semibold)",bold:"var(--lucent-font-weight-bold)"},En={tight:"var(--lucent-line-height-tight)",base:"var(--lucent-line-height-base)",relaxed:"var(--lucent-line-height-relaxed)"},Rn={base:"var(--lucent-font-family-base)",mono:"var(--lucent-font-family-mono)",display:"var(--lucent-font-family-display)"};function P({as:e="p",size:n="md",weight:a="regular",color:o="primary",align:r="left",lineHeight:i="base",family:s="base",truncate:l=!1,children:c,style:d,...p}){const m={fontSize:zn[n],fontWeight:An[a],color:Mn[o],textAlign:r,lineHeight:En[i],fontFamily:Rn[s],margin:0,...l&&{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},...d},h=e;return t.jsx(h,{style:m,...p,children:c})}const Ln={id:"text",name:"Text",tier:"atom",domain:"neutral",specVersion:"0.1",description:"Polymorphic typography primitive that maps semantic HTML elements to design-system type scales.",designIntent:"Text is the single source of truth for typography in Lucent UI. Rather than hard-coding font sizes and colors directly in components, every piece of rendered text should pass through this atom. The `as` prop controls the HTML element (and therefore semantic meaning), while `size`, `weight`, `color`, and `lineHeight` control appearance independently — decoupling semantics from style. Use `truncate` only in constrained-width containers where overflow must be prevented; it applies overflow: hidden + text-overflow: ellipsis. The `family` prop enables inline code or monospaced content without switching components.",props:[{name:"as",type:"enum",required:!1,default:"p",description:"HTML element to render. Controls semantic meaning independently of visual style.",enumValues:["p","h1","h2","h3","h4","h5","h6","span","div","label","strong","em","code"]},{name:"size",type:"enum",required:!1,default:"md",description:"Font size from the type scale. Maps to the corresponding --lucent-font-size-* token.",enumValues:["xs","sm","md","lg","xl","2xl","3xl"]},{name:"weight",type:"enum",required:!1,default:"regular",description:"Font weight. Maps to --lucent-font-weight-* tokens.",enumValues:["regular","medium","semibold","bold"]},{name:"color",type:"enum",required:!1,default:"primary",description:"Semantic text color. All values adapt automatically in light and dark themes.",enumValues:["primary","secondary","disabled","inverse","onAccent","success","warning","danger","info"]},{name:"align",type:"enum",required:!1,default:"left",description:"Text alignment.",enumValues:["left","center","right"]},{name:"lineHeight",type:"enum",required:!1,default:"base",description:"Line height. tight=1.25, base=1.5, relaxed=1.75.",enumValues:["tight","base","relaxed"]},{name:"family",type:"enum",required:!1,default:"base",description:"Font family. Use mono for code or tabular data. Use display (Unbounded) for headings and marketing copy.",enumValues:["base","mono","display"]},{name:"truncate",type:"boolean",required:!1,default:"false",description:"Clips overflow text with an ellipsis. Requires the container to have a constrained width."},{name:"children",type:"ReactNode",required:!0,description:"The text content to render."},{name:"style",type:"object",required:!1,description:"Inline style overrides. Applied after computed token styles."}],usageExamples:[{title:"Heading",code:'<Text as="h1" size="3xl" weight="bold">Page title</Text>'},{title:"Body paragraph",code:'<Text size="md" color="secondary">Supporting copy goes here.</Text>'},{title:"Label",code:'<Text as="label" size="sm" weight="medium" htmlFor="email">Email</Text>'},{title:"Inline code",code:'<Text as="code" family="mono" size="sm">const x = 1;</Text>'},{title:"Truncated",code:"<Text truncate style={{ maxWidth: 200 }}>Very long text that will be clipped</Text>"},{title:"Status color",code:'<Text color="danger" size="xs">This field is required</Text>'}],compositionGraph:[],accessibility:{notes:'The rendered element determines the implicit ARIA role. Use heading elements (h1–h6) for document headings so screen readers can navigate the page structure. Use `as="label"` with `htmlFor` to associate labels with form controls. Decorative text needs no additional ARIA.'}};function Bn({children:e,href:n,isActive:a=!1,icon:o,disabled:r=!1,onClick:i,as:s,style:l}){const c=s??"a";return t.jsxs(c,{href:r?void 0:n,onClick:r?void 0:i,"aria-current":a?"page":void 0,"aria-disabled":r||void 0,style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-2) var(--lucent-space-3) var(--lucent-space-2) var(--lucent-space-4)",borderRadius:"var(--lucent-radius-md)",background:r?"transparent":a?"var(--lucent-accent-default)":"transparent",color:r?"var(--lucent-text-disabled)":a?"var(--lucent-text-on-accent)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:a?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",textDecoration:"none",cursor:r?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), color var(--lucent-duration-fast) var(--lucent-easing-default)",userSelect:"none",boxSizing:"border-box",...l},onMouseEnter:d=>{!r&&!a&&(d.currentTarget.style.background="var(--lucent-surface-secondary)")},onMouseLeave:d=>{!r&&!a&&(d.currentTarget.style.background="transparent")},children:[o!=null&&t.jsx("span",{style:{display:"flex",flexShrink:0,color:"inherit"},children:o}),e]})}const qn={sm:"3px",md:"4px",lg:"5px"},Pn={sm:"14px",md:"18px",lg:"22px"},Fn=`
56
56
  .lucent-slider {
57
57
  -webkit-appearance: none;
58
58
  appearance: none;
@@ -145,9 +145,9 @@
145
145
  border-color: var(--lucent-border-default);
146
146
  cursor: not-allowed;
147
147
  }
148
- `;function Nn({label:e,showValue:n=!1,size:a="md",min:o=0,max:r=100,step:i=1,value:s,defaultValue:l,disabled:c,id:u,onChange:f,style:d,...y}){const h=u??`lucent-slider-${Math.random().toString(36).slice(2,7)}`,w=s!==void 0,[v,g]=p.useState(l??Math.round((o+r)/2)),b=w?s:v,k=`${(b-o)/(r-o)*100}%`,D=S=>{w||g(Number(S.target.value)),f==null||f(S)};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:Fn}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%",fontFamily:"var(--lucent-font-family-base)",...d},children:[(e||n)&&t.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"baseline"},children:[e&&t.jsx("label",{htmlFor:h,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:c?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",cursor:c?"not-allowed":"default"},children:e}),n&&t.jsx("span",{style:{fontSize:"var(--lucent-font-size-sm)",color:c?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",fontVariantNumeric:"tabular-nums"},children:b})]}),t.jsx("input",{type:"range",id:h,className:"lucent-slider",min:o,max:r,step:i,disabled:c,value:w?s:v,onChange:D,style:{"--ls-track-h":qn[a],"--ls-thumb":Pn[a],"--ls-fill":k},...y})]})]})}const $n={id:"slider",name:"Slider",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A range input styled with Lucent tokens for selecting a numeric value within a bounded range.",designIntent:'Use Slider for continuous or stepped numeric inputs where the relative position matters — volume, brightness, border radius, spacing scale. Pair with showValue when the exact number is meaningful to the user. For precise numeric entry, use Input with type="number" instead. Disabled state uses muted colours without opacity hacks.',props:[{name:"min",type:"number",required:!1,default:"0",description:"Minimum value."},{name:"max",type:"number",required:!1,default:"100",description:"Maximum value."},{name:"step",type:"number",required:!1,default:"1",description:"Increment step between values."},{name:"value",type:"number",required:!1,description:"Controlled current value. Pair with onChange."},{name:"defaultValue",type:"number",required:!1,description:"Initial value for uncontrolled usage. Defaults to the midpoint of min/max."},{name:"onChange",type:"function",required:!1,description:"Called on every value change."},{name:"label",type:"string",required:!1,description:"Visible label rendered above the track."},{name:"showValue",type:"boolean",required:!1,default:"false",description:"Displays the current numeric value to the right of the label."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls track thickness and thumb diameter.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the control."}],usageExamples:[{title:"Basic",code:'<Slider label="Volume" showValue />'},{title:"Controlled",code:'<Slider label="Opacity" min={0} max={1} step={0.01} value={opacity} onChange={e => setOpacity(Number(e.target.value))} showValue />'},{title:"Sizes",code:`<Slider size="sm" label="Small" />
148
+ `;function Nn({label:e,showValue:n=!1,size:a="md",min:o=0,max:r=100,step:i=1,value:s,defaultValue:l,disabled:c,id:d,onChange:p,style:m,...h}){const u=d??`lucent-slider-${Math.random().toString(36).slice(2,7)}`,S=s!==void 0,[y,b]=f.useState(l??Math.round((o+r)/2)),v=S?s:y,w=`${(v-o)/(r-o)*100}%`,j=T=>{S||b(Number(T.target.value)),p==null||p(T)};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:Fn}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)",width:"100%",fontFamily:"var(--lucent-font-family-base)",...m},children:[(e||n)&&t.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"baseline"},children:[e&&t.jsx("label",{htmlFor:u,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:c?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",cursor:c?"not-allowed":"default"},children:e}),n&&t.jsx("span",{style:{fontSize:"var(--lucent-font-size-sm)",color:c?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",fontVariantNumeric:"tabular-nums"},children:v})]}),t.jsx("input",{type:"range",id:u,className:"lucent-slider",min:o,max:r,step:i,disabled:c,value:S?s:y,onChange:j,style:{"--ls-track-h":qn[a],"--ls-thumb":Pn[a],"--ls-fill":w},...h})]})]})}const $n={id:"slider",name:"Slider",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A range input styled with Lucent tokens for selecting a numeric value within a bounded range.",designIntent:'Use Slider for continuous or stepped numeric inputs where the relative position matters — volume, brightness, border radius, spacing scale. Pair with showValue when the exact number is meaningful to the user. For precise numeric entry, use Input with type="number" instead. Disabled state uses muted colours without opacity hacks.',props:[{name:"min",type:"number",required:!1,default:"0",description:"Minimum value."},{name:"max",type:"number",required:!1,default:"100",description:"Maximum value."},{name:"step",type:"number",required:!1,default:"1",description:"Increment step between values."},{name:"value",type:"number",required:!1,description:"Controlled current value. Pair with onChange."},{name:"defaultValue",type:"number",required:!1,description:"Initial value for uncontrolled usage. Defaults to the midpoint of min/max."},{name:"onChange",type:"function",required:!1,description:"Called on every value change."},{name:"label",type:"string",required:!1,description:"Visible label rendered above the track."},{name:"showValue",type:"boolean",required:!1,default:"false",description:"Displays the current numeric value to the right of the label."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls track thickness and thumb diameter.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the control."}],usageExamples:[{title:"Basic",code:'<Slider label="Volume" showValue />'},{title:"Controlled",code:'<Slider label="Opacity" min={0} max={1} step={0.01} value={opacity} onChange={e => setOpacity(Number(e.target.value))} showValue />'},{title:"Sizes",code:`<Slider size="sm" label="Small" />
149
149
  <Slider size="md" label="Medium" />
150
- <Slider size="lg" label="Large" />`},{title:"Disabled",code:'<Slider label="Locked" disabled defaultValue={40} />'}],compositionGraph:[],accessibility:{role:"slider",ariaAttributes:["aria-valuemin","aria-valuemax","aria-valuenow","aria-disabled"],keyboardInteractions:["ArrowRight / ArrowUp — increase value by step","ArrowLeft / ArrowDown — decrease value by step","Home — jump to min","End — jump to max"]}},Wn=2e3;function On(){return t.jsxs("svg",{width:13,height:13,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),t.jsx("path",{d:"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"})]})}function Vn(){return t.jsx("svg",{width:13,height:13,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:t.jsx("path",{d:"M20 6L9 17l-5-5"})})}function Hn({code:e,language:n,tabs:a,variant:o="code",helperText:r,showCopyButton:i=!0,style:s}){var b,k;const l=!!(a!=null&&a.length),[c,u]=p.useState(0),[f,d]=p.useState(!1),y=l?((b=a[c])==null?void 0:b.code)??"":e??"",h=l?(k=a[c])==null?void 0:k.language:n,w=async()=>{try{await navigator.clipboard.writeText(y),d(!0),setTimeout(()=>d(!1),Wn)}catch{}},v={display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",padding:"3px var(--lucent-space-2)",border:"1px solid transparent",borderRadius:"var(--lucent-radius-md)",background:"transparent",color:f?"var(--lucent-success-default)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",cursor:"pointer",flexShrink:0,transition:"color var(--lucent-duration-fast) var(--lucent-easing-default), background var(--lucent-duration-fast) var(--lucent-easing-default)"},g=()=>t.jsxs("button",{onClick:w,"aria-label":f?"Copied!":"Copy code",style:v,onMouseEnter:D=>{f||(D.currentTarget.style.background="var(--lucent-surface-secondary)",D.currentTarget.style.color="var(--lucent-text-primary)")},onMouseLeave:D=>{f||(D.currentTarget.style.background="transparent",D.currentTarget.style.color="var(--lucent-text-secondary)")},children:[f?t.jsx(Vn,{}):t.jsx(On,{}),f?"Copied!":"Copy"]});return t.jsxs("div",{style:{borderRadius:"var(--lucent-radius-lg)",border:"1px solid var(--lucent-border-default)",overflow:"hidden",...s},children:[l&&t.jsx("div",{style:{display:"flex",alignItems:"flex-end",background:"var(--lucent-surface)",borderBottom:"1px solid var(--lucent-border-default)",padding:"0 var(--lucent-space-2)"},children:a.map((D,S)=>{const x=S===c;return t.jsxs("button",{onClick:()=>{u(S),d(!1)},style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",padding:"var(--lucent-space-2) var(--lucent-space-3)",border:"none",borderBottom:x?"2px solid var(--lucent-accent-default)":"2px solid transparent",marginBottom:-1,background:"transparent",color:x?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",fontWeight:x?"var(--lucent-font-weight-semibold)":"var(--lucent-font-weight-regular)",cursor:"pointer",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)",whiteSpace:"nowrap"},onMouseEnter:z=>{x||(z.currentTarget.style.color="var(--lucent-text-primary)")},onMouseLeave:z=>{x||(z.currentTarget.style.color="var(--lucent-text-secondary)")},children:[D.icon!==void 0&&t.jsx("span",{style:{display:"inline-flex",alignItems:"center"},children:D.icon}),D.label]},D.label)})}),!l&&(!!h||i)&&t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:h?"space-between":"flex-end",padding:"0 var(--lucent-space-3)",height:36,background:"var(--lucent-surface-secondary)",borderBottom:"1px solid var(--lucent-border-default)"},children:[h&&t.jsx("span",{style:{fontSize:"var(--lucent-font-size-xs)",fontFamily:"var(--lucent-font-family-mono)",color:"var(--lucent-text-secondary)",letterSpacing:"var(--lucent-letter-spacing-wide)"},children:h}),i&&t.jsx(g,{})]}),r&&t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-4)",fontSize:"var(--lucent-font-size-xs)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",background:"var(--lucent-surface-secondary)",borderBottom:"1px solid var(--lucent-border-default)"},children:r}),o==="code"?t.jsxs("div",{style:{position:"relative"},children:[t.jsx("pre",{style:{margin:0,padding:"var(--lucent-space-4)",paddingRight:l&&i?"var(--lucent-space-16)":"var(--lucent-space-4)",background:"var(--lucent-surface-secondary)",overflowX:"auto",lineHeight:1.65},children:t.jsx("code",{style:{fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-primary)"},children:y})}),l&&i&&t.jsx("div",{style:{position:"absolute",top:"var(--lucent-space-2)",right:"var(--lucent-space-3)"},children:t.jsx(g,{})})]}):t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-3) var(--lucent-space-4)",background:"var(--lucent-surface-secondary)"},children:[t.jsx("span",{style:{flex:1,overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis",fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-primary)"},children:y}),i&&t.jsx(g,{})]})]})}const Gn={id:"code-block",name:"CodeBlock",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A styled code display with optional tabs, a language label, copy-to-clipboard, and an AI prompt variant.",designIntent:"Use CodeBlock for static code snippets, install commands, API examples, and AI prompt sharing. The tabs prop switches between related snippets (e.g. pnpm / npm / yarn). The prompt variant renders a single-line truncated display suited to AI tool prompts — the full text is always copied even when visually clipped. Zero-dependency — no syntax highlighting library is bundled.",props:[{name:"code",type:"string",required:!1,description:"Code string — used in single (non-tabbed) mode."},{name:"language",type:"string",required:!1,description:"Language label shown in the header (non-tabbed mode only). Purely cosmetic."},{name:"tabs",type:"array",required:!1,description:"Tabbed mode. Each entry has { label, code, language?, icon? }. Switching tabs resets the copied state."},{name:"variant",type:"enum",required:!1,default:"code",enumValues:["code","prompt"],description:'"code" renders a <pre><code> block with horizontal scroll. "prompt" renders a single-line truncated span suited to AI prompts.'},{name:"helperText",type:"string",required:!1,description:"Descriptive text rendered between the tab bar and the code area."},{name:"showCopyButton",type:"boolean",required:!1,default:"true",description:'Renders a copy-to-clipboard button. Shows a "Copied!" confirmation for 2 s on success.'}],usageExamples:[{title:"Single snippet",code:'<CodeBlock language="tsx" code={`<Button variant="primary">Save</Button>`} />'},{title:"Tabbed install commands",code:`<CodeBlock tabs={[
150
+ <Slider size="lg" label="Large" />`},{title:"Disabled",code:'<Slider label="Locked" disabled defaultValue={40} />'}],compositionGraph:[],accessibility:{role:"slider",ariaAttributes:["aria-valuemin","aria-valuemax","aria-valuenow","aria-disabled"],keyboardInteractions:["ArrowRight / ArrowUp — increase value by step","ArrowLeft / ArrowDown — decrease value by step","Home — jump to min","End — jump to max"]}},Wn=2e3;function On(){return t.jsxs("svg",{width:13,height:13,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),t.jsx("path",{d:"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"})]})}function Vn(){return t.jsx("svg",{width:13,height:13,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2.5,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:t.jsx("path",{d:"M20 6L9 17l-5-5"})})}function Hn({code:e,language:n,tabs:a,variant:o="code",helperText:r,showCopyButton:i=!0,style:s}){var v,w;const l=!!(a!=null&&a.length),[c,d]=f.useState(0),[p,m]=f.useState(!1),h=l?((v=a[c])==null?void 0:v.code)??"":e??"",u=l?(w=a[c])==null?void 0:w.language:n,S=async()=>{try{await navigator.clipboard.writeText(h),m(!0),setTimeout(()=>m(!1),Wn)}catch{}},y={display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",padding:"3px var(--lucent-space-2)",border:"1px solid transparent",borderRadius:"var(--lucent-radius-md)",background:"transparent",color:p?"var(--lucent-success-default)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",cursor:"pointer",flexShrink:0,transition:"color var(--lucent-duration-fast) var(--lucent-easing-default), background var(--lucent-duration-fast) var(--lucent-easing-default)"},b=()=>t.jsxs("button",{onClick:S,"aria-label":p?"Copied!":"Copy code",style:y,onMouseEnter:j=>{p||(j.currentTarget.style.background="var(--lucent-surface-secondary)",j.currentTarget.style.color="var(--lucent-text-primary)")},onMouseLeave:j=>{p||(j.currentTarget.style.background="transparent",j.currentTarget.style.color="var(--lucent-text-secondary)")},children:[p?t.jsx(Vn,{}):t.jsx(On,{}),p?"Copied!":"Copy"]});return t.jsxs("div",{style:{borderRadius:"var(--lucent-radius-lg)",border:"1px solid var(--lucent-border-default)",overflow:"hidden",...s},children:[l&&t.jsx("div",{style:{display:"flex",alignItems:"flex-end",background:"var(--lucent-surface)",borderBottom:"1px solid var(--lucent-border-default)",padding:"0 var(--lucent-space-2)"},children:a.map((j,T)=>{const x=T===c;return t.jsxs("button",{onClick:()=>{d(T),m(!1)},style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",padding:"var(--lucent-space-2) var(--lucent-space-3)",border:"none",borderBottom:x?"2px solid var(--lucent-accent-default)":"2px solid transparent",marginBottom:-1,background:"transparent",color:x?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",fontWeight:x?"var(--lucent-font-weight-semibold)":"var(--lucent-font-weight-regular)",cursor:"pointer",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)",whiteSpace:"nowrap"},onMouseEnter:M=>{x||(M.currentTarget.style.color="var(--lucent-text-primary)")},onMouseLeave:M=>{x||(M.currentTarget.style.color="var(--lucent-text-secondary)")},children:[j.icon!==void 0&&t.jsx("span",{style:{display:"inline-flex",alignItems:"center"},children:j.icon}),j.label]},j.label)})}),!l&&(!!u||i)&&t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:u?"space-between":"flex-end",padding:"0 var(--lucent-space-3)",height:36,background:"var(--lucent-surface-secondary)",borderBottom:"1px solid var(--lucent-border-default)"},children:[u&&t.jsx("span",{style:{fontSize:"var(--lucent-font-size-xs)",fontFamily:"var(--lucent-font-family-mono)",color:"var(--lucent-text-secondary)",letterSpacing:"var(--lucent-letter-spacing-wide)"},children:u}),i&&t.jsx(b,{})]}),r&&t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-4)",fontSize:"var(--lucent-font-size-xs)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",background:"var(--lucent-surface-secondary)",borderBottom:"1px solid var(--lucent-border-default)"},children:r}),o==="code"?t.jsxs("div",{style:{position:"relative"},children:[t.jsx("pre",{style:{margin:0,padding:"var(--lucent-space-4)",paddingRight:l&&i?"var(--lucent-space-16)":"var(--lucent-space-4)",background:"var(--lucent-surface-secondary)",overflowX:"auto",lineHeight:1.65},children:t.jsx("code",{style:{fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-primary)"},children:h})}),l&&i&&t.jsx("div",{style:{position:"absolute",top:"var(--lucent-space-2)",right:"var(--lucent-space-3)"},children:t.jsx(b,{})})]}):t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-3) var(--lucent-space-4)",background:"var(--lucent-surface-secondary)"},children:[t.jsx("span",{style:{flex:1,overflow:"hidden",whiteSpace:"nowrap",textOverflow:"ellipsis",fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-primary)"},children:h}),i&&t.jsx(b,{})]})]})}const Gn={id:"code-block",name:"CodeBlock",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A styled code display with optional tabs, a language label, copy-to-clipboard, and an AI prompt variant.",designIntent:"Use CodeBlock for static code snippets, install commands, API examples, and AI prompt sharing. The tabs prop switches between related snippets (e.g. pnpm / npm / yarn). The prompt variant renders a single-line truncated display suited to AI tool prompts — the full text is always copied even when visually clipped. Zero-dependency — no syntax highlighting library is bundled.",props:[{name:"code",type:"string",required:!1,description:"Code string — used in single (non-tabbed) mode."},{name:"language",type:"string",required:!1,description:"Language label shown in the header (non-tabbed mode only). Purely cosmetic."},{name:"tabs",type:"array",required:!1,description:"Tabbed mode. Each entry has { label, code, language?, icon? }. Switching tabs resets the copied state."},{name:"variant",type:"enum",required:!1,default:"code",enumValues:["code","prompt"],description:'"code" renders a <pre><code> block with horizontal scroll. "prompt" renders a single-line truncated span suited to AI prompts.'},{name:"helperText",type:"string",required:!1,description:"Descriptive text rendered between the tab bar and the code area."},{name:"showCopyButton",type:"boolean",required:!1,default:"true",description:'Renders a copy-to-clipboard button. Shows a "Copied!" confirmation for 2 s on success.'}],usageExamples:[{title:"Single snippet",code:'<CodeBlock language="tsx" code={`<Button variant="primary">Save</Button>`} />'},{title:"Tabbed install commands",code:`<CodeBlock tabs={[
151
151
  { label: 'pnpm', code: 'pnpm add lucent-ui', language: 'bash' },
152
152
  { label: 'npm', code: 'npm install lucent-ui', language: 'bash' },
153
153
  ]} />`},{title:"AI prompt",code:`<CodeBlock
@@ -166,7 +166,7 @@
166
166
  .lucent-table-striped tbody .lucent-table-row:nth-child(even) > th {
167
167
  background: var(--lucent-surface-secondary);
168
168
  }
169
- `;function _n({children:e,style:n,...a}){return t.jsx("thead",{style:{background:"var(--lucent-surface-secondary)",...n},...a,children:e})}function Yn({children:e,...n}){return t.jsx("tbody",{...n,children:e})}function Kn({children:e,style:n,...a}){return t.jsx("tfoot",{style:{background:"var(--lucent-surface-secondary)",...n},...a,children:e})}function Xn({children:e,className:n,...a}){return t.jsx("tr",{className:["lucent-table-row",n].filter(Boolean).join(" "),...a,children:e})}function Jn({as:e,children:n,style:a,...o}){const r=e==="th",i={padding:"var(--lucent-space-3) var(--lucent-space-4)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",borderBottom:"1px solid var(--lucent-border-default)",textAlign:"left",verticalAlign:"middle",color:r?"var(--lucent-text-secondary)":"var(--lucent-text-primary)",fontWeight:r?"var(--lucent-font-weight-semibold)":"var(--lucent-font-weight-regular)",whiteSpace:r?"nowrap":void 0,...a};return r?t.jsx("th",{scope:"col",style:i,...o,children:n}):t.jsx("td",{style:i,...o,children:n})}function ne({striped:e=!1,children:n,className:a,style:o,...r}){const i=["lucent-table",e&&"lucent-table-striped",a].filter(Boolean).join(" ");return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:Un}),t.jsx("div",{style:{overflowX:"auto",width:"100%"},children:t.jsx("table",{className:i,style:{width:"100%",borderCollapse:"collapse",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",...o},...r,children:n})})]})}ne.Head=_n;ne.Body=Yn;ne.Foot=Kn;ne.Row=Xn;ne.Cell=Jn;const Zn={id:"table",name:"Table",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A lightweight, token-styled HTML table primitive with compound sub-components. Distinct from DataTable — no sorting, filtering, or pagination.",designIntent:"Use Table for static or lightly dynamic tabular data where full DataTable features are not needed — props tables, changelog entries, comparison grids, reference docs. The compound API (Table.Head, Table.Body, Table.Row, Table.Cell) maps directly to semantic HTML so screen readers get the full table structure. Horizontal overflow is handled automatically by a scroll wrapper.",props:[{name:"striped",type:"boolean",required:!1,default:"false",description:"Applies alternating surfaceSecondary backgrounds to even tbody rows."},{name:"Table.Head",type:"component",required:!1,description:"Renders <thead> with surfaceSecondary background. Accepts Table.Row children."},{name:"Table.Body",type:"component",required:!1,description:"Renders <tbody>. Accepts Table.Row children."},{name:"Table.Foot",type:"component",required:!1,description:"Renders <tfoot> with surfaceSecondary background."},{name:"Table.Row",type:"component",required:!1,description:"Renders <tr> with a hover highlight. Accepts Table.Cell children."},{name:"Table.Cell",type:"component",required:!1,description:'Renders <td> by default or <th scope="col"> when as="th". Header cells are semibold + secondary colour; data cells are regular + primary.'}],usageExamples:[{title:"Basic",code:`<Table>
169
+ `;function _n({children:e,style:n,...a}){return t.jsx("thead",{style:{background:"var(--lucent-surface-secondary)",...n},...a,children:e})}function Yn({children:e,...n}){return t.jsx("tbody",{...n,children:e})}function Kn({children:e,style:n,...a}){return t.jsx("tfoot",{style:{background:"var(--lucent-surface-secondary)",...n},...a,children:e})}function Xn({children:e,className:n,...a}){return t.jsx("tr",{className:["lucent-table-row",n].filter(Boolean).join(" "),...a,children:e})}function Jn({as:e,children:n,style:a,...o}){const r=e==="th",i={padding:"var(--lucent-space-3) var(--lucent-space-4)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",borderBottom:"1px solid var(--lucent-border-default)",textAlign:"left",verticalAlign:"middle",color:r?"var(--lucent-text-secondary)":"var(--lucent-text-primary)",fontWeight:r?"var(--lucent-font-weight-semibold)":"var(--lucent-font-weight-regular)",whiteSpace:r?"nowrap":void 0,...a};return r?t.jsx("th",{scope:"col",style:i,...o,children:n}):t.jsx("td",{style:i,...o,children:n})}function ae({striped:e=!1,children:n,className:a,style:o,...r}){const i=["lucent-table",e&&"lucent-table-striped",a].filter(Boolean).join(" ");return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:Un}),t.jsx("div",{style:{overflowX:"auto",width:"100%"},children:t.jsx("table",{className:i,style:{width:"100%",borderCollapse:"collapse",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",...o},...r,children:n})})]})}ae.Head=_n;ae.Body=Yn;ae.Foot=Kn;ae.Row=Xn;ae.Cell=Jn;const Zn={id:"table",name:"Table",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A lightweight, token-styled HTML table primitive with compound sub-components. Distinct from DataTable — no sorting, filtering, or pagination.",designIntent:"Use Table for static or lightly dynamic tabular data where full DataTable features are not needed — props tables, changelog entries, comparison grids, reference docs. The compound API (Table.Head, Table.Body, Table.Row, Table.Cell) maps directly to semantic HTML so screen readers get the full table structure. Horizontal overflow is handled automatically by a scroll wrapper.",props:[{name:"striped",type:"boolean",required:!1,default:"false",description:"Applies alternating surfaceSecondary backgrounds to even tbody rows."},{name:"Table.Head",type:"component",required:!1,description:"Renders <thead> with surfaceSecondary background. Accepts Table.Row children."},{name:"Table.Body",type:"component",required:!1,description:"Renders <tbody>. Accepts Table.Row children."},{name:"Table.Foot",type:"component",required:!1,description:"Renders <tfoot> with surfaceSecondary background."},{name:"Table.Row",type:"component",required:!1,description:"Renders <tr> with a hover highlight. Accepts Table.Cell children."},{name:"Table.Cell",type:"component",required:!1,description:'Renders <td> by default or <th scope="col"> when as="th". Header cells are semibold + secondary colour; data cells are regular + primary.'}],usageExamples:[{title:"Basic",code:`<Table>
170
170
  <Table.Head>
171
171
  <Table.Row>
172
172
  <Table.Cell as="th">Name</Table.Cell>
@@ -184,11 +184,11 @@
184
184
  <Table.Body>…</Table.Body>
185
185
  </Table>`},{title:"Custom cell content",code:`<Table.Cell>
186
186
  <Badge variant="success">Active</Badge>
187
- </Table.Cell>`}],compositionGraph:[{componentId:"table-head",componentName:"Table.Head",role:"head",required:!1},{componentId:"table-body",componentName:"Table.Body",role:"body",required:!1},{componentId:"table-foot",componentName:"Table.Foot",role:"foot",required:!1},{componentId:"table-row",componentName:"Table.Row",role:"row",required:!1},{componentId:"table-cell",componentName:"Table.Cell",role:"cell",required:!1}],accessibility:{role:"table",ariaAttributes:['scope="col" on th cells'],keyboardInteractions:["Standard browser table navigation"]}},Ze={sm:"30px",md:"36px",lg:"42px"},Qn={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-sm)",lg:"var(--lucent-font-size-md)"},ea={sm:"var(--lucent-space-2)",md:"var(--lucent-space-3)",lg:"var(--lucent-space-4)"};function Ae({options:e,value:n,defaultValue:a,onChange:o,size:r="md",disabled:i=!1,fullWidth:s=!0,id:l,style:c}){var b;const[u,f]=p.useState(a??((b=e[0])==null?void 0:b.value)??""),d=n!==void 0?n:u,y=p.useRef(null),[h,w]=p.useState(null),v=p.useRef(!1);p.useLayoutEffect(()=>{const k=y.current;if(!k)return;const D=k.querySelector(`[data-sc-value="${d}"]`);D&&(w({left:D.offsetLeft,width:D.offsetWidth,animate:v.current}),v.current=!0)},[d,e]);const g=k=>{i||k.disabled||(n===void 0&&f(k.value),o==null||o(k.value))};return t.jsxs("div",{id:l,ref:y,role:"group",style:{position:"relative",display:"flex",alignItems:"center",width:s?"100%":"fit-content",height:Ze[r],background:"var(--lucent-surface-secondary)",borderRadius:"var(--lucent-radius-lg)",padding:2,gap:0,opacity:i?.5:1,...c},children:[h&&t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",top:2,left:h.left,width:h.width,height:"calc(100% - 4px)",background:"var(--lucent-surface)",borderRadius:"var(--lucent-radius-md)",boxShadow:"0 1px 2px rgba(0,0,0,0.1)",transition:h.animate?"left var(--lucent-duration-base) var(--lucent-easing-default), width var(--lucent-duration-base) var(--lucent-easing-default)":"none",zIndex:0,pointerEvents:"none"}}),e.map(k=>{const D=k.value===d,S=i||!!k.disabled;return t.jsx("button",{"data-sc-value":k.value,type:"button",role:"radio","aria-checked":D,disabled:S,onClick:()=>g(k),style:{position:"relative",zIndex:1,display:"flex",alignItems:"center",justifyContent:"center",gap:"var(--lucent-space-1)",flex:1,height:`calc(${Ze[r]} - 4px)`,padding:`0 ${ea[r]}`,fontSize:Qn[r],fontFamily:"var(--lucent-font-family-base)",fontWeight:D?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:S?"var(--lucent-text-disabled)":D?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",background:"transparent",border:"none",borderRadius:"var(--lucent-radius-md)",cursor:S?"not-allowed":"pointer",outline:"none",whiteSpace:"nowrap",transition:["color var(--lucent-duration-fast) var(--lucent-easing-default)","font-weight var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", ")},onFocus:x=>{x.currentTarget.style.boxShadow="0 0 0 2px var(--lucent-accent-subtle)"},onBlur:x=>{x.currentTarget.style.boxShadow="none"},children:k.label},k.value)})]})}Ae.displayName="SegmentedControl";const ta={xs:12,sm:16,md:22,lg:28,xl:36,"2xl":48},na={xs:"var(--lucent-radius-sm)",sm:"var(--lucent-radius-sm)",md:"var(--lucent-radius-md)",lg:"var(--lucent-radius-md)",xl:"var(--lucent-radius-lg)","2xl":"var(--lucent-radius-lg)"},Qe="inset 0 0 0 1px rgba(0,0,0,0.2)",et="inset 0 0 0 2px rgba(0,0,0,0.5)",aa="inset 0 0 0 1px rgba(0,0,0,0.2), 0 0 0 3px var(--lucent-accent-subtle)";function ra(e){return{backgroundImage:[`linear-gradient(${e}, ${e})`,"linear-gradient(45deg, #e5e5e5 25%, transparent 25%)","linear-gradient(-45deg, #e5e5e5 25%, transparent 25%)","linear-gradient(45deg, transparent 75%, #e5e5e5 75%)","linear-gradient(-45deg, transparent 75%, #e5e5e5 75%)"].join(", "),backgroundSize:"auto, 8px 8px, 8px 8px, 8px 8px, 8px 8px",backgroundPosition:"0 0, 0 0, 0 4px, 4px -4px, -4px 0",backgroundColor:"#fff"}}const se=p.forwardRef(({color:e,size:n="md",shape:a="circle",showCheckerboard:o=!1,selected:r=!1,disabled:i=!1,style:s,onFocus:l,onBlur:c,onClick:u,...f},d)=>{const y=ta[n],h=a==="circle"?"50%":na[n];return t.jsx("button",{ref:d,type:"button",disabled:i,onClick:u,style:{width:y,height:y,flexShrink:0,...o?ra(e):{background:e},border:"none",borderRadius:h,cursor:i?"not-allowed":u?"pointer":"default",padding:0,outline:"none",opacity:i?.4:1,boxShadow:r?et:Qe,transition:"box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)",...s},onFocus:w=>{i||(w.currentTarget.style.boxShadow=aa),l==null||l(w)},onBlur:w=>{w.currentTarget.style.boxShadow=r?et:Qe,c==null||c(w)},...f})});se.displayName="ColorSwatch";function ge(e,n,a){return Math.max(n,Math.min(a,e))}function oa(e,n,a){const o=n/100,r=a/100,i=r*o,s=i*(1-Math.abs(e/60%2-1)),l=r-i;let c=0,u=0,f=0;return e<60?(c=i,u=s):e<120?(c=s,u=i):e<180?(u=i,f=s):e<240?(u=s,f=i):e<300?(c=s,f=i):(c=i,f=s),{r:Math.round((c+l)*255),g:Math.round((u+l)*255),b:Math.round((f+l)*255)}}function ia(e,n,a){const o=e/255,r=n/255,i=a/255,s=Math.max(o,r,i),l=Math.min(o,r,i),c=s-l,u=s,f=s===0?0:c/s;let d=0;return c!==0&&(s===o?d=((r-i)/c+(r<i?6:0))/6:s===r?d=((i-o)/c+2)/6:d=((o-r)/c+4)/6),{h:Math.round(d*360),s:Math.round(f*100),v:Math.round(u*100)}}function sa(e,n,a){const o=e/255,r=n/255,i=a/255,s=Math.max(o,r,i),l=Math.min(o,r,i),c=(s+l)/2;if(s===l)return{h:0,s:0,l:Math.round(c*100)};const u=s-l,f=c>.5?u/(2-s-l):u/(s+l);let d=0;return s===o?d=((r-i)/u+(r<i?6:0))/6:s===r?d=((i-o)/u+2)/6:d=((o-r)/u+4)/6,{h:Math.round(d*360),s:Math.round(f*100),l:Math.round(c*100)}}function me(e,n,a){const o=n/100,r=a/100,i=(1-Math.abs(2*r-1))*o,s=i*(1-Math.abs(e/60%2-1)),l=r-i/2;let c=0,u=0,f=0;return e<60?(c=i,u=s):e<120?(c=s,u=i):e<180?(u=i,f=s):e<240?(u=s,f=i):e<300?(c=s,f=i):(c=i,f=s),{r:Math.round((c+l)*255),g:Math.round((u+l)*255),b:Math.round((f+l)*255)}}function ze(e){const n=e.replace("#","");return n.length===3?`#${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}`:n.length===6||n.length===8?`#${n}`:"#000000"}function ht(e){const n=ze(e);return{r:parseInt(n.slice(1,3),16),g:parseInt(n.slice(3,5),16),b:parseInt(n.slice(5,7),16),a:n.length===9?+(parseInt(n.slice(7,9),16)/255).toFixed(2):1}}function Se({r:e,g:n,b:a,a:o}){const r=s=>ge(Math.round(s),0,255).toString(16).padStart(2,"0"),i=`#${r(e)}${r(n)}${r(a)}`;return o<1?`${i}${r(Math.round(o*255))}`:i}function mt({h:e,s:n,v:a,a:o}){return{...oa(e,n,a),a:o}}function U({r:e,g:n,b:a,a:o}){return{...ia(e,n,a),a:o}}function de(e){return Se(mt(e))}function ue(e){const n=e.trim();if(n.startsWith("#")){const r=ze(n);return/^#[0-9a-f]{6}([0-9a-f]{2})?$/i.test(r)?ht(r):null}const a=n.match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*([\d.]+))?\s*\)$/);if(a){const r=+(a[1]??"0"),i=+(a[2]??"0"),s=+(a[3]??"0"),l=a[4]!==void 0?+a[4]:1;return[r,i,s].every(c=>c<=255)&&l>=0&&l<=1?{r,g:i,b:s,a:l}:null}const o=n.match(/^hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%?\s*,\s*(\d{1,3})%?\s*\)$/);if(o){const r=+(o[1]??"0"),i=+(o[2]??"0"),s=+(o[3]??"0");return r<=360&&i<=100&&s<=100?{...me(r,i,s),a:1}:null}return null}const la=[{label:"Presets",colors:["#000000","#2563eb","#16a34a","#ca8a04","#dc2626","#0ea5e9","#9333ea","#4f46e5","#e11d48"]}],ca=["linear-gradient(45deg, #c0c0c0 25%, transparent 25%)","linear-gradient(-45deg, #c0c0c0 25%, transparent 25%)","linear-gradient(45deg, transparent 75%, #c0c0c0 75%)","linear-gradient(-45deg, transparent 75%, #c0c0c0 75%)"].join(", ");function tt({value:e,min:n,max:a,onChange:o,trackStyle:r,formatTooltip:i}){const s=p.useRef(null),[l,c]=p.useState(!1),u=p.useCallback(d=>{const y=s.current.getBoundingClientRect(),h=ge((d.clientX-y.left)/y.width,0,1);o(n+h*(a-n))},[n,a,o]),f=(e-n)/(a-n)*100;return t.jsx("div",{ref:s,style:{position:"relative",height:12,borderRadius:6,cursor:"crosshair",userSelect:"none",...r},onPointerDown:d=>{d.currentTarget.setPointerCapture(d.pointerId),c(!0),u(d)},onPointerMove:d=>{d.buttons>0&&u(d)},onPointerUp:()=>c(!1),onPointerCancel:()=>c(!1),children:t.jsx("div",{style:{position:"absolute",left:`${f}%`,top:"50%",transform:"translate(-50%, -50%)",width:14,height:14,borderRadius:"50%",background:"white",border:"2px solid rgba(0,0,0,0.22)",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",zIndex:1,pointerEvents:"none"},children:l&&i&&t.jsx("div",{style:{position:"absolute",bottom:"100%",left:"50%",transform:"translateX(-50%)",marginBottom:6,background:"rgba(0,0,0,0.75)",color:"#fff",fontSize:11,fontFamily:"var(--lucent-font-family-base)",fontWeight:500,borderRadius:4,padding:"2px 6px",whiteSpace:"nowrap",pointerEvents:"none"},children:i(e)})})})}function da(){return t.jsxs("svg",{width:14,height:14,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("path",{d:"M2 22l1-1h3l9-9"}),t.jsx("path",{d:"M3 21v-3l9-9"}),t.jsx("path",{d:"M15 6l3.4-3.4a2.1 2.1 0 1 1 3 3L18 9l.4.4a2.1 2.1 0 1 1-3 3l-3.8-3.8a2.1 2.1 0 1 1 3-3l.4.4Z"})]})}function gt({value:e,onChange:n,label:a,disabled:o=!1,presetGroups:r=la,id:i,style:s}){var _,ae;const l=p.useId(),c=i??l,[u,f]=p.useState(!1),[d,y]=p.useState("hex"),[h,w]=p.useState(0),[v,g]=p.useState(()=>{const m=e?ue(e)??{r:0,g:0,b:0,a:1}:{r:0,g:0,b:0,a:1};return U(m)}),[b,k]=p.useState(()=>de(v).slice(1).toUpperCase()),D=p.useRef(null),S=p.useRef(null),x=p.useRef(null),[z,q]=p.useState(!1);p.useLayoutEffect(()=>{if(!u||!x.current)return;const m=x.current.getBoundingClientRect();q(m.right>window.innerWidth)},[u]),p.useEffect(()=>{if(!e)return;const m=ue(e);m&&(g(U(m)),k(Se(m).slice(1).toUpperCase()))},[e]),p.useEffect(()=>{if(!u)return;const m=A=>{D.current&&!D.current.contains(A.target)&&f(!1)};return document.addEventListener("mousedown",m),()=>document.removeEventListener("mousedown",m)},[u]);const T=p.useCallback(m=>{g(m);const A=de(m);k(A.slice(1).toUpperCase()),n==null||n(A)},[n]),C=p.useCallback(m=>{const A=S.current.getBoundingClientRect(),E=Math.round(ge((m.clientX-A.left)/A.width,0,1)*100),L=Math.round((1-ge((m.clientY-A.top)/A.height,0,1))*100);T({...v,s:E,v:L})},[v,T]),V=p.useCallback(async()=>{if("EyeDropper"in window)try{const m=await new window.EyeDropper().open(),A=ue(m.sRGBHex);A&&T(U(A))}catch{}},[T]),R=mt(v),I=sa(R.r,R.g,R.b),j=de(v),M=de({...v,a:1}),P=Math.round(v.a*100),G=[{id:"hex",label:"Hex"},{id:"rgb",label:"RGB"},{id:"hsl",label:"HSL"},{id:"hsb",label:"HSB"}],H=typeof window<"u"&&"EyeDropper"in window;return t.jsxs("div",{ref:D,style:{display:"inline-flex",flexDirection:"column",gap:"var(--lucent-space-1)",position:"relative",...s},children:[t.jsx("style",{children:`
187
+ </Table.Cell>`}],compositionGraph:[{componentId:"table-head",componentName:"Table.Head",role:"head",required:!1},{componentId:"table-body",componentName:"Table.Body",role:"body",required:!1},{componentId:"table-foot",componentName:"Table.Foot",role:"foot",required:!1},{componentId:"table-row",componentName:"Table.Row",role:"row",required:!1},{componentId:"table-cell",componentName:"Table.Cell",role:"cell",required:!1}],accessibility:{role:"table",ariaAttributes:['scope="col" on th cells'],keyboardInteractions:["Standard browser table navigation"]}},Ze={sm:"30px",md:"36px",lg:"42px"},Qn={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-sm)",lg:"var(--lucent-font-size-md)"},ea={sm:"var(--lucent-space-2)",md:"var(--lucent-space-3)",lg:"var(--lucent-space-4)"};function ze({options:e,value:n,defaultValue:a,onChange:o,size:r="md",disabled:i=!1,fullWidth:s=!0,id:l,style:c}){var v;const[d,p]=f.useState(a??((v=e[0])==null?void 0:v.value)??""),m=n!==void 0?n:d,h=f.useRef(null),[u,S]=f.useState(null),y=f.useRef(!1);f.useLayoutEffect(()=>{const w=h.current;if(!w)return;const j=w.querySelector(`[data-sc-value="${m}"]`);j&&(S({left:j.offsetLeft,width:j.offsetWidth,animate:y.current}),y.current=!0)},[m,e]);const b=w=>{i||w.disabled||(n===void 0&&p(w.value),o==null||o(w.value))};return t.jsxs("div",{id:l,ref:h,role:"group",style:{position:"relative",display:"flex",alignItems:"center",width:s?"100%":"fit-content",height:Ze[r],background:"var(--lucent-surface-secondary)",borderRadius:"var(--lucent-radius-lg)",padding:2,gap:0,opacity:i?.5:1,...c},children:[u&&t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",top:2,left:u.left,width:u.width,height:"calc(100% - 4px)",background:"var(--lucent-surface)",borderRadius:"var(--lucent-radius-md)",boxShadow:"0 1px 2px rgba(0,0,0,0.1)",transition:u.animate?"left var(--lucent-duration-base) var(--lucent-easing-default), width var(--lucent-duration-base) var(--lucent-easing-default)":"none",zIndex:0,pointerEvents:"none"}}),e.map(w=>{const j=w.value===m,T=i||!!w.disabled;return t.jsx("button",{"data-sc-value":w.value,type:"button",role:"radio","aria-checked":j,disabled:T,onClick:()=>b(w),style:{position:"relative",zIndex:1,display:"flex",alignItems:"center",justifyContent:"center",gap:"var(--lucent-space-1)",flex:1,height:`calc(${Ze[r]} - 4px)`,padding:`0 ${ea[r]}`,fontSize:Qn[r],fontFamily:"var(--lucent-font-family-base)",fontWeight:j?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:T?"var(--lucent-text-disabled)":j?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",background:"transparent",border:"none",borderRadius:"var(--lucent-radius-md)",cursor:T?"not-allowed":"pointer",outline:"none",whiteSpace:"nowrap",transition:["color var(--lucent-duration-fast) var(--lucent-easing-default)","font-weight var(--lucent-duration-fast) var(--lucent-easing-default)"].join(", ")},onFocus:x=>{x.currentTarget.style.boxShadow="0 0 0 2px var(--lucent-accent-subtle)"},onBlur:x=>{x.currentTarget.style.boxShadow="none"},children:w.label},w.value)})]})}ze.displayName="SegmentedControl";const ta={xs:12,sm:16,md:22,lg:28,xl:36,"2xl":48},na={xs:"var(--lucent-radius-sm)",sm:"var(--lucent-radius-sm)",md:"var(--lucent-radius-md)",lg:"var(--lucent-radius-md)",xl:"var(--lucent-radius-lg)","2xl":"var(--lucent-radius-lg)"},Qe="inset 0 0 0 1px rgba(0,0,0,0.2)",et="inset 0 0 0 2px rgba(0,0,0,0.5)",aa="inset 0 0 0 1px rgba(0,0,0,0.2), 0 0 0 3px var(--lucent-accent-subtle)";function ra(e){return{backgroundImage:[`linear-gradient(${e}, ${e})`,"linear-gradient(45deg, #e5e5e5 25%, transparent 25%)","linear-gradient(-45deg, #e5e5e5 25%, transparent 25%)","linear-gradient(45deg, transparent 75%, #e5e5e5 75%)","linear-gradient(-45deg, transparent 75%, #e5e5e5 75%)"].join(", "),backgroundSize:"auto, 8px 8px, 8px 8px, 8px 8px, 8px 8px",backgroundPosition:"0 0, 0 0, 0 4px, 4px -4px, -4px 0",backgroundColor:"#fff"}}const se=f.forwardRef(({color:e,size:n="md",shape:a="circle",showCheckerboard:o=!1,selected:r=!1,disabled:i=!1,style:s,onFocus:l,onBlur:c,onClick:d,...p},m)=>{const h=ta[n],u=a==="circle"?"50%":na[n];return t.jsx("button",{ref:m,type:"button",disabled:i,onClick:d,style:{width:h,height:h,flexShrink:0,...o?ra(e):{background:e},border:"none",borderRadius:u,cursor:i?"not-allowed":d?"pointer":"default",padding:0,outline:"none",opacity:i?.4:1,boxShadow:r?et:Qe,transition:"box-shadow var(--lucent-duration-fast) var(--lucent-easing-default)",...s},onFocus:S=>{i||(S.currentTarget.style.boxShadow=aa),l==null||l(S)},onBlur:S=>{S.currentTarget.style.boxShadow=r?et:Qe,c==null||c(S)},...p})});se.displayName="ColorSwatch";function ge(e,n,a){return Math.max(n,Math.min(a,e))}function oa(e,n,a){const o=n/100,r=a/100,i=r*o,s=i*(1-Math.abs(e/60%2-1)),l=r-i;let c=0,d=0,p=0;return e<60?(c=i,d=s):e<120?(c=s,d=i):e<180?(d=i,p=s):e<240?(d=s,p=i):e<300?(c=s,p=i):(c=i,p=s),{r:Math.round((c+l)*255),g:Math.round((d+l)*255),b:Math.round((p+l)*255)}}function ia(e,n,a){const o=e/255,r=n/255,i=a/255,s=Math.max(o,r,i),l=Math.min(o,r,i),c=s-l,d=s,p=s===0?0:c/s;let m=0;return c!==0&&(s===o?m=((r-i)/c+(r<i?6:0))/6:s===r?m=((i-o)/c+2)/6:m=((o-r)/c+4)/6),{h:Math.round(m*360),s:Math.round(p*100),v:Math.round(d*100)}}function sa(e,n,a){const o=e/255,r=n/255,i=a/255,s=Math.max(o,r,i),l=Math.min(o,r,i),c=(s+l)/2;if(s===l)return{h:0,s:0,l:Math.round(c*100)};const d=s-l,p=c>.5?d/(2-s-l):d/(s+l);let m=0;return s===o?m=((r-i)/d+(r<i?6:0))/6:s===r?m=((i-o)/d+2)/6:m=((o-r)/d+4)/6,{h:Math.round(m*360),s:Math.round(p*100),l:Math.round(c*100)}}function me(e,n,a){const o=n/100,r=a/100,i=(1-Math.abs(2*r-1))*o,s=i*(1-Math.abs(e/60%2-1)),l=r-i/2;let c=0,d=0,p=0;return e<60?(c=i,d=s):e<120?(c=s,d=i):e<180?(d=i,p=s):e<240?(d=s,p=i):e<300?(c=s,p=i):(c=i,p=s),{r:Math.round((c+l)*255),g:Math.round((d+l)*255),b:Math.round((p+l)*255)}}function Ae(e){const n=e.replace("#","");return n.length===3?`#${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}`:n.length===6||n.length===8?`#${n}`:"#000000"}function mt(e){const n=Ae(e);return{r:parseInt(n.slice(1,3),16),g:parseInt(n.slice(3,5),16),b:parseInt(n.slice(5,7),16),a:n.length===9?+(parseInt(n.slice(7,9),16)/255).toFixed(2):1}}function Te({r:e,g:n,b:a,a:o}){const r=s=>ge(Math.round(s),0,255).toString(16).padStart(2,"0"),i=`#${r(e)}${r(n)}${r(a)}`;return o<1?`${i}${r(Math.round(o*255))}`:i}function gt({h:e,s:n,v:a,a:o}){return{...oa(e,n,a),a:o}}function Y({r:e,g:n,b:a,a:o}){return{...ia(e,n,a),a:o}}function de(e){return Te(gt(e))}function ue(e){const n=e.trim();if(n.startsWith("#")){const r=Ae(n);return/^#[0-9a-f]{6}([0-9a-f]{2})?$/i.test(r)?mt(r):null}const a=n.match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*([\d.]+))?\s*\)$/);if(a){const r=+(a[1]??"0"),i=+(a[2]??"0"),s=+(a[3]??"0"),l=a[4]!==void 0?+a[4]:1;return[r,i,s].every(c=>c<=255)&&l>=0&&l<=1?{r,g:i,b:s,a:l}:null}const o=n.match(/^hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%?\s*,\s*(\d{1,3})%?\s*\)$/);if(o){const r=+(o[1]??"0"),i=+(o[2]??"0"),s=+(o[3]??"0");return r<=360&&i<=100&&s<=100?{...me(r,i,s),a:1}:null}return null}const la=[{label:"Presets",colors:["#000000","#2563eb","#16a34a","#ca8a04","#dc2626","#0ea5e9","#9333ea","#4f46e5","#e11d48"]}],ca=["linear-gradient(45deg, #c0c0c0 25%, transparent 25%)","linear-gradient(-45deg, #c0c0c0 25%, transparent 25%)","linear-gradient(45deg, transparent 75%, #c0c0c0 75%)","linear-gradient(-45deg, transparent 75%, #c0c0c0 75%)"].join(", ");function tt({value:e,min:n,max:a,onChange:o,trackStyle:r,formatTooltip:i}){const s=f.useRef(null),[l,c]=f.useState(!1),d=f.useCallback(m=>{const h=s.current.getBoundingClientRect(),u=ge((m.clientX-h.left)/h.width,0,1);o(n+u*(a-n))},[n,a,o]),p=(e-n)/(a-n)*100;return t.jsx("div",{ref:s,style:{position:"relative",height:12,borderRadius:6,cursor:"crosshair",userSelect:"none",...r},onPointerDown:m=>{m.currentTarget.setPointerCapture(m.pointerId),c(!0),d(m)},onPointerMove:m=>{m.buttons>0&&d(m)},onPointerUp:()=>c(!1),onPointerCancel:()=>c(!1),children:t.jsx("div",{style:{position:"absolute",left:`${p}%`,top:"50%",transform:"translate(-50%, -50%)",width:14,height:14,borderRadius:"50%",background:"white",border:"2px solid rgba(0,0,0,0.22)",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",zIndex:1,pointerEvents:"none"},children:l&&i&&t.jsx("div",{style:{position:"absolute",bottom:"100%",left:"50%",transform:"translateX(-50%)",marginBottom:6,background:"rgba(0,0,0,0.75)",color:"#fff",fontSize:11,fontFamily:"var(--lucent-font-family-base)",fontWeight:500,borderRadius:4,padding:"2px 6px",whiteSpace:"nowrap",pointerEvents:"none"},children:i(e)})})})}function da(){return t.jsxs("svg",{width:14,height:14,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:[t.jsx("path",{d:"M2 22l1-1h3l9-9"}),t.jsx("path",{d:"M3 21v-3l9-9"}),t.jsx("path",{d:"M15 6l3.4-3.4a2.1 2.1 0 1 1 3 3L18 9l.4.4a2.1 2.1 0 1 1-3 3l-3.8-3.8a2.1 2.1 0 1 1 3-3l.4.4Z"})]})}function bt({value:e,onChange:n,label:a,disabled:o=!1,presetGroups:r=la,id:i,style:s}){var G,U;const l=f.useId(),c=i??l,[d,p]=f.useState(!1),[m,h]=f.useState("hex"),[u,S]=f.useState(0),[y,b]=f.useState(()=>{const g=e?ue(e)??{r:0,g:0,b:0,a:1}:{r:0,g:0,b:0,a:1};return Y(g)}),[v,w]=f.useState(()=>de(y).slice(1).toUpperCase()),j=f.useRef(null),T=f.useRef(null),x=f.useRef(null),[M,F]=f.useState(!1);f.useLayoutEffect(()=>{if(!d||!x.current)return;const g=x.current.getBoundingClientRect();F(g.right>window.innerWidth)},[d]),f.useEffect(()=>{if(!e)return;const g=ue(e);g&&(b(Y(g)),w(Te(g).slice(1).toUpperCase()))},[e]),f.useEffect(()=>{if(!d)return;const g=D=>{j.current&&!j.current.contains(D.target)&&p(!1)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[d]);const k=f.useCallback(g=>{b(g);const D=de(g);w(D.slice(1).toUpperCase()),n==null||n(D)},[n]),z=f.useCallback(g=>{const D=T.current.getBoundingClientRect(),A=Math.round(ge((g.clientX-D.left)/D.width,0,1)*100),B=Math.round((1-ge((g.clientY-D.top)/D.height,0,1))*100);k({...y,s:A,v:B})},[y,k]),q=f.useCallback(async()=>{if("EyeDropper"in window)try{const g=await new window.EyeDropper().open(),D=ue(g.sRGBHex);D&&k(Y(D))}catch{}},[k]),E=gt(y),C=sa(E.r,E.g,E.b),R=de(y),I=de({...y,a:1}),L=Math.round(y.a*100),W=[{id:"hex",label:"Hex"},{id:"rgb",label:"RGB"},{id:"hsl",label:"HSL"},{id:"hsb",label:"HSB"}],N=typeof window<"u"&&"EyeDropper"in window;return t.jsxs("div",{ref:j,style:{display:"inline-flex",flexDirection:"column",gap:"var(--lucent-space-1)",position:"relative",...s},children:[t.jsx("style",{children:`
188
188
  .lucent-cp-field::-webkit-outer-spin-button,
189
189
  .lucent-cp-field::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
190
190
  .lucent-cp-field { -moz-appearance: textfield; }
191
- `}),a&&t.jsx("label",{htmlFor:`${c}-swatch`,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:o?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:a}),t.jsx(se,{id:`${c}-swatch`,color:`rgba(${R.r},${R.g},${R.b},${v.a})`,shape:"square",showCheckerboard:!0,disabled:o,onClick:()=>f(m=>!m),"aria-expanded":u,"aria-haspopup":"dialog",style:{width:40,height:40,borderRadius:"var(--lucent-radius-lg)",boxShadow:u?"inset 0 0 0 2px var(--lucent-focus-ring), 0 0 0 3px var(--lucent-accent-subtle)":"inset 0 0 0 1px rgba(0,0,0,0.2)"}}),u&&t.jsxs("div",{ref:x,role:"dialog","aria-label":"Color picker",style:{position:"absolute",top:"calc(100% + 8px)",...z?{right:0}:{left:0},zIndex:1e3,background:"var(--lucent-surface)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-xl)",boxShadow:"var(--lucent-shadow-md)",width:280,overflow:"hidden",display:"flex",flexDirection:"column"},children:[t.jsxs("div",{ref:S,style:{position:"relative",height:160,background:`hsl(${v.h}, 100%, 50%)`,cursor:"crosshair",userSelect:"none",flexShrink:0},onPointerDown:m=>{m.currentTarget.setPointerCapture(m.pointerId),C(m)},onPointerMove:m=>{m.buttons>0&&C(m)},children:[t.jsx("div",{style:{position:"absolute",inset:0,background:"linear-gradient(to right, #fff, transparent)"}}),t.jsx("div",{style:{position:"absolute",inset:0,background:"linear-gradient(to bottom, transparent, #000)"}}),t.jsx("div",{style:{position:"absolute",left:`${v.s}%`,top:`${100-v.v}%`,transform:"translate(-50%, -50%)",width:14,height:14,borderRadius:"50%",border:"2px solid #fff",boxShadow:"0 0 0 1px rgba(0,0,0,0.25), 0 2px 4px rgba(0,0,0,0.35)",pointerEvents:"none"}})]}),t.jsxs("div",{style:{padding:12,display:"flex",flexDirection:"column",gap:10},children:[t.jsxs("div",{style:{display:"flex",gap:10,alignItems:"center"},children:[t.jsx(se,{color:`rgba(${R.r},${R.g},${R.b},${v.a})`,shape:"square",showCheckerboard:!0,style:{width:44,height:44,borderRadius:8}}),t.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:8},children:[t.jsx(tt,{value:v.h,min:0,max:360,onChange:m=>T({...v,h:Math.round(m)}),trackStyle:{background:"linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)"},formatTooltip:m=>`${Math.round(m)}°`}),t.jsxs("div",{style:{position:"relative",borderRadius:6,overflow:"hidden"},children:[t.jsx("div",{style:{position:"absolute",inset:0,backgroundImage:ca,backgroundSize:"8px 8px",backgroundPosition:"0 0, 0 4px, 4px -4px, -4px 0",backgroundColor:"#fff"}}),t.jsx("div",{style:{position:"absolute",inset:0,background:`linear-gradient(to right, transparent, ${M})`}}),t.jsx(tt,{value:v.a,min:0,max:1,onChange:m=>T({...v,a:Math.round(m*100)/100}),trackStyle:{background:"transparent",position:"relative",zIndex:1},formatTooltip:m=>`${Math.round(m*100)}%`})]})]})]}),t.jsx(Ae,{size:"sm",value:d,onChange:m=>y(m),options:G.map(({id:m,label:A})=>({value:m,label:A}))}),d==="hex"&&t.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[t.jsx(De,{variant:"secondary",size:"sm",onClick:V,disabled:!H,title:H?"Pick color from screen":"Not supported in this browser",leftIcon:t.jsx(da,{}),style:{flexShrink:0,paddingLeft:8,paddingRight:8}}),t.jsx(Y,{size:"sm",prefix:"#",value:b,onChange:m=>{const A=m.target.value.replace("#","");k(A.toUpperCase());const E=ue(`#${A}`);if(E){const L=U(E);g(L),n==null||n(Se(E))}},spellCheck:!1,placeholder:"000000",maxLength:8,style:{flex:1}}),t.jsx(Y,{size:"sm",type:"number",suffix:"%",value:P,min:0,max:100,onChange:m=>{const A=+m.target.value;!isNaN(A)&&A>=0&&A<=100&&T({...v,a:A/100})},className:"lucent-cp-field",style:{width:68,flexShrink:0}})]}),d==="rgb"&&t.jsx("div",{style:{display:"flex",gap:6},children:[{label:"R",val:R.r,max:255,fn:m=>T(U({...R,r:m}))},{label:"G",val:R.g,max:255,fn:m=>T(U({...R,g:m}))},{label:"B",val:R.b,max:255,fn:m=>T(U({...R,b:m}))},{label:"A",val:P,max:100,fn:m=>T({...v,a:m/100})}].map(({label:m,val:A,max:E,fn:L})=>t.jsx(Y,{size:"sm",type:"number",prefix:m,value:A,min:0,max:E,onChange:N=>{const $=+N.target.value;!isNaN($)&&$>=0&&$<=E&&L($)},className:"lucent-cp-field",style:{flex:1}},m))}),d==="hsl"&&t.jsx("div",{style:{display:"flex",gap:6},children:[{label:"H",val:I.h,max:360,fn:m=>{const{r:A,g:E,b:L}=me(m,I.s,I.l);T(U({r:A,g:E,b:L,a:v.a}))}},{label:"S",val:I.s,max:100,fn:m=>{const{r:A,g:E,b:L}=me(I.h,m,I.l);T(U({r:A,g:E,b:L,a:v.a}))}},{label:"L",val:I.l,max:100,fn:m=>{const{r:A,g:E,b:L}=me(I.h,I.s,m);T(U({r:A,g:E,b:L,a:v.a}))}},{label:"A",val:P,max:100,fn:m=>T({...v,a:m/100})}].map(({label:m,val:A,max:E,fn:L})=>t.jsx(Y,{size:"sm",type:"number",prefix:m,value:A,min:0,max:E,onChange:N=>{const $=+N.target.value;!isNaN($)&&$>=0&&$<=E&&L($)},className:"lucent-cp-field",style:{flex:1}},m))}),d==="hsb"&&t.jsx("div",{style:{display:"flex",gap:6},children:[{label:"H",val:v.h,max:360,fn:m=>T({...v,h:m})},{label:"S",val:v.s,max:100,fn:m=>T({...v,s:m})},{label:"B",val:v.v,max:100,fn:m=>T({...v,v:m})},{label:"A",val:P,max:100,fn:m=>T({...v,a:m/100})}].map(({label:m,val:A,max:E,fn:L})=>t.jsx(Y,{size:"sm",type:"number",prefix:m,value:A,min:0,max:E,onChange:N=>{const $=+N.target.value;!isNaN($)&&$>=0&&$<=E&&L($)},className:"lucent-cp-field",style:{flex:1}},m))}),r.length>0&&t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[r.length>1&&t.jsx(Me,{size:"sm",value:String(h),onChange:m=>w(Number(m.target.value)),options:r.map((m,A)=>({value:String(A),label:m.label}))}),r.length===1&&t.jsx("span",{style:{fontSize:"var(--lucent-font-size-xs)",fontWeight:"var(--lucent-font-weight-medium)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:(_=r[0])==null?void 0:_.label}),t.jsx("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:(((ae=r[h])==null?void 0:ae.colors)??[]).map(m=>{const A=ze(m).toLowerCase()===j.slice(0,7).toLowerCase();return t.jsx(se,{color:m,selected:A,onClick:()=>T(U(ht(m)))},m)})})]})]})]})]})}gt.displayName="ColorPicker";const ua={id:"color-picker",name:"ColorPicker",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A color swatch button that opens a popover with preset swatches and HEX / RGB / RGBA / HSL inputs.",designIntent:"ColorPicker surfaces color selection without navigating away. The swatch button shows the current color at a glance; the popover provides precise input through four format modes. Presets accelerate common choices — provide a curated palette relevant to the product. Always pair with a visible label so the purpose of the picker is clear.",props:[{name:"value",type:"string",required:!1,description:"Controlled color value. Accepts hex (#rrggbb / #rrggbbaa), rgb(), rgba(), or hsl() strings."},{name:"onChange",type:"function",required:!1,description:"Called with the new hex string (#rrggbb, or #rrggbbaa when alpha < 1) whenever the color changes."},{name:"label",type:"string",required:!1,description:"Visible label rendered above the swatch button."},{name:"presets",type:"string[]",required:!1,description:"Array of hex color strings shown as clickable swatches. Defaults to a 16-color palette."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the label."},{name:"id",type:"string",required:!1,description:"HTML id for the swatch button. Auto-generated if omitted."},{name:"style",type:"CSSProperties",required:!1,description:"Inline styles applied to the outer wrapper."}],usageExamples:[{title:"Basic controlled",code:`const [color, setColor] = useState('#3b82f6');
191
+ `}),a&&t.jsx("label",{htmlFor:`${c}-swatch`,style:{fontSize:"var(--lucent-font-size-sm)",fontWeight:"var(--lucent-font-weight-medium)",color:o?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)"},children:a}),t.jsx(se,{id:`${c}-swatch`,color:`rgba(${E.r},${E.g},${E.b},${y.a})`,shape:"square",showCheckerboard:!0,disabled:o,onClick:()=>p(g=>!g),"aria-expanded":d,"aria-haspopup":"dialog",style:{width:40,height:40,borderRadius:"var(--lucent-radius-lg)",boxShadow:d?"inset 0 0 0 2px var(--lucent-focus-ring), 0 0 0 3px var(--lucent-accent-subtle)":"inset 0 0 0 1px rgba(0,0,0,0.2)"}}),d&&t.jsxs("div",{ref:x,role:"dialog","aria-label":"Color picker",style:{position:"absolute",top:"calc(100% + 8px)",...M?{right:0}:{left:0},zIndex:1e3,background:"var(--lucent-surface)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-xl)",boxShadow:"var(--lucent-shadow-md)",width:280,overflow:"hidden",display:"flex",flexDirection:"column"},children:[t.jsxs("div",{ref:T,style:{position:"relative",height:160,background:`hsl(${y.h}, 100%, 50%)`,cursor:"crosshair",userSelect:"none",flexShrink:0},onPointerDown:g=>{g.currentTarget.setPointerCapture(g.pointerId),z(g)},onPointerMove:g=>{g.buttons>0&&z(g)},children:[t.jsx("div",{style:{position:"absolute",inset:0,background:"linear-gradient(to right, #fff, transparent)"}}),t.jsx("div",{style:{position:"absolute",inset:0,background:"linear-gradient(to bottom, transparent, #000)"}}),t.jsx("div",{style:{position:"absolute",left:`${y.s}%`,top:`${100-y.v}%`,transform:"translate(-50%, -50%)",width:14,height:14,borderRadius:"50%",border:"2px solid #fff",boxShadow:"0 0 0 1px rgba(0,0,0,0.25), 0 2px 4px rgba(0,0,0,0.35)",pointerEvents:"none"}})]}),t.jsxs("div",{style:{padding:12,display:"flex",flexDirection:"column",gap:10},children:[t.jsxs("div",{style:{display:"flex",gap:10,alignItems:"center"},children:[t.jsx(se,{color:`rgba(${E.r},${E.g},${E.b},${y.a})`,shape:"square",showCheckerboard:!0,style:{width:44,height:44,borderRadius:8}}),t.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:8},children:[t.jsx(tt,{value:y.h,min:0,max:360,onChange:g=>k({...y,h:Math.round(g)}),trackStyle:{background:"linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)"},formatTooltip:g=>`${Math.round(g)}°`}),t.jsxs("div",{style:{position:"relative",borderRadius:6,overflow:"hidden"},children:[t.jsx("div",{style:{position:"absolute",inset:0,backgroundImage:ca,backgroundSize:"8px 8px",backgroundPosition:"0 0, 0 4px, 4px -4px, -4px 0",backgroundColor:"#fff"}}),t.jsx("div",{style:{position:"absolute",inset:0,background:`linear-gradient(to right, transparent, ${I})`}}),t.jsx(tt,{value:y.a,min:0,max:1,onChange:g=>k({...y,a:Math.round(g*100)/100}),trackStyle:{background:"transparent",position:"relative",zIndex:1},formatTooltip:g=>`${Math.round(g*100)}%`})]})]})]}),t.jsx(ze,{size:"sm",value:m,onChange:g=>h(g),options:W.map(({id:g,label:D})=>({value:g,label:D}))}),m==="hex"&&t.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[t.jsx(De,{variant:"secondary",size:"sm",onClick:q,disabled:!N,title:N?"Pick color from screen":"Not supported in this browser",leftIcon:t.jsx(da,{}),style:{flexShrink:0,paddingLeft:8,paddingRight:8}}),t.jsx(K,{size:"sm",prefix:"#",value:v,onChange:g=>{const D=g.target.value.replace("#","");w(D.toUpperCase());const A=ue(`#${D}`);if(A){const B=Y(A);b(B),n==null||n(Te(A))}},spellCheck:!1,placeholder:"000000",maxLength:8,style:{flex:1}}),t.jsx(K,{size:"sm",type:"number",suffix:"%",value:L,min:0,max:100,onChange:g=>{const D=+g.target.value;!isNaN(D)&&D>=0&&D<=100&&k({...y,a:D/100})},className:"lucent-cp-field",style:{width:68,flexShrink:0}})]}),m==="rgb"&&t.jsx("div",{style:{display:"flex",gap:6},children:[{label:"R",val:E.r,max:255,fn:g=>k(Y({...E,r:g}))},{label:"G",val:E.g,max:255,fn:g=>k(Y({...E,g}))},{label:"B",val:E.b,max:255,fn:g=>k(Y({...E,b:g}))},{label:"A",val:L,max:100,fn:g=>k({...y,a:g/100})}].map(({label:g,val:D,max:A,fn:B})=>t.jsx(K,{size:"sm",type:"number",prefix:g,value:D,min:0,max:A,onChange:O=>{const V=+O.target.value;!isNaN(V)&&V>=0&&V<=A&&B(V)},className:"lucent-cp-field",style:{flex:1}},g))}),m==="hsl"&&t.jsx("div",{style:{display:"flex",gap:6},children:[{label:"H",val:C.h,max:360,fn:g=>{const{r:D,g:A,b:B}=me(g,C.s,C.l);k(Y({r:D,g:A,b:B,a:y.a}))}},{label:"S",val:C.s,max:100,fn:g=>{const{r:D,g:A,b:B}=me(C.h,g,C.l);k(Y({r:D,g:A,b:B,a:y.a}))}},{label:"L",val:C.l,max:100,fn:g=>{const{r:D,g:A,b:B}=me(C.h,C.s,g);k(Y({r:D,g:A,b:B,a:y.a}))}},{label:"A",val:L,max:100,fn:g=>k({...y,a:g/100})}].map(({label:g,val:D,max:A,fn:B})=>t.jsx(K,{size:"sm",type:"number",prefix:g,value:D,min:0,max:A,onChange:O=>{const V=+O.target.value;!isNaN(V)&&V>=0&&V<=A&&B(V)},className:"lucent-cp-field",style:{flex:1}},g))}),m==="hsb"&&t.jsx("div",{style:{display:"flex",gap:6},children:[{label:"H",val:y.h,max:360,fn:g=>k({...y,h:g})},{label:"S",val:y.s,max:100,fn:g=>k({...y,s:g})},{label:"B",val:y.v,max:100,fn:g=>k({...y,v:g})},{label:"A",val:L,max:100,fn:g=>k({...y,a:g/100})}].map(({label:g,val:D,max:A,fn:B})=>t.jsx(K,{size:"sm",type:"number",prefix:g,value:D,min:0,max:A,onChange:O=>{const V=+O.target.value;!isNaN(V)&&V>=0&&V<=A&&B(V)},className:"lucent-cp-field",style:{flex:1}},g))}),r.length>0&&t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[r.length>1&&t.jsx(Me,{size:"sm",value:String(u),onChange:g=>S(Number(g.target.value)),options:r.map((g,D)=>({value:String(D),label:g.label}))}),r.length===1&&t.jsx("span",{style:{fontSize:"var(--lucent-font-size-xs)",fontWeight:"var(--lucent-font-weight-medium)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)"},children:(G=r[0])==null?void 0:G.label}),t.jsx("div",{style:{display:"flex",gap:6,flexWrap:"wrap"},children:(((U=r[u])==null?void 0:U.colors)??[]).map(g=>{const D=Ae(g).toLowerCase()===R.slice(0,7).toLowerCase();return t.jsx(se,{color:g,selected:D,onClick:()=>k(Y(mt(g)))},g)})})]})]})]})]})}bt.displayName="ColorPicker";const ua={id:"color-picker",name:"ColorPicker",tier:"atom",domain:"neutral",specVersion:"0.1",description:"A color swatch button that opens a popover with preset swatches and HEX / RGB / RGBA / HSL inputs.",designIntent:"ColorPicker surfaces color selection without navigating away. The swatch button shows the current color at a glance; the popover provides precise input through four format modes. Presets accelerate common choices — provide a curated palette relevant to the product. Always pair with a visible label so the purpose of the picker is clear.",props:[{name:"value",type:"string",required:!1,description:"Controlled color value. Accepts hex (#rrggbb / #rrggbbaa), rgb(), rgba(), or hsl() strings."},{name:"onChange",type:"function",required:!1,description:"Called with the new hex string (#rrggbb, or #rrggbbaa when alpha < 1) whenever the color changes."},{name:"label",type:"string",required:!1,description:"Visible label rendered above the swatch button."},{name:"presets",type:"string[]",required:!1,description:"Array of hex color strings shown as clickable swatches. Defaults to a 16-color palette."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Prevents interaction and dims the label."},{name:"id",type:"string",required:!1,description:"HTML id for the swatch button. Auto-generated if omitted."},{name:"style",type:"CSSProperties",required:!1,description:"Inline styles applied to the outer wrapper."}],usageExamples:[{title:"Basic controlled",code:`const [color, setColor] = useState('#3b82f6');
192
192
  <ColorPicker value={color} onChange={setColor} label="Brand color" />`},{title:"Custom presets",code:`<ColorPicker
193
193
  value={accent}
194
194
  onChange={setAccent}
@@ -214,7 +214,7 @@
214
214
  ]}
215
215
  />`},{title:"Full-width, sizes",code:`<SegmentedControl fullWidth size="sm" defaultValue="a" options={[{ value: 'a', label: 'Alpha' }, { value: 'b', label: 'Beta' }]} />
216
216
  <SegmentedControl fullWidth size="md" defaultValue="a" options={[{ value: 'a', label: 'Alpha' }, { value: 'b', label: 'Beta' }]} />
217
- <SegmentedControl fullWidth size="lg" defaultValue="a" options={[{ value: 'a', label: 'Alpha' }, { value: 'b', label: 'Beta' }]} />`}],compositionGraph:[],accessibility:{role:"group (radiogroup)",ariaAttributes:["aria-checked",'role="radio"',"disabled"],keyboardInteractions:["Tab — focuses the group","Click — selects an option"]}};function ha({label:e,htmlFor:n,required:a=!1,helperText:o,errorMessage:r,children:i,style:s}){const l=r??o,c=r?"danger":"secondary";return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)",...s},children:[e&&t.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:"var(--lucent-space-1)"},children:[t.jsx(B,{as:"label",size:"sm",weight:"medium",lineHeight:"tight",...n!==void 0&&{htmlFor:n},children:e}),a&&t.jsx(B,{as:"span",size:"sm",color:"danger",lineHeight:"tight","aria-hidden":"true",children:"*"})]}),i,l&&t.jsx(B,{size:"xs",color:c,lineHeight:"tight",children:l})]})}const ma={id:"form-field",name:"FormField",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"Wraps any form control (Input, Select, Textarea) with a label, helper text, and validation message.",designIntent:"FormField standardises the vertical rhythm around form controls. A label is linked to the control via htmlFor so screen readers announce it correctly. The required asterisk is decorative (aria-hidden) because the actual required state should be communicated on the input via aria-required. Helper text provides proactive guidance; errorMessage replaces it when validation fails, using danger color to draw attention. The gap between elements uses space-2 to create a tight but breathable stack.",props:[{name:"label",type:"string",required:!1,description:"Label text rendered above the control as a <label> element."},{name:"htmlFor",type:"string",required:!1,description:"ID of the form control this label describes. Forwarded to the label htmlFor attribute."},{name:"required",type:"boolean",required:!1,default:"false",description:"Appends a danger-colored asterisk after the label text."},{name:"helperText",type:"string",required:!1,description:"Secondary text below the control providing guidance. Hidden when errorMessage is set."},{name:"errorMessage",type:"string",required:!1,description:"Validation error shown in danger color below the control. Replaces helperText when set."},{name:"children",type:"ReactNode",required:!0,description:"The form control to wrap — typically Input, Select, or Textarea."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Basic field",code:`<FormField label="Email" htmlFor="email">
217
+ <SegmentedControl fullWidth size="lg" defaultValue="a" options={[{ value: 'a', label: 'Alpha' }, { value: 'b', label: 'Beta' }]} />`}],compositionGraph:[],accessibility:{role:"group (radiogroup)",ariaAttributes:["aria-checked",'role="radio"',"disabled"],keyboardInteractions:["Tab — focuses the group","Click — selects an option"]}};function ha({label:e,htmlFor:n,required:a=!1,helperText:o,errorMessage:r,children:i,style:s}){const l=r??o,c=r?"danger":"secondary";return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)",...s},children:[e&&t.jsxs("div",{style:{display:"flex",alignItems:"baseline",gap:"var(--lucent-space-1)"},children:[t.jsx(P,{as:"label",size:"sm",weight:"medium",lineHeight:"tight",...n!==void 0&&{htmlFor:n},children:e}),a&&t.jsx(P,{as:"span",size:"sm",color:"danger",lineHeight:"tight","aria-hidden":"true",children:"*"})]}),i,l&&t.jsx(P,{size:"xs",color:c,lineHeight:"tight",children:l})]})}const ma={id:"form-field",name:"FormField",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"Wraps any form control (Input, Select, Textarea) with a label, helper text, and validation message.",designIntent:"FormField standardises the vertical rhythm around form controls. A label is linked to the control via htmlFor so screen readers announce it correctly. The required asterisk is decorative (aria-hidden) because the actual required state should be communicated on the input via aria-required. Helper text provides proactive guidance; errorMessage replaces it when validation fails, using danger color to draw attention. The gap between elements uses space-2 to create a tight but breathable stack.",props:[{name:"label",type:"string",required:!1,description:"Label text rendered above the control as a <label> element."},{name:"htmlFor",type:"string",required:!1,description:"ID of the form control this label describes. Forwarded to the label htmlFor attribute."},{name:"required",type:"boolean",required:!1,default:"false",description:"Appends a danger-colored asterisk after the label text."},{name:"helperText",type:"string",required:!1,description:"Secondary text below the control providing guidance. Hidden when errorMessage is set."},{name:"errorMessage",type:"string",required:!1,description:"Validation error shown in danger color below the control. Replaces helperText when set."},{name:"children",type:"ReactNode",required:!0,description:"The form control to wrap — typically Input, Select, or Textarea."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Basic field",code:`<FormField label="Email" htmlFor="email">
218
218
  <Input id="email" placeholder="you@example.com" />
219
219
  </FormField>`},{title:"Required with helper",code:`<FormField label="Username" htmlFor="username" required helperText="Letters and numbers only">
220
220
  <Input id="username" />
@@ -222,7 +222,7 @@
222
222
  <Input id="pw" type="password" />
223
223
  </FormField>`},{title:"Wrapping a Select",code:`<FormField label="Country" htmlFor="country">
224
224
  <Select id="country" options={countryOptions} />
225
- </FormField>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Label, helper text, and error message",required:!1}],accessibility:{ariaAttributes:["aria-required","aria-describedby"],notes:'Link the wrapped control to an error message using aria-describedby on the control and a matching id on the error element for full screen reader support. The required asterisk is aria-hidden; set aria-required="true" on the control itself.'}},ga=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"6.5",cy:"6.5",r:"4",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M9.5 9.5L13 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),ba=()=>t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M3 3L11 11M11 3L3 11",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})});function va({value:e,onChange:n,placeholder:a="Search…",size:o="md",results:r=[],onResultSelect:i,isLoading:s=!1,disabled:l=!1,id:c,style:u}){const[f,d]=p.useState(!1),[y,h]=p.useState(null),w=p.useRef(null),v=f&&r.length>0,g=()=>{n("")},b=x=>{i==null||i(x),d(!1)},k=()=>{w.current=setTimeout(()=>d(!1),150)},D=()=>{w.current&&clearTimeout(w.current),d(!0)},S=s?t.jsx(ut,{size:"sm"}):e?t.jsx("button",{type:"button","aria-label":"Clear search",onClick:g,style:{display:"flex",alignItems:"center",background:"none",border:"none",cursor:"pointer",padding:2,borderRadius:"var(--lucent-radius-sm)",color:"var(--lucent-text-secondary)"},onMouseEnter:x=>{x.currentTarget.style.color="var(--lucent-text-primary)"},onMouseLeave:x=>{x.currentTarget.style.color="var(--lucent-text-secondary)"},children:t.jsx(ba,{})}):null;return t.jsxs("div",{style:{position:"relative",...u},children:[t.jsx(Y,{id:c,type:"search",size:o,value:e,onChange:x=>n(x.target.value),placeholder:a,disabled:l,leftElement:t.jsx(ga,{}),rightElement:S??void 0,onFocus:D,onBlur:k}),v&&t.jsx("div",{role:"listbox",style:{position:"absolute",top:"calc(100% + var(--lucent-space-1))",left:0,right:0,zIndex:50,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-md)",boxShadow:"var(--lucent-shadow-md)",overflow:"hidden"},children:r.map((x,z)=>t.jsx("div",{role:"option","aria-selected":!1,onMouseDown:()=>b(x),onMouseEnter:()=>h(z),onMouseLeave:()=>h(null),style:{padding:"var(--lucent-space-2) var(--lucent-space-3)",cursor:"pointer",background:y===z?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:t.jsx(B,{as:"span",size:"md",children:x.label})},x.id))})]})}const ya={id:"search-input",name:"SearchInput",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"A search field with a built-in magnifier icon, clear button, and an optional results dropdown.",designIntent:"SearchInput is intentionally dumb about filtering — the consumer passes already-filtered results so the component stays stateless and flexible. The clear button appears only when the input has a value, keeping the right side clean at rest. The results dropdown is rendered absolutely below the input and closes after a 150ms delay on blur to allow result clicks to register before focus is lost. Spinner replaces the clear button during loading to communicate async state without layout shift.",props:[{name:"value",type:"string",required:!0,description:"Controlled input value."},{name:"onChange",type:"function",required:!0,description:"Called with the new string value whenever the input changes."},{name:"placeholder",type:"string",required:!1,default:'"Search…"',description:"Placeholder text for the input."},{name:"results",type:"array",required:!1,default:"[]",description:"Pre-filtered list of SearchResult objects ({ id, label }) to display in the dropdown."},{name:"onResultSelect",type:"function",required:!1,description:"Called with the selected SearchResult when a dropdown item is clicked."},{name:"isLoading",type:"boolean",required:!1,default:"false",description:"Shows a spinner in the right slot to indicate async search in progress."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the input."},{name:"id",type:"string",required:!1,description:"HTML id forwarded to the underlying input element."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Basic controlled search",code:`const [query, setQuery] = useState('');
225
+ </FormField>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Label, helper text, and error message",required:!1}],accessibility:{ariaAttributes:["aria-required","aria-describedby"],notes:'Link the wrapped control to an error message using aria-describedby on the control and a matching id on the error element for full screen reader support. The required asterisk is aria-hidden; set aria-required="true" on the control itself.'}},ga=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"6.5",cy:"6.5",r:"4",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M9.5 9.5L13 13",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),ba=()=>t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M3 3L11 11M11 3L3 11",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})});function va({value:e,onChange:n,placeholder:a="Search…",size:o="md",results:r=[],onResultSelect:i,isLoading:s=!1,disabled:l=!1,id:c,style:d}){const[p,m]=f.useState(!1),[h,u]=f.useState(null),S=f.useRef(null),y=p&&r.length>0,b=()=>{n("")},v=x=>{i==null||i(x),m(!1)},w=()=>{S.current=setTimeout(()=>m(!1),150)},j=()=>{S.current&&clearTimeout(S.current),m(!0)},T=s?t.jsx(ut,{size:"sm"}):e?t.jsx("button",{type:"button","aria-label":"Clear search",onClick:b,style:{display:"flex",alignItems:"center",background:"none",border:"none",cursor:"pointer",padding:2,borderRadius:"var(--lucent-radius-sm)",color:"var(--lucent-text-secondary)"},onMouseEnter:x=>{x.currentTarget.style.color="var(--lucent-text-primary)"},onMouseLeave:x=>{x.currentTarget.style.color="var(--lucent-text-secondary)"},children:t.jsx(ba,{})}):null;return t.jsxs("div",{style:{position:"relative",...d},children:[t.jsx(K,{id:c,type:"search",size:o,value:e,onChange:x=>n(x.target.value),placeholder:a,disabled:l,leftElement:t.jsx(ga,{}),rightElement:T??void 0,onFocus:j,onBlur:w}),y&&t.jsx("div",{role:"listbox",style:{position:"absolute",top:"calc(100% + var(--lucent-space-1))",left:0,right:0,zIndex:50,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-md)",boxShadow:"var(--lucent-shadow-md)",overflow:"hidden"},children:r.map((x,M)=>t.jsx("div",{role:"option","aria-selected":!1,onMouseDown:()=>v(x),onMouseEnter:()=>u(M),onMouseLeave:()=>u(null),style:{padding:"var(--lucent-space-2) var(--lucent-space-3)",cursor:"pointer",background:h===M?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:t.jsx(P,{as:"span",size:"md",children:x.label})},x.id))})]})}const ya={id:"search-input",name:"SearchInput",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"A search field with a built-in magnifier icon, clear button, and an optional results dropdown.",designIntent:"SearchInput is intentionally dumb about filtering — the consumer passes already-filtered results so the component stays stateless and flexible. The clear button appears only when the input has a value, keeping the right side clean at rest. The results dropdown is rendered absolutely below the input and closes after a 150ms delay on blur to allow result clicks to register before focus is lost. Spinner replaces the clear button during loading to communicate async state without layout shift.",props:[{name:"value",type:"string",required:!0,description:"Controlled input value."},{name:"onChange",type:"function",required:!0,description:"Called with the new string value whenever the input changes."},{name:"placeholder",type:"string",required:!1,default:'"Search…"',description:"Placeholder text for the input."},{name:"results",type:"array",required:!1,default:"[]",description:"Pre-filtered list of SearchResult objects ({ id, label }) to display in the dropdown."},{name:"onResultSelect",type:"function",required:!1,description:"Called with the selected SearchResult when a dropdown item is clicked."},{name:"isLoading",type:"boolean",required:!1,default:"false",description:"Shows a spinner in the right slot to indicate async search in progress."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the input."},{name:"id",type:"string",required:!1,description:"HTML id forwarded to the underlying input element."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Basic controlled search",code:`const [query, setQuery] = useState('');
226
226
  const [results, setResults] = useState([]);
227
227
 
228
228
  <SearchInput
@@ -230,7 +230,7 @@ const [results, setResults] = useState([]);
230
230
  onChange={(v) => { setQuery(v); setResults(filter(v)); }}
231
231
  results={results}
232
232
  onResultSelect={(r) => console.log(r)}
233
- />`},{title:"Loading state",code:"<SearchInput value={query} onChange={setQuery} isLoading={isFetching} results={[]} />"}],compositionGraph:[{componentId:"input",componentName:"Input",role:"Search text field with icon slots",required:!0},{componentId:"spinner",componentName:"Spinner",role:"Loading indicator in the right slot",required:!1}],accessibility:{role:"combobox",ariaAttributes:["aria-expanded","aria-haspopup","aria-label"],keyboardInteractions:["Enter to select focused result","Escape to close dropdown"],notes:'The results list uses role="listbox" with role="option" items. For full keyboard navigation (arrow keys to move between results), wire up onKeyDown on the Input and manage an activeIndex state.'}},bt=p.createContext("0"),xa={none:"0",sm:"var(--lucent-space-4)",md:"var(--lucent-space-6)",lg:"var(--lucent-space-8)"},wa={none:"var(--lucent-shadow-none)",sm:"var(--lucent-shadow-sm)",md:"var(--lucent-shadow-md)",lg:"var(--lucent-shadow-lg)"},ka={none:"var(--lucent-radius-none)",sm:"var(--lucent-radius-sm)",md:"var(--lucent-radius-md)",lg:"var(--lucent-radius-lg)"};function Sa({header:e,footer:n,children:a,padding:o="md",shadow:r="sm",radius:i="md",style:s}){const l=xa[o],c=ka[i];return t.jsxs("div",{style:{display:"flex",flexDirection:"column",background:"var(--lucent-surface)",border:"1px solid var(--lucent-border-default)",borderRadius:c,boxShadow:wa[r],overflow:"hidden",boxSizing:"border-box",...s},children:[e!=null&&t.jsx("div",{style:{padding:l,borderBottom:"1px solid var(--lucent-border-default)"},children:e}),t.jsx(bt.Provider,{value:l,children:t.jsx("div",{style:{padding:l,flex:1},children:a})}),n!=null&&t.jsx("div",{style:{padding:l,borderTop:"1px solid var(--lucent-border-default)"},children:n})]})}function Ta({children:e,style:n}){const a=p.useContext(bt);return t.jsx("div",{style:{marginLeft:`calc(-1 * ${a})`,marginRight:`calc(-1 * ${a})`,paddingLeft:a,paddingRight:a,...n},children:e})}const ja={id:"card",name:"Card",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"A surface container with optional header, body, and footer slots, configurable padding, shadow, and radius. Includes a CardBleed sub-component for edge-to-edge content.",designIntent:`Card provides a consistent elevated surface for grouping related content. The header and footer slots are separated from the body by a border-default divider, giving visual structure without requiring the consumer to manage spacing. Padding, shadow, and radius are all configurable to accommodate flat/ghost cards, modal-like surfaces, and compact data-dense layouts. The overflow: hidden ensures children respect the border-radius without needing additional clipping.
233
+ />`},{title:"Loading state",code:"<SearchInput value={query} onChange={setQuery} isLoading={isFetching} results={[]} />"}],compositionGraph:[{componentId:"input",componentName:"Input",role:"Search text field with icon slots",required:!0},{componentId:"spinner",componentName:"Spinner",role:"Loading indicator in the right slot",required:!1}],accessibility:{role:"combobox",ariaAttributes:["aria-expanded","aria-haspopup","aria-label"],keyboardInteractions:["Enter to select focused result","Escape to close dropdown"],notes:'The results list uses role="listbox" with role="option" items. For full keyboard navigation (arrow keys to move between results), wire up onKeyDown on the Input and manage an activeIndex state.'}},vt=f.createContext("0"),xa={none:"0",sm:"var(--lucent-space-4)",md:"var(--lucent-space-6)",lg:"var(--lucent-space-8)"},wa={none:"var(--lucent-shadow-none)",sm:"var(--lucent-shadow-sm)",md:"var(--lucent-shadow-md)",lg:"var(--lucent-shadow-lg)"},ka={none:"var(--lucent-radius-none)",sm:"var(--lucent-radius-sm)",md:"var(--lucent-radius-md)",lg:"var(--lucent-radius-lg)"};function Sa({header:e,footer:n,children:a,padding:o="md",shadow:r="sm",radius:i="md",style:s}){const l=xa[o],c=ka[i];return t.jsxs("div",{style:{display:"flex",flexDirection:"column",background:"var(--lucent-surface)",border:"1px solid var(--lucent-border-default)",borderRadius:c,boxShadow:wa[r],overflow:"hidden",boxSizing:"border-box",...s},children:[e!=null&&t.jsx("div",{style:{padding:l,borderBottom:"1px solid var(--lucent-border-default)"},children:e}),t.jsx(vt.Provider,{value:l,children:t.jsx("div",{style:{padding:l,flex:1},children:a})}),n!=null&&t.jsx("div",{style:{padding:l,borderTop:"1px solid var(--lucent-border-default)"},children:n})]})}function Ta({children:e,style:n}){const a=f.useContext(vt);return t.jsx("div",{style:{marginLeft:`calc(-1 * ${a})`,marginRight:`calc(-1 * ${a})`,paddingLeft:a,paddingRight:a,...n},children:e})}const ja={id:"card",name:"Card",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"A surface container with optional header, body, and footer slots, configurable padding, shadow, and radius. Includes a CardBleed sub-component for edge-to-edge content.",designIntent:`Card provides a consistent elevated surface for grouping related content. The header and footer slots are separated from the body by a border-default divider, giving visual structure without requiring the consumer to manage spacing. Padding, shadow, and radius are all configurable to accommodate flat/ghost cards, modal-like surfaces, and compact data-dense layouts. The overflow: hidden ensures children respect the border-radius without needing additional clipping.
234
234
 
235
235
  CardBleed is a companion component that allows specific children within the Card body to stretch edge-to-edge, cancelling the horizontal padding via negative margins. Text inside CardBleed stays aligned with the rest of the card content thanks to matching inner padding. Use it for dividers, full-width lists, or bordered sections that need to reach the card edges.
236
236
 
@@ -248,11 +248,11 @@ Token rule: Card uses surface for its background. Never use bgBase or bgSubtle o
248
248
  <CardBleed style={{ borderTop: '1px solid var(--lucent-border-default)', marginTop: 'var(--lucent-space-4)' }}>
249
249
  <Text color="secondary">This section stretches to the card edges.</Text>
250
250
  </CardBleed>
251
- </Card>`}],compositionGraph:[],accessibility:{notes:"Card has no implicit ARIA role. If the card represents a landmark, wrap it in a <section> or <article> and provide an aria-label. For interactive cards (clickable), make the wrapper a <button> or <a> and ensure focus styles are visible."}},Ca={info:{bg:"var(--lucent-info-subtle)",border:"var(--lucent-info-default)",iconColor:"var(--lucent-info-text)",textColor:"info"},success:{bg:"var(--lucent-success-subtle)",border:"var(--lucent-success-default)",iconColor:"var(--lucent-success-text)",textColor:"success"},warning:{bg:"var(--lucent-warning-subtle)",border:"var(--lucent-warning-default)",iconColor:"var(--lucent-warning-text)",textColor:"warning"},danger:{bg:"var(--lucent-danger-subtle)",border:"var(--lucent-danger-default)",iconColor:"var(--lucent-danger-text)",textColor:"danger"}},Da=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M8 5.5V8.5M8 10.5V11",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),Ia=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M5 8L7 10L11 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),Ma=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("path",{d:"M8 2L14.5 13H1.5L8 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M8 6V9M8 11V11.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),Aa=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M5.5 5.5L10.5 10.5M10.5 5.5L5.5 10.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),za={info:t.jsx(Da,{}),success:t.jsx(Ia,{}),warning:t.jsx(Ma,{}),danger:t.jsx(Aa,{})},Ea=()=>t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M3 3L11 11M11 3L3 11",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})});function Ra({variant:e="info",title:n,children:a,onDismiss:o,icon:r,style:i}){const s=Ca[e],l=r??za[e];return t.jsxs("div",{role:"alert",style:{display:"flex",alignItems:"flex-start",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-3) var(--lucent-space-4)",background:s.bg,border:`1px solid ${s.border}`,borderRadius:"var(--lucent-radius-md)",boxSizing:"border-box",...i},children:[t.jsx("span",{style:{flexShrink:0,color:s.iconColor,display:"flex",alignItems:"center",paddingTop:2},children:l}),t.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)"},children:[n&&t.jsx(B,{as:"span",size:"sm",weight:"semibold",color:s.textColor,lineHeight:"tight",children:n}),a&&t.jsx(B,{as:"span",size:"sm",color:s.textColor,lineHeight:"base",children:a})]}),o&&t.jsx("button",{type:"button","aria-label":"Dismiss",onClick:o,style:{flexShrink:0,display:"flex",alignItems:"center",background:"none",border:"none",cursor:"pointer",padding:2,borderRadius:"var(--lucent-radius-sm)",color:s.iconColor,opacity:.7},onMouseEnter:c=>{c.currentTarget.style.opacity="1"},onMouseLeave:c=>{c.currentTarget.style.opacity="0.7"},children:t.jsx(Ea,{})})]})}const La={id:"alert",name:"Alert",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"An inline feedback banner with info, success, warning, and danger variants, optional title, and dismiss button.",designIntent:'Alert uses role="alert" so screen readers announce the message immediately when it appears. Each variant has a built-in icon that communicates intent visually; the icon can be overridden for custom scenarios. Title and body are both optional — you can show either, both, or just an icon with a body. The dismiss button is only rendered when onDismiss is provided, keeping the layout clean for non-dismissible alerts. All colors use status semantic tokens so they adapt correctly between light and dark themes.',props:[{name:"variant",type:"enum",required:!1,default:"info",description:"Visual and semantic variant of the alert.",enumValues:["info","success","warning","danger"]},{name:"title",type:"string",required:!1,description:"Bold title line rendered above the body."},{name:"children",type:"ReactNode",required:!1,description:"Alert body content — typically a short sentence or ReactNode."},{name:"onDismiss",type:"function",required:!1,description:"When provided, renders a dismiss (×) button and calls this handler on click."},{name:"icon",type:"ReactNode",required:!1,description:"Custom icon to replace the built-in variant icon."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the alert wrapper."}],usageExamples:[{title:"Info with body",code:'<Alert variant="info">Your changes have been saved as a draft.</Alert>'},{title:"With title and dismiss",code:`<Alert variant="danger" title="Payment failed" onDismiss={() => setVisible(false)}>
251
+ </Card>`}],compositionGraph:[],accessibility:{notes:"Card has no implicit ARIA role. If the card represents a landmark, wrap it in a <section> or <article> and provide an aria-label. For interactive cards (clickable), make the wrapper a <button> or <a> and ensure focus styles are visible."}},Ca={info:{bg:"var(--lucent-info-subtle)",border:"var(--lucent-info-default)",iconColor:"var(--lucent-info-text)",textColor:"info"},success:{bg:"var(--lucent-success-subtle)",border:"var(--lucent-success-default)",iconColor:"var(--lucent-success-text)",textColor:"success"},warning:{bg:"var(--lucent-warning-subtle)",border:"var(--lucent-warning-default)",iconColor:"var(--lucent-warning-text)",textColor:"warning"},danger:{bg:"var(--lucent-danger-subtle)",border:"var(--lucent-danger-default)",iconColor:"var(--lucent-danger-text)",textColor:"danger"}},Da=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M8 5.5V8.5M8 10.5V11",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),Ia=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M5 8L7 10L11 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),Ma=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("path",{d:"M8 2L14.5 13H1.5L8 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinejoin:"round"}),t.jsx("path",{d:"M8 6V9M8 11V11.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),za=()=>t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[t.jsx("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M5.5 5.5L10.5 10.5M10.5 5.5L5.5 10.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),Aa={info:t.jsx(Da,{}),success:t.jsx(Ia,{}),warning:t.jsx(Ma,{}),danger:t.jsx(za,{})},Ea=()=>t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:t.jsx("path",{d:"M3 3L11 11M11 3L3 11",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})});function Ra({variant:e="info",title:n,children:a,onDismiss:o,icon:r,style:i}){const s=Ca[e],l=r??Aa[e];return t.jsxs("div",{role:"alert",style:{display:"flex",alignItems:"flex-start",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-3) var(--lucent-space-4)",background:s.bg,border:`1px solid ${s.border}`,borderRadius:"var(--lucent-radius-md)",boxSizing:"border-box",...i},children:[t.jsx("span",{style:{flexShrink:0,color:s.iconColor,display:"flex",alignItems:"center",paddingTop:2},children:l}),t.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column",gap:"var(--lucent-space-1)"},children:[n&&t.jsx(P,{as:"span",size:"sm",weight:"semibold",color:s.textColor,lineHeight:"tight",children:n}),a&&t.jsx(P,{as:"span",size:"sm",color:s.textColor,lineHeight:"base",children:a})]}),o&&t.jsx("button",{type:"button","aria-label":"Dismiss",onClick:o,style:{flexShrink:0,display:"flex",alignItems:"center",background:"none",border:"none",cursor:"pointer",padding:2,borderRadius:"var(--lucent-radius-sm)",color:s.iconColor,opacity:.7},onMouseEnter:c=>{c.currentTarget.style.opacity="1"},onMouseLeave:c=>{c.currentTarget.style.opacity="0.7"},children:t.jsx(Ea,{})})]})}const La={id:"alert",name:"Alert",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"An inline feedback banner with info, success, warning, and danger variants, optional title, and dismiss button.",designIntent:'Alert uses role="alert" so screen readers announce the message immediately when it appears. Each variant has a built-in icon that communicates intent visually; the icon can be overridden for custom scenarios. Title and body are both optional — you can show either, both, or just an icon with a body. The dismiss button is only rendered when onDismiss is provided, keeping the layout clean for non-dismissible alerts. All colors use status semantic tokens so they adapt correctly between light and dark themes.',props:[{name:"variant",type:"enum",required:!1,default:"info",description:"Visual and semantic variant of the alert.",enumValues:["info","success","warning","danger"]},{name:"title",type:"string",required:!1,description:"Bold title line rendered above the body."},{name:"children",type:"ReactNode",required:!1,description:"Alert body content — typically a short sentence or ReactNode."},{name:"onDismiss",type:"function",required:!1,description:"When provided, renders a dismiss (×) button and calls this handler on click."},{name:"icon",type:"ReactNode",required:!1,description:"Custom icon to replace the built-in variant icon."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the alert wrapper."}],usageExamples:[{title:"Info with body",code:'<Alert variant="info">Your changes have been saved as a draft.</Alert>'},{title:"With title and dismiss",code:`<Alert variant="danger" title="Payment failed" onDismiss={() => setVisible(false)}>
252
252
  Check your card details and try again.
253
253
  </Alert>`},{title:"Success confirmation",code:`<Alert variant="success" title="Order placed!">
254
254
  You'll receive a confirmation email shortly.
255
- </Alert>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Title and body content",required:!1}],accessibility:{role:"alert",ariaAttributes:["aria-label"],notes:'role="alert" causes screen readers to announce the content immediately when rendered. For non-urgent status messages, consider using role="status" instead by overriding via style/wrapper.'}};function Ba({illustration:e,title:n,description:a,action:o,style:r}){return t.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:"var(--lucent-space-4)",padding:"var(--lucent-space-8)",textAlign:"center",...r},children:[e!=null&&t.jsx("div",{style:{width:64,height:64,display:"flex",alignItems:"center",justifyContent:"center",color:"var(--lucent-text-secondary)"},children:e}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)"},children:[t.jsx(B,{as:"h3",size:"lg",weight:"semibold",align:"center",lineHeight:"tight",children:n}),a&&t.jsx(B,{size:"sm",color:"secondary",align:"center",lineHeight:"relaxed",children:a})]}),o!=null&&t.jsx("div",{children:o})]})}const qa={id:"empty-state",name:"EmptyState",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"A centered placeholder shown when a list or page has no content, with an optional illustration, title, description, and CTA.",designIntent:"EmptyState communicates the absence of data in a constructive way. The illustration slot accepts any ReactNode — an Icon atom, a custom SVG, or an image — and constrains it to a 64px square to maintain visual consistency. Title is required to ensure the state is always named; description is optional for additional context. The action slot accepts any ReactNode (typically a Button) so the consumer controls variant and label without prescribing them. The entire layout is center-aligned and padded to sit naturally inside a Card or page section.",props:[{name:"title",type:"string",required:!0,description:'Short headline naming the empty state (e.g. "No results found").'},{name:"illustration",type:"ReactNode",required:!1,description:"Icon, SVG, or image rendered above the title. Constrained to a 64px container."},{name:"description",type:"string",required:!1,description:"Secondary text below the title providing context or next steps."},{name:"action",type:"ReactNode",required:!1,description:"Call-to-action rendered below the description — typically a Button."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"No search results",code:`<EmptyState
255
+ </Alert>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Title and body content",required:!1}],accessibility:{role:"alert",ariaAttributes:["aria-label"],notes:'role="alert" causes screen readers to announce the content immediately when rendered. For non-urgent status messages, consider using role="status" instead by overriding via style/wrapper.'}};function Ba({illustration:e,title:n,description:a,action:o,style:r}){return t.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:"var(--lucent-space-4)",padding:"var(--lucent-space-8)",textAlign:"center",...r},children:[e!=null&&t.jsx("div",{style:{width:64,height:64,display:"flex",alignItems:"center",justifyContent:"center",color:"var(--lucent-text-secondary)"},children:e}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)"},children:[t.jsx(P,{as:"h3",size:"lg",weight:"semibold",align:"center",lineHeight:"tight",children:n}),a&&t.jsx(P,{size:"sm",color:"secondary",align:"center",lineHeight:"relaxed",children:a})]}),o!=null&&t.jsx("div",{children:o})]})}const qa={id:"empty-state",name:"EmptyState",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"A centered placeholder shown when a list or page has no content, with an optional illustration, title, description, and CTA.",designIntent:"EmptyState communicates the absence of data in a constructive way. The illustration slot accepts any ReactNode — an Icon atom, a custom SVG, or an image — and constrains it to a 64px square to maintain visual consistency. Title is required to ensure the state is always named; description is optional for additional context. The action slot accepts any ReactNode (typically a Button) so the consumer controls variant and label without prescribing them. The entire layout is center-aligned and padded to sit naturally inside a Card or page section.",props:[{name:"title",type:"string",required:!0,description:'Short headline naming the empty state (e.g. "No results found").'},{name:"illustration",type:"ReactNode",required:!1,description:"Icon, SVG, or image rendered above the title. Constrained to a 64px container."},{name:"description",type:"string",required:!1,description:"Secondary text below the title providing context or next steps."},{name:"action",type:"ReactNode",required:!1,description:"Call-to-action rendered below the description — typically a Button."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"No search results",code:`<EmptyState
256
256
  illustration={<Icon size="xl"><SearchIcon /></Icon>}
257
257
  title="No results found"
258
258
  description="Try adjusting your search or filter to find what you're looking for."
@@ -263,23 +263,23 @@ Token rule: Card uses surface for its background. Never use bgBase or bgSubtle o
263
263
  action={<Button variant="primary">New project</Button>}
264
264
  />`},{title:"Inside a Card",code:`<Card>
265
265
  <EmptyState title="Nothing here" description="Add items to see them listed." />
266
- </Card>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Title and description",required:!0}],accessibility:{notes:"The title renders as an h3 by default. If EmptyState appears inside a section with its own heading hierarchy, override by passing a Text component as part of a custom layout. Ensure the action element has a descriptive label for screen readers."}},Pa={text:"1em",circle:40,rectangle:40},Fa={text:"var(--lucent-radius-sm)",circle:"var(--lucent-radius-full)",rectangle:"var(--lucent-radius-md)"};function nt({width:e,height:n,radius:a,animate:o,style:r}){return t.jsx("span",{style:{display:"block",width:typeof e=="number"?`${e}px`:e,height:typeof n=="number"?`${n}px`:n,borderRadius:a,background:o?"linear-gradient(90deg, var(--lucent-surface-secondary) 25%, var(--lucent-surface) 50%, var(--lucent-surface-secondary) 75%)":"var(--lucent-surface-secondary)",backgroundSize:o?"200% 100%":void 0,animation:o?"lucent-skeleton-shimmer 1.6s ease-in-out infinite":void 0,flexShrink:0,...r}})}function Na({variant:e="rectangle",width:n="100%",height:a,lines:o=1,animate:r=!0,radius:i,style:s}){const l=a??Pa[e],c=i??Fa[e],u=r?t.jsx("style",{children:`
266
+ </Card>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Title and description",required:!0}],accessibility:{notes:"The title renders as an h3 by default. If EmptyState appears inside a section with its own heading hierarchy, override by passing a Text component as part of a custom layout. Ensure the action element has a descriptive label for screen readers."}},Pa={text:"1em",circle:40,rectangle:40},Fa={text:"var(--lucent-radius-sm)",circle:"var(--lucent-radius-full)",rectangle:"var(--lucent-radius-md)"};function nt({width:e,height:n,radius:a,animate:o,style:r}){return t.jsx("span",{style:{display:"block",width:typeof e=="number"?`${e}px`:e,height:typeof n=="number"?`${n}px`:n,borderRadius:a,background:o?"linear-gradient(90deg, var(--lucent-surface-secondary) 25%, var(--lucent-surface) 50%, var(--lucent-surface-secondary) 75%)":"var(--lucent-surface-secondary)",backgroundSize:o?"200% 100%":void 0,animation:o?"lucent-skeleton-shimmer 1.6s ease-in-out infinite":void 0,flexShrink:0,...r}})}function Na({variant:e="rectangle",width:n="100%",height:a,lines:o=1,animate:r=!0,radius:i,style:s}){const l=a??Pa[e],c=i??Fa[e],d=r?t.jsx("style",{children:`
267
267
  @keyframes lucent-skeleton-shimmer {
268
268
  0% { background-position: 200% 0; }
269
269
  100% { background-position: -200% 0; }
270
270
  }
271
- `}):null;return e==="text"&&o>1?t.jsxs(t.Fragment,{children:[u,t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)",...s},children:Array.from({length:o}).map((f,d)=>t.jsx(nt,{width:d===o-1?"70%":n,height:l,radius:c,animate:r},d))})]}):t.jsxs(t.Fragment,{children:[u,t.jsx(nt,{width:e==="circle"?a??40:n,height:l,radius:c,animate:r,...s!==void 0&&{style:s}})]})}const $a={id:"skeleton",name:"Skeleton",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"Animated placeholder that matches the shape of content while it loads.",designIntent:"Skeleton uses a shimmer animation to communicate that content is loading without showing a spinner. The three variants (text, circle, rectangle) cover the most common content shapes: inline text, avatars/thumbnails, and generic content blocks. The text variant with lines > 1 mimics a paragraph by stacking multiple text skeletons and shortening the last line to 70%, which is a widely recognised convention for body copy placeholders. The shimmer gradient uses bg-muted and bg-subtle so it adapts correctly in both light and dark themes without hard-coded colors.",props:[{name:"variant",type:"enum",required:!1,default:"rectangle",description:"Shape of the skeleton — text (1em tall), circle (equal width/height), or rectangle.",enumValues:["text","circle","rectangle"]},{name:"width",type:"string",required:!1,default:'"100%"',description:"Width of the skeleton. Accepts any CSS value or a number (interpreted as px)."},{name:"height",type:"string",required:!1,description:"Height of the skeleton. Defaults: text=1em, circle=40px, rectangle=40px."},{name:"lines",type:"number",required:!1,default:"1",description:"Number of stacked text lines to render. Only applies to the text variant."},{name:"animate",type:"boolean",required:!1,default:"true",description:"Enables the shimmer animation. Set to false to render a static placeholder."},{name:"radius",type:"string",required:!1,description:"Override the default border-radius for the variant."},{name:"style",type:"object",required:!1,description:"Inline style overrides."}],usageExamples:[{title:"Paragraph placeholder",code:'<Skeleton variant="text" lines={3} />'},{title:"Avatar placeholder",code:'<Skeleton variant="circle" width={40} height={40} />'},{title:"Card placeholder",code:`<Card>
271
+ `}):null;return e==="text"&&o>1?t.jsxs(t.Fragment,{children:[d,t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)",...s},children:Array.from({length:o}).map((p,m)=>t.jsx(nt,{width:m===o-1?"70%":n,height:l,radius:c,animate:r},m))})]}):t.jsxs(t.Fragment,{children:[d,t.jsx(nt,{width:e==="circle"?a??40:n,height:l,radius:c,animate:r,...s!==void 0&&{style:s}})]})}const $a={id:"skeleton",name:"Skeleton",tier:"molecule",domain:"neutral",specVersion:"0.1",description:"Animated placeholder that matches the shape of content while it loads.",designIntent:"Skeleton uses a shimmer animation to communicate that content is loading without showing a spinner. The three variants (text, circle, rectangle) cover the most common content shapes: inline text, avatars/thumbnails, and generic content blocks. The text variant with lines > 1 mimics a paragraph by stacking multiple text skeletons and shortening the last line to 70%, which is a widely recognised convention for body copy placeholders. The shimmer gradient uses bg-muted and bg-subtle so it adapts correctly in both light and dark themes without hard-coded colors.",props:[{name:"variant",type:"enum",required:!1,default:"rectangle",description:"Shape of the skeleton — text (1em tall), circle (equal width/height), or rectangle.",enumValues:["text","circle","rectangle"]},{name:"width",type:"string",required:!1,default:'"100%"',description:"Width of the skeleton. Accepts any CSS value or a number (interpreted as px)."},{name:"height",type:"string",required:!1,description:"Height of the skeleton. Defaults: text=1em, circle=40px, rectangle=40px."},{name:"lines",type:"number",required:!1,default:"1",description:"Number of stacked text lines to render. Only applies to the text variant."},{name:"animate",type:"boolean",required:!1,default:"true",description:"Enables the shimmer animation. Set to false to render a static placeholder."},{name:"radius",type:"string",required:!1,description:"Override the default border-radius for the variant."},{name:"style",type:"object",required:!1,description:"Inline style overrides."}],usageExamples:[{title:"Paragraph placeholder",code:'<Skeleton variant="text" lines={3} />'},{title:"Avatar placeholder",code:'<Skeleton variant="circle" width={40} height={40} />'},{title:"Card placeholder",code:`<Card>
272
272
  <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
273
273
  <Skeleton variant="rectangle" height={160} />
274
274
  <Skeleton variant="text" lines={2} />
275
275
  <Skeleton variant="text" width="40%" />
276
276
  </div>
277
- </Card>`},{title:"Static (no animation)",code:'<Skeleton variant="rectangle" width={200} height={32} animate={false} />'}],compositionGraph:[],accessibility:{ariaAttributes:["aria-busy","aria-label"],notes:'Wrap loading regions with aria-busy="true" on the container so screen readers know content is loading. Individual Skeleton elements are presentational and do not need ARIA attributes themselves.'}};function Wa({items:e,separator:n="/",style:a}){return t.jsx("nav",{"aria-label":"Breadcrumb",style:a,children:t.jsx("ol",{style:{display:"flex",alignItems:"center",flexWrap:"wrap",gap:"var(--lucent-space-1)",listStyle:"none",margin:0,padding:0,fontFamily:"var(--lucent-font-family-base)"},children:e.map((o,r)=>{const i=r===e.length-1;return t.jsxs("li",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[i?t.jsx(B,{size:"sm",color:"primary",as:"span","aria-current":"page",children:o.label}):o.href!=null?t.jsx("a",{href:o.href,onClick:o.onClick,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",textDecoration:"none",fontFamily:"var(--lucent-font-family-base)",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)"},onMouseEnter:s=>{s.currentTarget.style.color="var(--lucent-text-primary)"},onMouseLeave:s=>{s.currentTarget.style.color="var(--lucent-text-secondary)"},children:o.label}):t.jsx("button",{onClick:o.onClick,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",background:"none",border:"none",padding:0,cursor:"pointer",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)"},onMouseEnter:s=>{s.currentTarget.style.color="var(--lucent-text-primary)"},onMouseLeave:s=>{s.currentTarget.style.color="var(--lucent-text-secondary)"},children:o.label}),!i&&t.jsx("span",{"aria-hidden":!0,style:{color:"var(--lucent-text-disabled)",fontSize:"var(--lucent-font-size-sm)",userSelect:"none"},children:n})]},r)})})})}function Oa({tabs:e,defaultValue:n,value:a,onChange:o,variant:r="underline",style:i}){var ae;const s=a!==void 0,[l,c]=p.useState(n??((ae=e[0])==null?void 0:ae.value)??""),u=s?a:l,[f,d]=p.useState(null),y=p.useRef([]),[h,w]=p.useState(null),v=p.useRef(!1),g=r==="pills",b=p.useRef(null),k=p.useRef(null),D=p.useRef(null),[S,x]=p.useState(e.length),[z,q]=p.useState(!1),[T,C]=p.useState(!1),[V,R]=p.useState(null),I=e.slice(0,S),j=e.slice(S),M=j.length>0,P=j.some(m=>m.value===u),G=()=>{if(P){w(null);return}const m=e.findIndex((E,L)=>L<S&&E.value===u),A=y.current[m];if(A){if(g){const E=A.querySelector("span");if(!E)return;w({left:E.offsetLeft+A.offsetLeft,width:E.offsetWidth,animate:v.current})}else w({left:A.offsetLeft,width:A.offsetWidth,animate:v.current});v.current=!0}};p.useLayoutEffect(()=>{G(),document.fonts.ready.then(G)},[u,S,g]),p.useEffect(()=>{const m=b.current;if(!m)return;const A=()=>{const $=m.clientWidth,re=70;let oe=0,J=0;for(let Z=0;Z<e.length;Z++){const Q=y.current[Z];if(!Q){J++;continue}const ee=Q.offsetWidth;if(Z<e.length-1){if(oe+ee+re>$)break}else if(oe+ee>$)break;oe+=ee,J++}if(J>=e.length-1&&J<e.length){let Z=0;for(let Q=0;Q<e.length;Q++){const ee=y.current[Q];ee&&(Z+=ee.offsetWidth)}Z<=$&&(J=e.length)}x(J<1?1:J)};let E;(()=>{E=requestAnimationFrame(()=>{E=requestAnimationFrame(A)})})();const N=new ResizeObserver(A);return N.observe(m),()=>{N.disconnect(),cancelAnimationFrame(E)}},[e]),p.useEffect(()=>{if(!z)return;const m=A=>{D.current&&!D.current.contains(A.target)&&k.current&&!k.current.contains(A.target)&&(q(!1),R(null))};return document.addEventListener("mousedown",m),()=>document.removeEventListener("mousedown",m)},[z]);const H=m=>{s||c(m),o==null||o(m)},_=(m,A)=>{var $;const E=I.map((re,oe)=>re.disabled?-1:oe).filter(re=>re!==-1),L=E.indexOf(A);let N=-1;m.key==="ArrowRight"&&(N=E[(L+1)%E.length]??-1),m.key==="ArrowLeft"&&(N=E[(L-1+E.length)%E.length]??-1),m.key==="Home"&&(N=E[0]??-1),m.key==="End"&&(N=E[E.length-1]??-1),N!==-1&&(m.preventDefault(),($=y.current[N])==null||$.focus(),H(I[N].value))};return t.jsxs("div",{style:{display:"flex",flexDirection:"column",position:"relative",...i},children:[t.jsxs("div",{ref:b,role:"tablist",style:{position:"relative",display:"flex",overflow:"hidden",...g?{padding:"var(--lucent-space-1)"}:{borderBottom:"1px solid var(--lucent-border-default)"}},children:[e.map((m,A)=>{const E=A<S,L=m.value===u,N=m.disabled??!1;return t.jsxs("button",{ref:$=>{y.current[A]=$},role:"tab","aria-selected":L,"aria-controls":`lucent-tabpanel-${m.value}`,id:`lucent-tab-${m.value}`,disabled:N,tabIndex:L&&E?0:-1,onClick:()=>{N||H(m.value)},onKeyDown:$=>_($,A),onMouseEnter:()=>{!N&&E&&d(A)},onMouseLeave:()=>d(null),style:{padding:g?"var(--lucent-space-1) var(--lucent-space-2)":"var(--lucent-space-1) var(--lucent-space-2) var(--lucent-space-3)",background:"none",border:"none",cursor:N?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:L?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:N?"var(--lucent-text-disabled)":g&&L?"var(--lucent-text-on-accent)":L?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)",whiteSpace:"nowrap",outline:"none",position:E?"relative":"absolute",zIndex:L?1:0,...E?{}:{visibility:"hidden",pointerEvents:"none",left:-9999}},children:[t.jsx("span",{style:{display:"block",padding:"var(--lucent-space-1) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",background:!g&&f===A&&!L&&!N?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:m.label}),g&&f===A&&!L&&!N&&E&&t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",top:0,bottom:0,left:0,right:0,borderRadius:"var(--lucent-radius-md)",background:"var(--lucent-surface-secondary)",zIndex:-1,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"}})]},m.value)}),M&&t.jsx("button",{ref:k,onClick:()=>q(m=>!m),onMouseEnter:()=>C(!0),onMouseLeave:()=>C(!1),style:{padding:g?"var(--lucent-space-1) var(--lucent-space-2)":"var(--lucent-space-1) var(--lucent-space-2) var(--lucent-space-3)",background:"none",border:"none",cursor:"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:P?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:P?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",whiteSpace:"nowrap",outline:"none",position:"relative",flexShrink:0},children:t.jsx("span",{style:{display:"block",padding:"var(--lucent-space-1) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",background:T?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:"More…"})}),h!=null&&t.jsx("span",{"aria-hidden":!0,style:g?{position:"absolute",top:"var(--lucent-space-1)",bottom:"var(--lucent-space-1)",left:h.left,width:h.width,background:"var(--lucent-accent-default)",borderRadius:"var(--lucent-radius-md)",transition:h.animate?"left 220ms var(--lucent-easing-default), width 220ms var(--lucent-easing-default)":"none"}:{position:"absolute",bottom:0,left:h.left,width:h.width,height:2,background:"var(--lucent-accent-default)",borderRadius:"var(--lucent-radius-sm)",transition:h.animate?"left 220ms var(--lucent-easing-default), width 220ms var(--lucent-easing-default)":"none"}})]}),M&&z&&t.jsx("div",{ref:D,style:{position:"absolute",top:"100%",right:0,zIndex:50,marginTop:"var(--lucent-space-1)",background:"var(--lucent-surface-primary)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-md)",boxShadow:"var(--lucent-shadow-md)",padding:"var(--lucent-space-1) 0",minWidth:140},children:j.map((m,A)=>{const E=m.value===u,L=m.disabled??!1,N=V===A;return t.jsx("button",{disabled:L,onClick:()=>{L||(H(m.value),q(!1))},onMouseEnter:()=>{L||R(A)},onMouseLeave:()=>R(null),style:{display:"block",width:"100%",padding:"var(--lucent-space-2) var(--lucent-space-4)",background:E||N?"var(--lucent-surface-secondary)":"none",border:"none",cursor:L?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:E?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:L?"var(--lucent-text-disabled)":E||N?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",textAlign:"left",outline:"none",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), color var(--lucent-duration-fast) var(--lucent-easing-default)"},children:m.label},m.value)})}),e.map(m=>t.jsx("div",{role:"tabpanel",id:`lucent-tabpanel-${m.value}`,"aria-labelledby":`lucent-tab-${m.value}`,hidden:m.value!==u,style:{padding:"var(--lucent-space-4) 0",outline:"none"},tabIndex:0,children:m.content},m.value))]})}const Va=`
277
+ </Card>`},{title:"Static (no animation)",code:'<Skeleton variant="rectangle" width={200} height={32} animate={false} />'}],compositionGraph:[],accessibility:{ariaAttributes:["aria-busy","aria-label"],notes:'Wrap loading regions with aria-busy="true" on the container so screen readers know content is loading. Individual Skeleton elements are presentational and do not need ARIA attributes themselves.'}};function Wa({items:e,separator:n="/",style:a}){return t.jsx("nav",{"aria-label":"Breadcrumb",style:a,children:t.jsx("ol",{style:{display:"flex",alignItems:"center",flexWrap:"wrap",gap:"var(--lucent-space-1)",listStyle:"none",margin:0,padding:0,fontFamily:"var(--lucent-font-family-base)"},children:e.map((o,r)=>{const i=r===e.length-1;return t.jsxs("li",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[i?t.jsx(P,{size:"sm",color:"primary",as:"span","aria-current":"page",children:o.label}):o.href!=null?t.jsx("a",{href:o.href,onClick:o.onClick,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",textDecoration:"none",fontFamily:"var(--lucent-font-family-base)",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)"},onMouseEnter:s=>{s.currentTarget.style.color="var(--lucent-text-primary)"},onMouseLeave:s=>{s.currentTarget.style.color="var(--lucent-text-secondary)"},children:o.label}):t.jsx("button",{onClick:o.onClick,style:{fontSize:"var(--lucent-font-size-sm)",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",background:"none",border:"none",padding:0,cursor:"pointer",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)"},onMouseEnter:s=>{s.currentTarget.style.color="var(--lucent-text-primary)"},onMouseLeave:s=>{s.currentTarget.style.color="var(--lucent-text-secondary)"},children:o.label}),!i&&t.jsx("span",{"aria-hidden":!0,style:{color:"var(--lucent-text-disabled)",fontSize:"var(--lucent-font-size-sm)",userSelect:"none"},children:n})]},r)})})})}function Oa({tabs:e,defaultValue:n,value:a,onChange:o,variant:r="underline",style:i}){var U;const s=a!==void 0,[l,c]=f.useState(n??((U=e[0])==null?void 0:U.value)??""),d=s?a:l,[p,m]=f.useState(null),h=f.useRef([]),[u,S]=f.useState(null),y=f.useRef(!1),b=r==="pills",v=f.useRef(null),w=f.useRef(null),j=f.useRef(null),[T,x]=f.useState(e.length),[M,F]=f.useState(!1),[k,z]=f.useState(!1),[q,E]=f.useState(null),C=e.slice(0,T),R=e.slice(T),I=R.length>0,L=R.some(g=>g.value===d),W=()=>{if(L){S(null);return}const g=e.findIndex((A,B)=>B<T&&A.value===d),D=h.current[g];if(D){if(b){const A=D.querySelector("span");if(!A)return;S({left:A.offsetLeft+D.offsetLeft,width:A.offsetWidth,animate:y.current})}else S({left:D.offsetLeft,width:D.offsetWidth,animate:y.current});y.current=!0}};f.useLayoutEffect(()=>{W(),document.fonts.ready.then(W)},[d,T,b]),f.useEffect(()=>{const g=v.current;if(!g)return;const D=()=>{const V=g.clientWidth,re=70;let oe=0,Z=0;for(let Q=0;Q<e.length;Q++){const ee=h.current[Q];if(!ee){Z++;continue}const te=ee.offsetWidth;if(Q<e.length-1){if(oe+te+re>V)break}else if(oe+te>V)break;oe+=te,Z++}if(Z>=e.length-1&&Z<e.length){let Q=0;for(let ee=0;ee<e.length;ee++){const te=h.current[ee];te&&(Q+=te.offsetWidth)}Q<=V&&(Z=e.length)}x(Z<1?1:Z)};let A;(()=>{A=requestAnimationFrame(()=>{A=requestAnimationFrame(D)})})();const O=new ResizeObserver(D);return O.observe(g),()=>{O.disconnect(),cancelAnimationFrame(A)}},[e]),f.useEffect(()=>{if(!M)return;const g=D=>{j.current&&!j.current.contains(D.target)&&w.current&&!w.current.contains(D.target)&&(F(!1),E(null))};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[M]);const N=g=>{s||c(g),o==null||o(g)},G=(g,D)=>{var V;const A=C.map((re,oe)=>re.disabled?-1:oe).filter(re=>re!==-1),B=A.indexOf(D);let O=-1;g.key==="ArrowRight"&&(O=A[(B+1)%A.length]??-1),g.key==="ArrowLeft"&&(O=A[(B-1+A.length)%A.length]??-1),g.key==="Home"&&(O=A[0]??-1),g.key==="End"&&(O=A[A.length-1]??-1),O!==-1&&(g.preventDefault(),(V=h.current[O])==null||V.focus(),N(C[O].value))};return t.jsxs("div",{style:{display:"flex",flexDirection:"column",position:"relative",...i},children:[t.jsxs("div",{ref:v,role:"tablist",style:{position:"relative",display:"flex",overflow:"hidden",...b?{padding:"var(--lucent-space-1)"}:{borderBottom:"1px solid var(--lucent-border-default)"}},children:[e.map((g,D)=>{const A=D<T,B=g.value===d,O=g.disabled??!1;return t.jsxs("button",{ref:V=>{h.current[D]=V},role:"tab","aria-selected":B,"aria-controls":`lucent-tabpanel-${g.value}`,id:`lucent-tab-${g.value}`,disabled:O,tabIndex:B&&A?0:-1,onClick:()=>{O||N(g.value)},onKeyDown:V=>G(V,D),onMouseEnter:()=>{!O&&A&&m(D)},onMouseLeave:()=>m(null),style:{padding:b?"var(--lucent-space-1) var(--lucent-space-2)":"var(--lucent-space-1) var(--lucent-space-2) var(--lucent-space-3)",background:"none",border:"none",cursor:O?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:B?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:O?"var(--lucent-text-disabled)":b&&B?"var(--lucent-text-on-accent)":B?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",transition:"color var(--lucent-duration-fast) var(--lucent-easing-default)",whiteSpace:"nowrap",outline:"none",position:A?"relative":"absolute",zIndex:B?1:0,...A?{}:{visibility:"hidden",pointerEvents:"none",left:-9999}},children:[t.jsx("span",{style:{display:"block",padding:"var(--lucent-space-1) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",background:!b&&p===D&&!B&&!O?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:g.label}),b&&p===D&&!B&&!O&&A&&t.jsx("span",{"aria-hidden":!0,style:{position:"absolute",top:0,bottom:0,left:0,right:0,borderRadius:"var(--lucent-radius-md)",background:"var(--lucent-surface-secondary)",zIndex:-1,transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"}})]},g.value)}),I&&t.jsx("button",{ref:w,onClick:()=>F(g=>!g),onMouseEnter:()=>z(!0),onMouseLeave:()=>z(!1),style:{padding:b?"var(--lucent-space-1) var(--lucent-space-2)":"var(--lucent-space-1) var(--lucent-space-2) var(--lucent-space-3)",background:"none",border:"none",cursor:"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:L?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:L?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",whiteSpace:"nowrap",outline:"none",position:"relative",flexShrink:0},children:t.jsx("span",{style:{display:"block",padding:"var(--lucent-space-1) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",background:k?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:"More…"})}),u!=null&&t.jsx("span",{"aria-hidden":!0,style:b?{position:"absolute",top:"var(--lucent-space-1)",bottom:"var(--lucent-space-1)",left:u.left,width:u.width,background:"var(--lucent-accent-default)",borderRadius:"var(--lucent-radius-md)",transition:u.animate?"left 220ms var(--lucent-easing-default), width 220ms var(--lucent-easing-default)":"none"}:{position:"absolute",bottom:0,left:u.left,width:u.width,height:2,background:"var(--lucent-accent-default)",borderRadius:"var(--lucent-radius-sm)",transition:u.animate?"left 220ms var(--lucent-easing-default), width 220ms var(--lucent-easing-default)":"none"}})]}),I&&M&&t.jsx("div",{ref:j,style:{position:"absolute",top:"100%",right:0,zIndex:50,marginTop:"var(--lucent-space-1)",background:"var(--lucent-surface-primary)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-md)",boxShadow:"var(--lucent-shadow-md)",padding:"var(--lucent-space-1) 0",minWidth:140},children:R.map((g,D)=>{const A=g.value===d,B=g.disabled??!1,O=q===D;return t.jsx("button",{disabled:B,onClick:()=>{B||(N(g.value),F(!1))},onMouseEnter:()=>{B||E(D)},onMouseLeave:()=>E(null),style:{display:"block",width:"100%",padding:"var(--lucent-space-2) var(--lucent-space-4)",background:A||O?"var(--lucent-surface-secondary)":"none",border:"none",cursor:B?"not-allowed":"pointer",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",fontWeight:A?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",color:B?"var(--lucent-text-disabled)":A||O?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",textAlign:"left",outline:"none",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default), color var(--lucent-duration-fast) var(--lucent-easing-default)"},children:g.label},g.value)})}),e.map(g=>t.jsx("div",{role:"tabpanel",id:`lucent-tabpanel-${g.value}`,"aria-labelledby":`lucent-tab-${g.value}`,hidden:g.value!==d,style:{padding:"var(--lucent-space-4) 0",outline:"none"},tabIndex:0,children:g.content},g.value))]})}const Va=`
278
278
  @keyframes lucent-collapsible-open {
279
279
  from { opacity: 0; transform: translateY(-4px); }
280
280
  to { opacity: 1; transform: translateY(0); }
281
281
  }
282
- `;function Ha({trigger:e,children:n,defaultOpen:a=!1,open:o,onOpenChange:r,style:i}){const s=o!==void 0,[l,c]=p.useState(a),u=s?o:l,f=p.useRef(null),[d,y]=p.useState(u?void 0:0),h=p.useRef(!1);p.useEffect(()=>{const v=f.current;if(v)if(u){const g=v.scrollHeight;y(g),h.current=!0;const b=setTimeout(()=>{y(void 0),h.current=!1},220);return()=>clearTimeout(b)}else y(v.scrollHeight),v.getBoundingClientRect(),y(0)},[u]);const w=()=>{const v=!u;s||c(v),r==null||r(v)};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:Va}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",...i},children:[t.jsxs("button",{onClick:w,"aria-expanded":u,style:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",background:"none",border:"none",padding:"var(--lucent-space-3) var(--lucent-space-4)",cursor:"pointer",textAlign:"left",outline:"none",fontFamily:"inherit",fontSize:"inherit"},children:[t.jsx("span",{style:{flex:1},children:e}),t.jsx(Ga,{open:u})]}),t.jsx("div",{ref:f,"aria-hidden":!u,style:{overflow:"hidden",height:d!==void 0?d:"auto",transition:"height 200ms var(--lucent-easing-default)"},children:t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-4) var(--lucent-space-3)",animation:u?"lucent-collapsible-open 200ms var(--lucent-easing-default) forwards":void 0},children:n})})]})]})}function Ga({open:e}){return t.jsx("svg",{width:16,height:16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,style:{flexShrink:0,color:"var(--lucent-text-secondary)",transform:e?"rotate(180deg)":"rotate(0deg)",transition:"transform 200ms var(--lucent-easing-default)"},children:t.jsx("polyline",{points:"6 9 12 15 18 9"})})}function pe(e){return typeof e=="number"?`${e}px`:e}function Ua({children:e,header:n,sidebar:a,sidebarWidth:o=240,headerHeight:r=48,sidebarCollapsed:i=!1,rightSidebar:s,rightSidebarWidth:l=240,rightSidebarCollapsed:c=!1,footer:u,footerHeight:f=28,mainStyle:d,style:y}){const h=pe(r),w=pe(o),v=pe(l),g=pe(f);return t.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100vh",overflow:"hidden",fontFamily:"var(--lucent-font-family-base)",...y},children:[n!=null&&t.jsx("div",{style:{flexShrink:0,height:h,zIndex:10,background:"var(--lucent-surface)"},children:n}),t.jsxs("div",{style:{display:"flex",flex:1,overflow:"hidden"},children:[a!=null&&t.jsx("div",{style:{width:i?0:w,flexShrink:0,overflow:"hidden",overflowY:i?"hidden":"auto",background:"var(--lucent-surface)",transition:"width 200ms var(--lucent-easing-default)"},children:a}),t.jsx("main",{style:{flex:1,overflowY:"auto",minWidth:0,margin:s!=null?"0 0 var(--lucent-space-3) 0":"0 var(--lucent-space-3) var(--lucent-space-3) 0",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"var(--lucent-shadow-sm)",background:"var(--lucent-surface)",...d},children:e}),s!=null&&t.jsx("aside",{style:{width:c?0:v,flexShrink:0,overflow:"hidden",overflowY:c?"hidden":"auto",background:"var(--lucent-surface)",transition:"width 200ms var(--lucent-easing-default)"},children:s})]}),u!=null&&t.jsx("div",{style:{flexShrink:0,height:g,zIndex:10,background:"var(--lucent-surface)"},children:u})]})}function _a({state:e}){return t.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none","aria-hidden":!0,style:{flexShrink:0,opacity:e==="none"?.35:1},children:[t.jsx("path",{d:"M6 2L9 5H3L6 2Z",fill:"currentColor",opacity:e==="desc"?.35:1}),t.jsx("path",{d:"M6 10L3 7H9L6 10Z",fill:"currentColor",opacity:e==="asc"?.35:1})]})}function at({dir:e}){return t.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:e==="left"?"M10 12L6 8l4-4":"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function Ya({columns:e,rows:n,pageSize:a=10,page:o,onPageChange:r,onFilterChange:i,emptyState:s,style:l}){const[c,u]=p.useState(null),[f,d]=p.useState(0),[y,h]=p.useState(null),[w,v]=p.useState({}),g=o!==void 0,b=g?o:f,k=e.some(I=>I.filterable),D=k?n.filter(I=>e.every(j=>{if(!j.filterable)return!0;const M=w[j.key];if(!M||M.length===0)return!0;const P=String(I[j.key]??"");return M.includes(P)})):n,S=c?[...D].sort((I,j)=>{const M=I[c.key],P=j[c.key],G=String(M??"").localeCompare(String(P??""),void 0,{numeric:!0});return c.dir==="asc"?G:-G}):D,x=a>0?S.slice(b*a,(b+1)*a):S,z=a>0?Math.max(1,Math.ceil(S.length/a)):1,q=I=>{g||d(I),r==null||r(I)},T=I=>{u(j=>!j||j.key!==I?{key:I,dir:"asc"}:j.dir==="asc"?{key:I,dir:"desc"}:null),g||d(0),r==null||r(0)},C=(I,j)=>{const M={...w,[I]:j};j.length===0&&delete M[I],v(M),g||d(0),r==null||r(0),i==null||i(M)},V=()=>{v({}),g||d(0),r==null||r(0),i==null||i({})},R=[];if(z<=7)for(let I=0;I<z;I++)R.push(I);else{R.push(0),b>2&&R.push("…");for(let I=Math.max(1,b-1);I<=Math.min(z-2,b+1);I++)R.push(I);b<z-3&&R.push("…"),R.push(z-1)}return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-3)",...l},children:[k&&t.jsx("div",{style:{position:"relative",zIndex:1},children:t.jsx(Ka,{columns:e,rows:n,filters:w,onFilter:C,onClearAll:V})}),t.jsx("div",{style:{overflowX:"auto",borderRadius:"var(--lucent-radius-lg)",border:"1px solid var(--lucent-border-default)"},children:t.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)"},children:[t.jsx("thead",{children:t.jsx("tr",{style:{borderBottom:"1px solid var(--lucent-border-default)"},children:e.map(I=>{const j=(c==null?void 0:c.key)===I.key?c.dir:"none";return t.jsx("th",{onClick:I.sortable?()=>T(I.key):void 0,style:{padding:"var(--lucent-space-3) var(--lucent-space-4)",textAlign:I.align??"left",fontWeight:"var(--lucent-font-weight-medium)",color:"var(--lucent-text-secondary)",background:"var(--lucent-surface-secondary)",borderBottom:"1px solid var(--lucent-border-default)",cursor:I.sortable?"pointer":"default",userSelect:"none",whiteSpace:"nowrap",...I.width?{width:I.width}:{}},children:t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[I.header,I.sortable&&t.jsx(_a,{state:j})]})},I.key)})})}),t.jsx("tbody",{children:x.length===0?t.jsx("tr",{children:t.jsx("td",{colSpan:e.length,style:{padding:"var(--lucent-space-12)",textAlign:"center"},children:s??t.jsx(B,{color:"secondary",children:"No data"})})}):x.map((I,j)=>t.jsx("tr",{onMouseEnter:()=>h(j),onMouseLeave:()=>h(null),style:{borderBottom:j<x.length-1?"1px solid var(--lucent-border-subtle)":"none",background:y===j?"var(--lucent-surface-secondary)":"var(--lucent-surface)",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:e.map(M=>t.jsx("td",{style:{padding:"var(--lucent-space-3) var(--lucent-space-4)",color:"var(--lucent-text-primary)",textAlign:M.align??"left",verticalAlign:"middle"},children:M.render?M.render(I,j):String(I[M.key]??"")},M.key))},j))})]})}),a>0&&S.length>0&&t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"var(--lucent-space-3)",flexWrap:"wrap"},children:[t.jsx(B,{color:"secondary",size:"sm",children:S.length===0?`0 rows${n.length>0?` (filtered from ${n.length})`:""}`:S.length===1?`1 row${S.length<n.length?` (filtered from ${n.length})`:""}`:`${b*a+1}–${Math.min((b+1)*a,S.length)} of ${S.length} rows${S.length<n.length?` (filtered from ${n.length})`:""}`}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[t.jsx(xe,{onClick:()=>q(b-1),disabled:b===0,"aria-label":"Previous page",children:t.jsx(at,{dir:"left"})}),R.map((I,j)=>I==="…"?t.jsx("span",{style:{padding:"0 var(--lucent-space-1)",color:"var(--lucent-text-disabled)",fontSize:"var(--lucent-font-size-sm)"},children:"…"},`ellipsis-${j}`):t.jsx(xe,{onClick:()=>q(I),active:I===b,"aria-label":`Page ${I+1}`,"aria-current":I===b?"page":void 0,children:I+1},I)),t.jsx(xe,{onClick:()=>q(b+1),disabled:b>=z-1,"aria-label":"Next page",children:t.jsx(at,{dir:"right"})})]})]})]})}function Ka({columns:e,rows:n,filters:a,onFilter:o,onClearAll:r}){const i=e.filter(l=>l.filterable),s=Object.keys(a).length;return t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",flexWrap:"wrap"},children:[i.map(l=>{const c=Array.from(new Set(n.map(u=>String(u[l.key]??"")))).sort();return t.jsx(Xa,{label:l.header,values:c,value:a[l.key]??[],onChange:u=>o(l.key,u)},l.key)}),s>0&&t.jsx("button",{onClick:r,style:{display:"inline-flex",alignItems:"center",height:30,padding:"0 var(--lucent-space-2)",border:"none",borderRadius:"var(--lucent-radius-md)",background:"transparent",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",cursor:"pointer"},children:"Clear all"})]})}function Xa({label:e,values:n,value:a,onChange:o}){const[r,i]=p.useState(!1),[s,l]=p.useState(!1),[c,u]=p.useState(""),f=p.useRef(null),d=p.useRef(null),y=a.length>0;p.useEffect(()=>{if(!r){u("");return}setTimeout(()=>{var k;return(k=d.current)==null?void 0:k.focus()},0);const g=k=>{f.current&&!f.current.contains(k.target)&&i(!1)},b=k=>{k.key==="Escape"&&i(!1)};return document.addEventListener("mousedown",g),document.addEventListener("keydown",b),()=>{document.removeEventListener("mousedown",g),document.removeEventListener("keydown",b)}},[r]);const h=c?n.filter(g=>g.toLowerCase().includes(c.toLowerCase())):n,w=g=>o(a.includes(g)?a.filter(b=>b!==g):[...a,g]),v=a.length===0?null:a.length===1?t.jsxs("span",{style:{color:"var(--lucent-text-secondary)",fontWeight:"var(--lucent-font-weight-regular)"},children:[": ",a[0]]}):t.jsxs("span",{style:{color:"var(--lucent-accent-default)"},children:["(",a.length,")"]});return t.jsxs("div",{ref:f,style:{position:"relative"},children:[t.jsxs("button",{onClick:()=>i(g=>!g),onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",height:30,padding:"0 var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:`1px solid ${y?"var(--lucent-accent-default)":s?"var(--lucent-border-strong)":"var(--lucent-border-default)"}`,background:y?"var(--lucent-accent-subtle)":"var(--lucent-surface)",color:y?"var(--lucent-accent-default)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",fontWeight:y?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",cursor:"pointer",outline:"none",whiteSpace:"nowrap",transition:"border-color var(--lucent-duration-fast) var(--lucent-easing-default), background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:[e,v,t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,style:{transform:r?"rotate(180deg)":"none",transition:"transform var(--lucent-duration-fast) var(--lucent-easing-default)"},children:t.jsx("path",{d:"M2 3.5L5 6.5L8 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]}),r&&t.jsxs("div",{style:{position:"absolute",top:"calc(100% + 4px)",left:0,minWidth:180,maxHeight:280,display:"flex",flexDirection:"column",background:"var(--lucent-surface)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"0 4px 16px color-mix(in srgb, var(--lucent-text-primary) 8%, transparent)",zIndex:50},children:[t.jsx("div",{style:{padding:"var(--lucent-space-2)",paddingBottom:0},children:t.jsx("input",{ref:d,type:"text",value:c,onChange:g=>u(g.target.value),placeholder:"Search…",style:{width:"100%",boxSizing:"border-box",height:26,padding:"0 var(--lucent-space-2)",borderRadius:"var(--lucent-radius-md)",border:"1px solid var(--lucent-border-default)",background:"var(--lucent-surface-secondary)",color:"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",outline:"none"}})}),a.length>0&&t.jsx("div",{style:{padding:"var(--lucent-space-1) var(--lucent-space-2) 0"},children:t.jsx("button",{onClick:()=>o([]),style:{display:"inline-flex",padding:"2px var(--lucent-space-2)",border:"none",borderRadius:"var(--lucent-radius-sm)",background:"transparent",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",cursor:"pointer",textDecoration:"underline"},children:"Clear selection"})}),t.jsx("div",{style:{overflowY:"auto",padding:"var(--lucent-space-1)",borderTop:"1px solid var(--lucent-border-subtle)",marginTop:"var(--lucent-space-2)"},children:h.length===0?t.jsx("div",{style:{padding:"var(--lucent-space-3)",color:"var(--lucent-text-disabled)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",textAlign:"center"},children:"No results"}):h.map(g=>t.jsx(Ja,{label:g,isSelected:a.includes(g),onClick:()=>w(g)},g))})]})]})}function Ja({label:e,isSelected:n,onClick:a}){const[o,r]=p.useState(!1);return t.jsxs("button",{onClick:a,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",width:"100%",textAlign:"left",padding:"var(--lucent-space-2) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:"none",background:o?"var(--lucent-surface-secondary)":"transparent",color:"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",fontWeight:n?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",cursor:"pointer",outline:"none",whiteSpace:"nowrap"},children:[t.jsx("span",{style:{flexShrink:0,width:14,height:14,borderRadius:"var(--lucent-radius-sm)",border:`1.5px solid ${n?"var(--lucent-accent-default)":"var(--lucent-border-strong)"}`,background:n?"var(--lucent-accent-default)":"transparent",display:"flex",alignItems:"center",justifyContent:"center",transition:"border-color var(--lucent-duration-fast), background var(--lucent-duration-fast)"},children:n&&t.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M1 4L3 6L7 2",stroke:"var(--lucent-text-on-accent)",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),e]})}function xe({children:e,onClick:n,disabled:a,active:o,...r}){const[i,s]=p.useState(!1);return t.jsx("button",{...r,onClick:n,disabled:a,onMouseEnter:()=>s(!0),onMouseLeave:()=>s(!1),style:{display:"inline-flex",alignItems:"center",justifyContent:"center",minWidth:32,height:32,padding:"0 var(--lucent-space-2)",borderRadius:"var(--lucent-radius-md)",border:o?"1px solid var(--lucent-accent-default)":"1px solid transparent",background:o?"var(--lucent-accent-default)":i&&!a?"var(--lucent-surface-secondary)":"transparent",color:o?"var(--lucent-text-on-accent)":a?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontSize:"var(--lucent-font-size-sm)",fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-regular)",cursor:a?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:e})}const Za={id:"data-table",name:"DataTable",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A sortable, filterable, paginated data table with configurable columns, custom cell renderers, and keyboard-accessible pagination controls.",designIntent:'DataTable is generic over row type T so TypeScript consumers get full type safety on column keys and renderers. Sorting is client-side and composable — each column opts in via sortable:true; clicking a sorted column cycles asc → desc → unsorted. Filtering is per-column — each column opts in via filterable:true, which adds a dropdown button above the table. Each dropdown is searchable and multi-select: a search input filters the option list, and each option is a checkbox that toggles membership in the active set. Filtering uses set-membership: a row passes if its column value is included in the selected values array. A "Clear selection" link inside each dropdown clears that column; a "Clear all" button in the bar appears when any filter is active. Filter → sort → paginate is the fixed pipeline order; any filter change resets the page to 0. Pagination is either controlled (page prop + onPageChange) or uncontrolled (internal state). A pageSize of 0 disables pagination entirely, useful when the parent manages windowing. Row hover uses bg-subtle, not a border change, so the visual weight stays low for dense data views.',props:[{name:"columns",type:"array",required:!0,description:"Column definitions. Each column has a key, header, optional render function, optional sortable flag, optional filterable flag (renders a text filter input below the header), optional width, and optional text align."},{name:"rows",type:"array",required:!0,description:"Array of data objects to display. The generic type T is inferred from this prop."},{name:"pageSize",type:"number",required:!1,default:"10",description:"Number of rows per page. Set to 0 to disable pagination."},{name:"page",type:"number",required:!1,description:"Controlled current page (0-indexed). When provided, the component is fully controlled."},{name:"onPageChange",type:"function",required:!1,description:"Called with the new page index whenever the page changes (from pagination controls or after a sort/filter reset)."},{name:"onFilterChange",type:"function",required:!1,description:"Called with the current filter map (Record<string, string[]>) whenever any column filter changes. Keys are column keys; columns with no selection are omitted from the map."},{name:"emptyState",type:"ReactNode",required:!1,description:'Content to render when rows is empty. Defaults to a "No data" text.'},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Basic sortable table",code:`<DataTable
282
+ `;function Ha({trigger:e,children:n,defaultOpen:a=!1,open:o,onOpenChange:r,style:i}){const s=o!==void 0,[l,c]=f.useState(a),d=s?o:l,p=f.useRef(null),[m,h]=f.useState(d?void 0:0),u=f.useRef(!1);f.useEffect(()=>{const y=p.current;if(y)if(d){const b=y.scrollHeight;h(b),u.current=!0;const v=setTimeout(()=>{h(void 0),u.current=!1},220);return()=>clearTimeout(v)}else h(y.scrollHeight),y.getBoundingClientRect(),h(0)},[d]);const S=()=>{const y=!d;s||c(y),r==null||r(y)};return t.jsxs(t.Fragment,{children:[t.jsx("style",{children:Va}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",...i},children:[t.jsxs("button",{onClick:S,"aria-expanded":d,style:{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",background:"none",border:"none",padding:"var(--lucent-space-3) var(--lucent-space-4)",cursor:"pointer",textAlign:"left",outline:"none",fontFamily:"inherit",fontSize:"inherit"},children:[t.jsx("span",{style:{flex:1},children:e}),t.jsx(Ga,{open:d})]}),t.jsx("div",{ref:p,"aria-hidden":!d,style:{overflow:"hidden",height:m!==void 0?m:"auto",transition:"height 200ms var(--lucent-easing-default)"},children:t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-4) var(--lucent-space-3)",animation:d?"lucent-collapsible-open 200ms var(--lucent-easing-default) forwards":void 0},children:n})})]})]})}function Ga({open:e}){return t.jsx("svg",{width:16,height:16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,style:{flexShrink:0,color:"var(--lucent-text-secondary)",transform:e?"rotate(180deg)":"rotate(0deg)",transition:"transform 200ms var(--lucent-easing-default)"},children:t.jsx("polyline",{points:"6 9 12 15 18 9"})})}function pe(e){return typeof e=="number"?`${e}px`:e}function Ua({children:e,header:n,sidebar:a,sidebarWidth:o=240,headerHeight:r=48,sidebarCollapsed:i=!1,rightSidebar:s,rightSidebarWidth:l=240,rightSidebarCollapsed:c=!1,footer:d,footerHeight:p=28,mainStyle:m,style:h}){const u=pe(r),S=pe(o),y=pe(l),b=pe(p);return t.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100vh",overflow:"hidden",fontFamily:"var(--lucent-font-family-base)",...h},children:[n!=null&&t.jsx("div",{style:{flexShrink:0,height:u,zIndex:10,background:"var(--lucent-surface)"},children:n}),t.jsxs("div",{style:{display:"flex",flex:1,overflow:"hidden"},children:[a!=null&&t.jsx("div",{style:{width:i?0:S,flexShrink:0,overflow:"hidden",overflowY:i?"hidden":"auto",background:"var(--lucent-surface)",transition:"width 200ms var(--lucent-easing-default)"},children:a}),t.jsx("main",{style:{flex:1,overflowY:"auto",minWidth:0,margin:s!=null?"0 0 var(--lucent-space-3) 0":"0 var(--lucent-space-3) var(--lucent-space-3) 0",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"var(--lucent-shadow-sm)",background:"var(--lucent-surface)",...m},children:e}),s!=null&&t.jsx("aside",{style:{width:c?0:y,flexShrink:0,overflow:"hidden",overflowY:c?"hidden":"auto",background:"var(--lucent-surface)",transition:"width 200ms var(--lucent-easing-default)"},children:s})]}),d!=null&&t.jsx("div",{style:{flexShrink:0,height:b,zIndex:10,background:"var(--lucent-surface)"},children:d})]})}function _a({state:e}){return t.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none","aria-hidden":!0,style:{flexShrink:0,opacity:e==="none"?.35:1},children:[t.jsx("path",{d:"M6 2L9 5H3L6 2Z",fill:"currentColor",opacity:e==="desc"?.35:1}),t.jsx("path",{d:"M6 10L3 7H9L6 10Z",fill:"currentColor",opacity:e==="asc"?.35:1})]})}function at({dir:e}){return t.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:e==="left"?"M10 12L6 8l4-4":"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function Ya({columns:e,rows:n,pageSize:a=10,page:o,onPageChange:r,onFilterChange:i,emptyState:s,style:l}){const[c,d]=f.useState(null),[p,m]=f.useState(0),[h,u]=f.useState(null),[S,y]=f.useState({}),b=o!==void 0,v=b?o:p,w=e.some(C=>C.filterable),j=w?n.filter(C=>e.every(R=>{if(!R.filterable)return!0;const I=S[R.key];if(!I||I.length===0)return!0;const L=String(C[R.key]??"");return I.includes(L)})):n,T=c?[...j].sort((C,R)=>{const I=C[c.key],L=R[c.key],W=String(I??"").localeCompare(String(L??""),void 0,{numeric:!0});return c.dir==="asc"?W:-W}):j,x=a>0?T.slice(v*a,(v+1)*a):T,M=a>0?Math.max(1,Math.ceil(T.length/a)):1,F=C=>{b||m(C),r==null||r(C)},k=C=>{d(R=>!R||R.key!==C?{key:C,dir:"asc"}:R.dir==="asc"?{key:C,dir:"desc"}:null),b||m(0),r==null||r(0)},z=(C,R)=>{const I={...S,[C]:R};R.length===0&&delete I[C],y(I),b||m(0),r==null||r(0),i==null||i(I)},q=()=>{y({}),b||m(0),r==null||r(0),i==null||i({})},E=[];if(M<=7)for(let C=0;C<M;C++)E.push(C);else{E.push(0),v>2&&E.push("…");for(let C=Math.max(1,v-1);C<=Math.min(M-2,v+1);C++)E.push(C);v<M-3&&E.push("…"),E.push(M-1)}return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-3)",...l},children:[w&&t.jsx("div",{style:{position:"relative",zIndex:1},children:t.jsx(Ka,{columns:e,rows:n,filters:S,onFilter:z,onClearAll:q})}),t.jsx("div",{style:{overflowX:"auto",borderRadius:"var(--lucent-radius-lg)",border:"1px solid var(--lucent-border-default)"},children:t.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)"},children:[t.jsx("thead",{children:t.jsx("tr",{style:{borderBottom:"1px solid var(--lucent-border-default)"},children:e.map(C=>{const R=(c==null?void 0:c.key)===C.key?c.dir:"none";return t.jsx("th",{onClick:C.sortable?()=>k(C.key):void 0,style:{padding:"var(--lucent-space-3) var(--lucent-space-4)",textAlign:C.align??"left",fontWeight:"var(--lucent-font-weight-medium)",color:"var(--lucent-text-secondary)",background:"var(--lucent-surface-secondary)",borderBottom:"1px solid var(--lucent-border-default)",cursor:C.sortable?"pointer":"default",userSelect:"none",whiteSpace:"nowrap",...C.width?{width:C.width}:{}},children:t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[C.header,C.sortable&&t.jsx(_a,{state:R})]})},C.key)})})}),t.jsx("tbody",{children:x.length===0?t.jsx("tr",{children:t.jsx("td",{colSpan:e.length,style:{padding:"var(--lucent-space-12)",textAlign:"center"},children:s??t.jsx(P,{color:"secondary",children:"No data"})})}):x.map((C,R)=>t.jsx("tr",{onMouseEnter:()=>u(R),onMouseLeave:()=>u(null),style:{borderBottom:R<x.length-1?"1px solid var(--lucent-border-subtle)":"none",background:h===R?"var(--lucent-surface-secondary)":"var(--lucent-surface)",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:e.map(I=>t.jsx("td",{style:{padding:"var(--lucent-space-3) var(--lucent-space-4)",color:"var(--lucent-text-primary)",textAlign:I.align??"left",verticalAlign:"middle"},children:I.render?I.render(C,R):String(C[I.key]??"")},I.key))},R))})]})}),a>0&&T.length>0&&t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"var(--lucent-space-3)",flexWrap:"wrap"},children:[t.jsx(P,{color:"secondary",size:"sm",children:T.length===0?`0 rows${n.length>0?` (filtered from ${n.length})`:""}`:T.length===1?`1 row${T.length<n.length?` (filtered from ${n.length})`:""}`:`${v*a+1}–${Math.min((v+1)*a,T.length)} of ${T.length} rows${T.length<n.length?` (filtered from ${n.length})`:""}`}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[t.jsx(we,{onClick:()=>F(v-1),disabled:v===0,"aria-label":"Previous page",children:t.jsx(at,{dir:"left"})}),E.map((C,R)=>C==="…"?t.jsx("span",{style:{padding:"0 var(--lucent-space-1)",color:"var(--lucent-text-disabled)",fontSize:"var(--lucent-font-size-sm)"},children:"…"},`ellipsis-${R}`):t.jsx(we,{onClick:()=>F(C),active:C===v,"aria-label":`Page ${C+1}`,"aria-current":C===v?"page":void 0,children:C+1},C)),t.jsx(we,{onClick:()=>F(v+1),disabled:v>=M-1,"aria-label":"Next page",children:t.jsx(at,{dir:"right"})})]})]})]})}function Ka({columns:e,rows:n,filters:a,onFilter:o,onClearAll:r}){const i=e.filter(l=>l.filterable),s=Object.keys(a).length;return t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",flexWrap:"wrap"},children:[i.map(l=>{const c=Array.from(new Set(n.map(d=>String(d[l.key]??"")))).sort();return t.jsx(Xa,{label:l.header,values:c,value:a[l.key]??[],onChange:d=>o(l.key,d)},l.key)}),s>0&&t.jsx("button",{onClick:r,style:{display:"inline-flex",alignItems:"center",height:30,padding:"0 var(--lucent-space-2)",border:"none",borderRadius:"var(--lucent-radius-md)",background:"transparent",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",cursor:"pointer"},children:"Clear all"})]})}function Xa({label:e,values:n,value:a,onChange:o}){const[r,i]=f.useState(!1),[s,l]=f.useState(!1),[c,d]=f.useState(""),p=f.useRef(null),m=f.useRef(null),h=a.length>0;f.useEffect(()=>{if(!r){d("");return}setTimeout(()=>{var w;return(w=m.current)==null?void 0:w.focus()},0);const b=w=>{p.current&&!p.current.contains(w.target)&&i(!1)},v=w=>{w.key==="Escape"&&i(!1)};return document.addEventListener("mousedown",b),document.addEventListener("keydown",v),()=>{document.removeEventListener("mousedown",b),document.removeEventListener("keydown",v)}},[r]);const u=c?n.filter(b=>b.toLowerCase().includes(c.toLowerCase())):n,S=b=>o(a.includes(b)?a.filter(v=>v!==b):[...a,b]),y=a.length===0?null:a.length===1?t.jsxs("span",{style:{color:"var(--lucent-text-secondary)",fontWeight:"var(--lucent-font-weight-regular)"},children:[": ",a[0]]}):t.jsxs("span",{style:{color:"var(--lucent-accent-default)"},children:["(",a.length,")"]});return t.jsxs("div",{ref:p,style:{position:"relative"},children:[t.jsxs("button",{onClick:()=>i(b=>!b),onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-1)",height:30,padding:"0 var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:`1px solid ${h?"var(--lucent-accent-default)":s?"var(--lucent-border-strong)":"var(--lucent-border-default)"}`,background:h?"var(--lucent-accent-subtle)":"var(--lucent-surface)",color:h?"var(--lucent-accent-default)":"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",fontWeight:h?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",cursor:"pointer",outline:"none",whiteSpace:"nowrap",transition:"border-color var(--lucent-duration-fast) var(--lucent-easing-default), background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:[e,y,t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,style:{transform:r?"rotate(180deg)":"none",transition:"transform var(--lucent-duration-fast) var(--lucent-easing-default)"},children:t.jsx("path",{d:"M2 3.5L5 6.5L8 3.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]}),r&&t.jsxs("div",{style:{position:"absolute",top:"calc(100% + 4px)",left:0,minWidth:180,maxHeight:280,display:"flex",flexDirection:"column",background:"var(--lucent-surface)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"0 4px 16px color-mix(in srgb, var(--lucent-text-primary) 8%, transparent)",zIndex:50},children:[t.jsx("div",{style:{padding:"var(--lucent-space-2)",paddingBottom:0},children:t.jsx("input",{ref:m,type:"text",value:c,onChange:b=>d(b.target.value),placeholder:"Search…",style:{width:"100%",boxSizing:"border-box",height:26,padding:"0 var(--lucent-space-2)",borderRadius:"var(--lucent-radius-md)",border:"1px solid var(--lucent-border-default)",background:"var(--lucent-surface-secondary)",color:"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",outline:"none"}})}),a.length>0&&t.jsx("div",{style:{padding:"var(--lucent-space-1) var(--lucent-space-2) 0"},children:t.jsx("button",{onClick:()=>o([]),style:{display:"inline-flex",padding:"2px var(--lucent-space-2)",border:"none",borderRadius:"var(--lucent-radius-sm)",background:"transparent",color:"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",cursor:"pointer",textDecoration:"underline"},children:"Clear selection"})}),t.jsx("div",{style:{overflowY:"auto",padding:"var(--lucent-space-1)",borderTop:"1px solid var(--lucent-border-subtle)",marginTop:"var(--lucent-space-2)"},children:u.length===0?t.jsx("div",{style:{padding:"var(--lucent-space-3)",color:"var(--lucent-text-disabled)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",textAlign:"center"},children:"No results"}):u.map(b=>t.jsx(Ja,{label:b,isSelected:a.includes(b),onClick:()=>S(b)},b))})]})]})}function Ja({label:e,isSelected:n,onClick:a}){const[o,r]=f.useState(!1);return t.jsxs("button",{onClick:a,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",width:"100%",textAlign:"left",padding:"var(--lucent-space-2) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:"none",background:o?"var(--lucent-surface-secondary)":"transparent",color:"var(--lucent-text-primary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-xs)",fontWeight:n?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",cursor:"pointer",outline:"none",whiteSpace:"nowrap"},children:[t.jsx("span",{style:{flexShrink:0,width:14,height:14,borderRadius:"var(--lucent-radius-sm)",border:`1.5px solid ${n?"var(--lucent-accent-default)":"var(--lucent-border-strong)"}`,background:n?"var(--lucent-accent-default)":"transparent",display:"flex",alignItems:"center",justifyContent:"center",transition:"border-color var(--lucent-duration-fast), background var(--lucent-duration-fast)"},children:n&&t.jsx("svg",{width:"8",height:"8",viewBox:"0 0 8 8",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M1 4L3 6L7 2",stroke:"var(--lucent-text-on-accent)",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),e]})}function we({children:e,onClick:n,disabled:a,active:o,...r}){const[i,s]=f.useState(!1);return t.jsx("button",{...r,onClick:n,disabled:a,onMouseEnter:()=>s(!0),onMouseLeave:()=>s(!1),style:{display:"inline-flex",alignItems:"center",justifyContent:"center",minWidth:32,height:32,padding:"0 var(--lucent-space-2)",borderRadius:"var(--lucent-radius-md)",border:o?"1px solid var(--lucent-accent-default)":"1px solid transparent",background:o?"var(--lucent-accent-default)":i&&!a?"var(--lucent-surface-secondary)":"transparent",color:o?"var(--lucent-text-on-accent)":a?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontSize:"var(--lucent-font-size-sm)",fontFamily:"var(--lucent-font-family-base)",fontWeight:"var(--lucent-font-weight-regular)",cursor:a?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)"},children:e})}const Za={id:"data-table",name:"DataTable",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A sortable, filterable, paginated data table with configurable columns, custom cell renderers, and keyboard-accessible pagination controls.",designIntent:'DataTable is generic over row type T so TypeScript consumers get full type safety on column keys and renderers. Sorting is client-side and composable — each column opts in via sortable:true; clicking a sorted column cycles asc → desc → unsorted. Filtering is per-column — each column opts in via filterable:true, which adds a dropdown button above the table. Each dropdown is searchable and multi-select: a search input filters the option list, and each option is a checkbox that toggles membership in the active set. Filtering uses set-membership: a row passes if its column value is included in the selected values array. A "Clear selection" link inside each dropdown clears that column; a "Clear all" button in the bar appears when any filter is active. Filter → sort → paginate is the fixed pipeline order; any filter change resets the page to 0. Pagination is either controlled (page prop + onPageChange) or uncontrolled (internal state). A pageSize of 0 disables pagination entirely, useful when the parent manages windowing. Row hover uses bg-subtle, not a border change, so the visual weight stays low for dense data views.',props:[{name:"columns",type:"array",required:!0,description:"Column definitions. Each column has a key, header, optional render function, optional sortable flag, optional filterable flag (renders a text filter input below the header), optional width, and optional text align."},{name:"rows",type:"array",required:!0,description:"Array of data objects to display. The generic type T is inferred from this prop."},{name:"pageSize",type:"number",required:!1,default:"10",description:"Number of rows per page. Set to 0 to disable pagination."},{name:"page",type:"number",required:!1,description:"Controlled current page (0-indexed). When provided, the component is fully controlled."},{name:"onPageChange",type:"function",required:!1,description:"Called with the new page index whenever the page changes (from pagination controls or after a sort/filter reset)."},{name:"onFilterChange",type:"function",required:!1,description:"Called with the current filter map (Record<string, string[]>) whenever any column filter changes. Keys are column keys; columns with no selection are omitted from the map."},{name:"emptyState",type:"ReactNode",required:!1,description:'Content to render when rows is empty. Defaults to a "No data" text.'},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Basic sortable table",code:`<DataTable
283
283
  columns={[
284
284
  { key: 'name', header: 'Name', sortable: true },
285
285
  { key: 'role', header: 'Role', sortable: true },
@@ -306,7 +306,7 @@ Token rule: Card uses surface for its background. Never use bgBase or bgSubtle o
306
306
  from { opacity: 0; transform: scale(0.96) translateY(-8px); }
307
307
  to { opacity: 1; transform: scale(1) translateY(0); }
308
308
  }
309
- `;function er(e,n){var o;const a=n.toLowerCase();return e.label.toLowerCase().includes(a)||(((o=e.description)==null?void 0:o.toLowerCase().includes(a))??!1)}function tr({commands:e,placeholder:n="Search commands…",shortcutKey:a="k",open:o,onOpenChange:r,style:i}){const s=o!==void 0,[l,c]=p.useState(!1),u=s?o:l,[f,d]=p.useState(""),[y,h]=p.useState(0),w=p.useRef(null),v=p.useRef(null),g=p.useRef(!1);if(!g.current){const T=document.createElement("style");T.textContent=Qa,document.head.appendChild(T),g.current=!0}const b=p.useCallback(T=>{s||c(T),r==null||r(T)},[s,r]);p.useEffect(()=>{const T=C=>{(C.metaKey||C.ctrlKey)&&C.key===a&&(C.preventDefault(),b(!u))};return window.addEventListener("keydown",T),()=>window.removeEventListener("keydown",T)},[u,a,b]),p.useEffect(()=>{u&&(d(""),h(0),setTimeout(()=>{var T;return(T=w.current)==null?void 0:T.focus()},10))},[u]);const k=f?e.filter(T=>er(T,f)):e,D=k.filter(T=>!T.disabled);p.useEffect(()=>{const T=v.current;if(!T)return;const C=T.querySelector('[data-active="true"]');C==null||C.scrollIntoView({block:"nearest"})},[y]);const S=T=>{T.disabled||(T.onSelect(),b(!1))},x=T=>{if(T.key==="Escape"){b(!1);return}if(T.key==="ArrowDown"&&(T.preventDefault(),h(C=>Math.min(C+1,D.length-1))),T.key==="ArrowUp"&&(T.preventDefault(),h(C=>Math.max(C-1,0))),T.key==="Enter"){const C=D[y];C&&S(C)}},z=[];for(const T of k){const C=z[z.length-1];C&&C.group===T.group?C.items.push(T):z.push({group:T.group,items:[T]})}if(!u)return null;let q=0;return t.jsx("div",{role:"dialog","aria-label":"Command palette","aria-modal":"true",onClick:()=>b(!1),style:{position:"fixed",inset:0,zIndex:9e3,display:"flex",alignItems:"flex-start",justifyContent:"center",paddingTop:"15vh",background:"var(--lucent-bg-overlay)",...i},children:t.jsxs("div",{role:"combobox","aria-haspopup":"listbox","aria-expanded":"true",onClick:T=>T.stopPropagation(),style:{width:"100%",maxWidth:560,margin:"0 var(--lucent-space-4)",background:"var(--lucent-surface-overlay)",borderRadius:"var(--lucent-radius-xl)",border:"1px solid var(--lucent-border-default)",boxShadow:"var(--lucent-shadow-xl)",overflow:"hidden",animation:"lucent-palette-in 150ms var(--lucent-easing-decelerate)"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-3) var(--lucent-space-4)",borderBottom:k.length>0?"1px solid var(--lucent-border-subtle)":"none"},children:[t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":!0,style:{flexShrink:0,color:"var(--lucent-text-secondary)"},children:[t.jsx("circle",{cx:"7",cy:"7",r:"4.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M10.5 10.5L13.5 13.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),t.jsx("input",{ref:w,role:"searchbox","aria-autocomplete":"list","aria-controls":"lucent-command-list",value:f,onChange:T=>{d(T.target.value),h(0)},onKeyDown:x,placeholder:n,style:{flex:1,border:"none",outline:"none",background:"transparent",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",color:"var(--lucent-text-primary)",lineHeight:"var(--lucent-line-height-base)"}}),t.jsx("kbd",{style:{display:"inline-flex",alignItems:"center",padding:"2px 6px",borderRadius:"var(--lucent-radius-sm)",border:"1px solid var(--lucent-border-default)",background:"var(--lucent-surface-secondary)",fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-xs)",color:"var(--lucent-text-secondary)"},children:"Esc"})]}),t.jsx("div",{id:"lucent-command-list",role:"listbox",ref:v,style:{maxHeight:360,overflowY:"auto",padding:"var(--lucent-space-1) 0"},children:k.length===0?t.jsx("div",{style:{padding:"var(--lucent-space-8)",textAlign:"center"},children:t.jsxs(B,{color:"secondary",children:['No results for "',f,'"']})}):z.map(({group:T,items:C},V)=>t.jsxs("div",{children:[T&&t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-4) var(--lucent-space-1)",...V>0?{borderTop:"1px solid var(--lucent-border-subtle)",marginTop:"var(--lucent-space-1)"}:{}},children:t.jsx(B,{size:"xs",color:"secondary",weight:"medium",children:T})}),C.map(R=>{const I=R.disabled??!1;let j=!1;return I||(j=q===y,q++),t.jsxs("div",{role:"option","aria-selected":j,"aria-disabled":I,"data-active":j,onClick:()=>S(R),onMouseEnter:()=>{if(!I){const M=D.indexOf(R);M!==-1&&h(M)}},style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-2) var(--lucent-space-4)",cursor:I?"not-allowed":"pointer",background:j?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)",opacity:I?.5:1},children:[R.icon&&t.jsx("span",{style:{flexShrink:0,color:"var(--lucent-text-secondary)",display:"flex"},children:R.icon}),t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx(B,{size:"sm",weight:"medium",truncate:!0,children:R.label}),R.description&&t.jsx(B,{size:"xs",color:"secondary",truncate:!0,children:R.description})]})]},R.id)})]},V))}),t.jsx("div",{style:{display:"flex",gap:"var(--lucent-space-4)",padding:"var(--lucent-space-2) var(--lucent-space-4)",borderTop:"1px solid var(--lucent-border-subtle)",background:"var(--lucent-surface-secondary)"},children:[["↑↓","Navigate"],["↵","Select"],["Esc","Close"]].map(([T,C])=>t.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[t.jsx("kbd",{style:{padding:"1px 5px",borderRadius:"var(--lucent-radius-sm)",border:"1px solid var(--lucent-border-default)",background:"var(--lucent-surface)",fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-xs)",color:"var(--lucent-text-secondary)"},children:T}),t.jsx(B,{size:"xs",color:"secondary",children:C})]},T))})]})})}const nr={id:"command-palette",name:"CommandPalette",tier:"overlay",domain:"neutral",specVersion:"1.0",description:"A keyboard-driven modal command palette with fuzzy search, grouped results, and a built-in ⌘K / Ctrl+K global shortcut.",designIntent:"CommandPalette renders as a portal-style overlay (fixed, full-viewport) with a centred panel that animates in with a subtle scale+fade. The ⌘K shortcut is registered as a global window listener so it works regardless of focus — consumers can override the key via shortcutKey prop. Clicking the backdrop dismisses the palette; Escape also closes it. Results are filtered client-side against label and description using simple substring match — no fuzzy library needed. Navigation is purely keyboard-driven: ↑↓ move the active index, Enter selects, mouse hover syncs the active index so mouse and keyboard stay in sync. Groups are derived from the group field on each CommandItem; the order of groups follows the order they first appear in the commands array. The component is controlled-or-uncontrolled: pass open + onOpenChange for controlled use, or omit both to use internal state.",props:[{name:"commands",type:"array",required:!0,description:"Array of CommandItem objects. Each has id, label, onSelect, and optional description, icon, group, disabled."},{name:"placeholder",type:"string",required:!1,default:'"Search commands…"',description:"Placeholder text for the search input."},{name:"shortcutKey",type:"string",required:!1,default:'"k"',description:'Key that opens the palette when pressed with Meta (Mac) or Ctrl (Windows). Defaults to "k" for ⌘K.'},{name:"open",type:"boolean",required:!1,description:"Controlled open state. When provided, the component is fully controlled."},{name:"onOpenChange",type:"function",required:!1,description:"Called when the palette requests an open/close state change."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the backdrop element."}],usageExamples:[{title:"Uncontrolled with ⌘K",code:`<CommandPalette
309
+ `;function er(e,n){var o;const a=n.toLowerCase();return e.label.toLowerCase().includes(a)||(((o=e.description)==null?void 0:o.toLowerCase().includes(a))??!1)}function tr({commands:e,placeholder:n="Search commands…",shortcutKey:a="k",open:o,onOpenChange:r,style:i}){const s=o!==void 0,[l,c]=f.useState(!1),d=s?o:l,[p,m]=f.useState(""),[h,u]=f.useState(0),S=f.useRef(null),y=f.useRef(null),b=f.useRef(!1);if(!b.current){const k=document.createElement("style");k.textContent=Qa,document.head.appendChild(k),b.current=!0}const v=f.useCallback(k=>{s||c(k),r==null||r(k)},[s,r]);f.useEffect(()=>{const k=z=>{(z.metaKey||z.ctrlKey)&&z.key===a&&(z.preventDefault(),v(!d))};return window.addEventListener("keydown",k),()=>window.removeEventListener("keydown",k)},[d,a,v]),f.useEffect(()=>{d&&(m(""),u(0),setTimeout(()=>{var k;return(k=S.current)==null?void 0:k.focus()},10))},[d]);const w=p?e.filter(k=>er(k,p)):e,j=w.filter(k=>!k.disabled);f.useEffect(()=>{const k=y.current;if(!k)return;const z=k.querySelector('[data-active="true"]');z==null||z.scrollIntoView({block:"nearest"})},[h]);const T=k=>{k.disabled||(k.onSelect(),v(!1))},x=k=>{if(k.key==="Escape"){v(!1);return}if(k.key==="ArrowDown"&&(k.preventDefault(),u(z=>Math.min(z+1,j.length-1))),k.key==="ArrowUp"&&(k.preventDefault(),u(z=>Math.max(z-1,0))),k.key==="Enter"){const z=j[h];z&&T(z)}},M=[];for(const k of w){const z=M[M.length-1];z&&z.group===k.group?z.items.push(k):M.push({group:k.group,items:[k]})}if(!d)return null;let F=0;return t.jsx("div",{role:"dialog","aria-label":"Command palette","aria-modal":"true",onClick:()=>v(!1),style:{position:"fixed",inset:0,zIndex:9e3,display:"flex",alignItems:"flex-start",justifyContent:"center",paddingTop:"15vh",background:"var(--lucent-bg-overlay)",...i},children:t.jsxs("div",{role:"combobox","aria-haspopup":"listbox","aria-expanded":"true",onClick:k=>k.stopPropagation(),style:{width:"100%",maxWidth:560,margin:"0 var(--lucent-space-4)",background:"var(--lucent-surface-overlay)",borderRadius:"var(--lucent-radius-xl)",border:"1px solid var(--lucent-border-default)",boxShadow:"var(--lucent-shadow-xl)",overflow:"hidden",animation:"lucent-palette-in 150ms var(--lucent-easing-decelerate)"},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-3) var(--lucent-space-4)",borderBottom:w.length>0?"1px solid var(--lucent-border-subtle)":"none"},children:[t.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":!0,style:{flexShrink:0,color:"var(--lucent-text-secondary)"},children:[t.jsx("circle",{cx:"7",cy:"7",r:"4.5",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("path",{d:"M10.5 10.5L13.5 13.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),t.jsx("input",{ref:S,role:"searchbox","aria-autocomplete":"list","aria-controls":"lucent-command-list",value:p,onChange:k=>{m(k.target.value),u(0)},onKeyDown:x,placeholder:n,style:{flex:1,border:"none",outline:"none",background:"transparent",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-md)",color:"var(--lucent-text-primary)",lineHeight:"var(--lucent-line-height-base)"}}),t.jsx("kbd",{style:{display:"inline-flex",alignItems:"center",padding:"2px 6px",borderRadius:"var(--lucent-radius-sm)",border:"1px solid var(--lucent-border-default)",background:"var(--lucent-surface-secondary)",fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-xs)",color:"var(--lucent-text-secondary)"},children:"Esc"})]}),t.jsx("div",{id:"lucent-command-list",role:"listbox",ref:y,style:{maxHeight:360,overflowY:"auto",padding:"var(--lucent-space-1) 0"},children:w.length===0?t.jsx("div",{style:{padding:"var(--lucent-space-8)",textAlign:"center"},children:t.jsxs(P,{color:"secondary",children:['No results for "',p,'"']})}):M.map(({group:k,items:z},q)=>t.jsxs("div",{children:[k&&t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-4) var(--lucent-space-1)",...q>0?{borderTop:"1px solid var(--lucent-border-subtle)",marginTop:"var(--lucent-space-1)"}:{}},children:t.jsx(P,{size:"xs",color:"secondary",weight:"medium",children:k})}),z.map(E=>{const C=E.disabled??!1;let R=!1;return C||(R=F===h,F++),t.jsxs("div",{role:"option","aria-selected":R,"aria-disabled":C,"data-active":R,onClick:()=>T(E),onMouseEnter:()=>{if(!C){const I=j.indexOf(E);I!==-1&&u(I)}},style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-2) var(--lucent-space-4)",cursor:C?"not-allowed":"pointer",background:R?"var(--lucent-surface-secondary)":"transparent",transition:"background var(--lucent-duration-fast) var(--lucent-easing-default)",opacity:C?.5:1},children:[E.icon&&t.jsx("span",{style:{flexShrink:0,color:"var(--lucent-text-secondary)",display:"flex"},children:E.icon}),t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx(P,{size:"sm",weight:"medium",truncate:!0,children:E.label}),E.description&&t.jsx(P,{size:"xs",color:"secondary",truncate:!0,children:E.description})]})]},E.id)})]},q))}),t.jsx("div",{style:{display:"flex",gap:"var(--lucent-space-4)",padding:"var(--lucent-space-2) var(--lucent-space-4)",borderTop:"1px solid var(--lucent-border-subtle)",background:"var(--lucent-surface-secondary)"},children:[["↑↓","Navigate"],["↵","Select"],["Esc","Close"]].map(([k,z])=>t.jsxs("span",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-1)"},children:[t.jsx("kbd",{style:{padding:"1px 5px",borderRadius:"var(--lucent-radius-sm)",border:"1px solid var(--lucent-border-default)",background:"var(--lucent-surface)",fontFamily:"var(--lucent-font-family-mono)",fontSize:"var(--lucent-font-size-xs)",color:"var(--lucent-text-secondary)"},children:k}),t.jsx(P,{size:"xs",color:"secondary",children:z})]},k))})]})})}const nr={id:"command-palette",name:"CommandPalette",tier:"overlay",domain:"neutral",specVersion:"1.0",description:"A keyboard-driven modal command palette with fuzzy search, grouped results, and a built-in ⌘K / Ctrl+K global shortcut.",designIntent:"CommandPalette renders as a portal-style overlay (fixed, full-viewport) with a centred panel that animates in with a subtle scale+fade. The ⌘K shortcut is registered as a global window listener so it works regardless of focus — consumers can override the key via shortcutKey prop. Clicking the backdrop dismisses the palette; Escape also closes it. Results are filtered client-side against label and description using simple substring match — no fuzzy library needed. Navigation is purely keyboard-driven: ↑↓ move the active index, Enter selects, mouse hover syncs the active index so mouse and keyboard stay in sync. Groups are derived from the group field on each CommandItem; the order of groups follows the order they first appear in the commands array. The component is controlled-or-uncontrolled: pass open + onOpenChange for controlled use, or omit both to use internal state.",props:[{name:"commands",type:"array",required:!0,description:"Array of CommandItem objects. Each has id, label, onSelect, and optional description, icon, group, disabled."},{name:"placeholder",type:"string",required:!1,default:'"Search commands…"',description:"Placeholder text for the search input."},{name:"shortcutKey",type:"string",required:!1,default:'"k"',description:'Key that opens the palette when pressed with Meta (Mac) or Ctrl (Windows). Defaults to "k" for ⌘K.'},{name:"open",type:"boolean",required:!1,description:"Controlled open state. When provided, the component is fully controlled."},{name:"onOpenChange",type:"function",required:!1,description:"Called when the palette requests an open/close state change."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the backdrop element."}],usageExamples:[{title:"Uncontrolled with ⌘K",code:`<CommandPalette
310
310
  commands={[
311
311
  { id: 'new', label: 'New document', icon: <PlusIcon />, onSelect: () => router.push('/new') },
312
312
  { id: 'settings', label: 'Settings', description: 'Open app settings', onSelect: () => router.push('/settings') },
@@ -321,7 +321,7 @@ Token rule: Card uses surface for its background. Never use bgBase or bgSubtle o
321
321
  onOpenChange={setOpen}
322
322
  shortcutKey="p"
323
323
  />
324
- </>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Group labels, item labels, descriptions, and empty state",required:!0}],accessibility:{role:"dialog",ariaAttributes:["aria-label","aria-modal","aria-expanded","aria-selected","aria-disabled","aria-controls","aria-autocomplete"],keyboardInteractions:["⌘K / Ctrl+K to open","↑↓ to navigate","Enter to select","Escape to close"],notes:'The backdrop and panel use role="dialog" with aria-modal="true". The input is role="searchbox". The result list is role="listbox" with role="option" items. Focus is moved to the search input on open.'}};function ar({label:e,onRemove:n,disabled:a}){return t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4,padding:"2px 6px 2px 8px",borderRadius:"var(--lucent-radius-full)",background:"var(--lucent-surface-secondary)",border:"1px solid var(--lucent-border-default)",fontSize:"var(--lucent-font-size-sm)",fontFamily:"var(--lucent-font-family-base)",color:"var(--lucent-text-primary)",lineHeight:1.4,flexShrink:0},children:[e,!a&&t.jsx("button",{type:"button",onClick:o=>{o.stopPropagation(),n()},"aria-label":`Remove ${e}`,style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:14,height:14,padding:0,border:"none",background:"none",cursor:"pointer",color:"var(--lucent-text-secondary)",borderRadius:"var(--lucent-radius-full)"},children:t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M2 2l6 6M8 2l-6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]})}function rr({options:e,value:n,defaultValue:a=[],onChange:o,placeholder:r="Select…",disabled:i=!1,max:s,style:l}){const c=n!==void 0,[u,f]=p.useState(a),d=c?n:u,[y,h]=p.useState(!1),[w,v]=p.useState(""),[g,b]=p.useState(0),[k,D]=p.useState(!1),S=p.useRef(null),x=p.useRef(null),z=p.useId();p.useEffect(()=>{if(!y)return;const j=M=>{var P;(P=S.current)!=null&&P.contains(M.target)||(h(!1),v(""))};return document.addEventListener("mousedown",j),()=>document.removeEventListener("mousedown",j)},[y]);const q=j=>{const M=d.includes(j)?d.filter(P=>P!==j):s!==void 0&&d.length>=s?d:[...d,j];c||f(M),o==null||o(M)},T=j=>{const M=d.filter(P=>P!==j);c||f(M),o==null||o(M)},C=e.filter(j=>j.label.toLowerCase().includes(w.toLowerCase())),V=j=>{if(j.key==="Escape"){h(!1),v("");return}if(j.key==="ArrowDown"&&(j.preventDefault(),h(!0),b(M=>Math.min(M+1,C.length-1))),j.key==="ArrowUp"&&(j.preventDefault(),b(M=>Math.max(M-1,0))),j.key==="Enter"){j.preventDefault();const M=C[g];M&&!M.disabled&&q(M.value)}j.key==="Backspace"&&w===""&&d.length>0&&T(d[d.length-1])},R=s!==void 0&&d.length>=s,I=i?"var(--lucent-border-default)":k?"var(--lucent-accent-default)":"var(--lucent-border-default)";return t.jsxs("div",{ref:S,style:{position:"relative",...l},children:[t.jsxs("div",{onClick:()=>{var j;i||(h(!0),(j=x.current)==null||j.focus())},style:{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"var(--lucent-space-1)",minHeight:38,padding:"var(--lucent-space-1) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:`1px solid ${I}`,background:i?"var(--lucent-surface-secondary)":"var(--lucent-surface)",cursor:i?"not-allowed":"text",transition:"border-color var(--lucent-duration-fast) var(--lucent-easing-default)",outline:k?"2px solid var(--lucent-focus-ring)":"none",outlineOffset:2},children:[d.map(j=>{const M=e.find(P=>P.value===j);return M?t.jsx(ar,{label:M.label,onRemove:()=>T(j),disabled:i},j):null}),t.jsx("input",{ref:x,value:w,onChange:j=>{v(j.target.value),h(!0),b(0)},onKeyDown:V,onFocus:()=>D(!0),onBlur:()=>D(!1),disabled:i,placeholder:d.length===0?r:"","aria-autocomplete":"list","aria-controls":z,"aria-expanded":y,role:"combobox",style:{flex:"1 1 80px",minWidth:80,border:"none",outline:"none",background:"transparent",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",color:i?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",cursor:i?"not-allowed":"text",padding:"2px 0"}})]}),y&&!i&&t.jsxs("div",{id:z,role:"listbox","aria-multiselectable":"true",style:{position:"absolute",top:"calc(100% + 4px)",left:0,right:0,zIndex:1e3,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-md)",boxShadow:"var(--lucent-shadow-md)",maxHeight:240,overflowY:"auto",padding:"var(--lucent-space-1) 0"},children:[C.length===0?t.jsx("div",{style:{padding:"var(--lucent-space-3) var(--lucent-space-4)"},children:t.jsx(B,{color:"secondary",size:"sm",children:"No options"})}):C.map((j,M)=>{const P=d.includes(j.value),G=M===g,H=j.disabled??!1,_=R&&!P;return t.jsxs("div",{role:"option","aria-selected":P,"aria-disabled":H||_,onClick:()=>{!H&&!_&&q(j.value)},onMouseEnter:()=>b(M),style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-2) var(--lucent-space-3)",cursor:H||_?"not-allowed":"pointer",background:G?"var(--lucent-surface-secondary)":"transparent",opacity:H||_?.5:1},children:[t.jsx(Ie,{checked:P,disabled:H||_,size:"md",style:{margin:0,pointerEvents:"none"},"aria-hidden":!0,readOnly:!0}),t.jsx(B,{size:"sm",children:j.label})]},j.value)}),R&&t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-3)",borderTop:"1px solid var(--lucent-border-subtle)"},children:t.jsxs(B,{size:"xs",color:"secondary",children:["Max ",s," selected"]})})]})]})}const or={id:"multi-select",name:"MultiSelect",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A tag-based multi-option selector with inline search, keyboard navigation, and an optional selection cap.",designIntent:"MultiSelect renders selected values as removable tags inside the trigger area, giving immediate visual feedback on what is selected. The search input sits inline with the tags so there is no separate search field to discover. Backspace with an empty query removes the last selected tag — a standard UX pattern in multi-select inputs. The max prop caps selection without disabling the entire component: unselected options beyond the cap are grayed out and show a hint. The dropdown closes on outside click, Escape, or when focus leaves. Checkbox indicators in the dropdown make the selected state scannable at a glance without relying solely on background color.",props:[{name:"options",type:"array",required:!0,description:"Array of { value, label, disabled? } option objects."},{name:"value",type:"array",required:!1,description:"Controlled array of selected values."},{name:"defaultValue",type:"array",required:!1,default:"[]",description:"Initial selected values for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called with the updated array of selected values on each change."},{name:"placeholder",type:"string",required:!1,default:'"Select…"',description:"Placeholder shown when nothing is selected."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables interaction and dims the component."},{name:"max",type:"number",required:!1,description:"Maximum number of selectable options. Unselected options beyond the cap are grayed out."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled",code:`<MultiSelect
324
+ </>`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Group labels, item labels, descriptions, and empty state",required:!0}],accessibility:{role:"dialog",ariaAttributes:["aria-label","aria-modal","aria-expanded","aria-selected","aria-disabled","aria-controls","aria-autocomplete"],keyboardInteractions:["⌘K / Ctrl+K to open","↑↓ to navigate","Enter to select","Escape to close"],notes:'The backdrop and panel use role="dialog" with aria-modal="true". The input is role="searchbox". The result list is role="listbox" with role="option" items. Focus is moved to the search input on open.'}},ar={sm:28,md:36,lg:42},rr={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-md)"},or={sm:"2px var(--lucent-space-2)",md:"2px var(--lucent-space-2)",lg:"2px var(--lucent-space-3)"},ir={sm:"sm",md:"md",lg:"lg"};function sr({options:e,value:n,defaultValue:a=[],onChange:o,placeholder:r="Select…",disabled:i=!1,max:s,size:l="md",style:c}){const d=n!==void 0,[p,m]=f.useState(a),h=d?n:p,[u,S]=f.useState(!1),[y,b]=f.useState(""),[v,w]=f.useState(0),[j,T]=f.useState(!1),x=f.useRef(null),M=f.useRef(null),F=f.useId();f.useEffect(()=>{if(!u)return;const I=L=>{var W;(W=x.current)!=null&&W.contains(L.target)||(S(!1),b(""))};return document.addEventListener("mousedown",I),()=>document.removeEventListener("mousedown",I)},[u]);const k=I=>{const L=h.includes(I)?h.filter(W=>W!==I):s!==void 0&&h.length>=s?h:[...h,I];d||m(L),o==null||o(L)},z=I=>{const L=h.filter(W=>W!==I);d||m(L),o==null||o(L)},q=e.filter(I=>I.label.toLowerCase().includes(y.toLowerCase())),E=I=>{if(I.key==="Escape"){S(!1),b("");return}if(I.key==="ArrowDown"&&(I.preventDefault(),S(!0),w(L=>Math.min(L+1,q.length-1))),I.key==="ArrowUp"&&(I.preventDefault(),w(L=>Math.max(L-1,0))),I.key==="Enter"){I.preventDefault();const L=q[v];L&&!L.disabled&&k(L.value)}I.key==="Backspace"&&y===""&&h.length>0&&z(h[h.length-1])},C=s!==void 0&&h.length>=s,R=i?"var(--lucent-border-default)":j?"var(--lucent-accent-default)":"var(--lucent-border-default)";return t.jsxs("div",{ref:x,style:{position:"relative",...c},children:[t.jsxs("div",{onClick:()=>{var I;i||(S(!0),(I=M.current)==null||I.focus())},style:{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"var(--lucent-space-2)",minHeight:ar[l],padding:or[l],borderRadius:"var(--lucent-radius-lg)",border:`1px solid ${R}`,background:i?"var(--lucent-surface-secondary)":"var(--lucent-surface)",cursor:i?"not-allowed":"text",transition:"border-color var(--lucent-duration-fast) var(--lucent-easing-default)",outline:j?"2px solid var(--lucent-focus-ring)":"none",outlineOffset:2},children:[h.map(I=>{const L=e.find(W=>W.value===I);return L?t.jsx(ht,{size:ir[l],onDismiss:()=>z(I),disabled:i,children:L.label},I):null}),t.jsx("input",{ref:M,value:y,onChange:I=>{b(I.target.value),S(!0),w(0)},onKeyDown:E,onFocus:()=>T(!0),onBlur:()=>T(!1),disabled:i,placeholder:h.length===0?r:"","aria-autocomplete":"list","aria-controls":F,"aria-expanded":u,role:"combobox",style:{flex:"1 1 80px",minWidth:80,border:"none",outline:"none",background:"transparent",fontFamily:"var(--lucent-font-family-base)",fontSize:rr[l],color:i?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",cursor:i?"not-allowed":"text",padding:"2px 0"}})]}),u&&!i&&t.jsxs("div",{id:F,role:"listbox","aria-multiselectable":"true",style:{position:"absolute",top:"calc(100% + 4px)",left:0,right:0,zIndex:1e3,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"var(--lucent-shadow-md)",maxHeight:240,overflowY:"auto",padding:"var(--lucent-space-1) 0"},children:[q.length===0?t.jsx("div",{style:{padding:"var(--lucent-space-3) var(--lucent-space-4)"},children:t.jsx(P,{color:"secondary",size:"sm",children:"No options"})}):q.map((I,L)=>{const W=h.includes(I.value),N=L===v,G=I.disabled??!1,U=C&&!W;return t.jsxs("div",{role:"option","aria-selected":W,"aria-disabled":G||U,onClick:()=>{!G&&!U&&k(I.value)},onMouseEnter:()=>w(L),style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-2) var(--lucent-space-3)",cursor:G||U?"not-allowed":"pointer",background:N?"var(--lucent-surface-secondary)":"transparent",opacity:G||U?.5:1},children:[t.jsx(Ie,{checked:W,disabled:G||U,size:"md",style:{margin:0,pointerEvents:"none"},"aria-hidden":!0,readOnly:!0}),t.jsx(P,{size:"sm",children:I.label})]},I.value)}),C&&t.jsx("div",{style:{padding:"var(--lucent-space-2) var(--lucent-space-3)",borderTop:"1px solid var(--lucent-border-subtle)"},children:t.jsxs(P,{size:"xs",color:"secondary",children:["Max ",s," selected"]})})]})]})}const lr={id:"multi-select",name:"MultiSelect",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A tag-based multi-option selector with inline search, keyboard navigation, and an optional selection cap.",designIntent:"MultiSelect renders selected values as removable tags inside the trigger area, giving immediate visual feedback on what is selected. The search input sits inline with the tags so there is no separate search field to discover. Backspace with an empty query removes the last selected tag — a standard UX pattern in multi-select inputs. The max prop caps selection without disabling the entire component: unselected options beyond the cap are grayed out and show a hint. The dropdown closes on outside click, Escape, or when focus leaves. Checkbox indicators in the dropdown make the selected state scannable at a glance without relying solely on background color.",props:[{name:"options",type:"array",required:!0,description:"Array of { value, label, disabled? } option objects."},{name:"value",type:"array",required:!1,description:"Controlled array of selected values."},{name:"defaultValue",type:"array",required:!1,default:"[]",description:"Initial selected values for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called with the updated array of selected values on each change."},{name:"placeholder",type:"string",required:!1,default:'"Select…"',description:"Placeholder shown when nothing is selected."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables interaction and dims the component."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls trigger height and font size to match Input/Select.",enumValues:["sm","md","lg"]},{name:"max",type:"number",required:!1,description:"Maximum number of selectable options. Unselected options beyond the cap are grayed out."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled",code:`<MultiSelect
325
325
  options={[
326
326
  { value: 'react', label: 'React' },
327
327
  { value: 'vue', label: 'Vue' },
@@ -335,14 +335,14 @@ Token rule: Card uses surface for its background. Never use bgBase or bgSubtle o
335
335
  onChange={setTags}
336
336
  max={3}
337
337
  placeholder="Up to 3 tags"
338
- />`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Option labels, empty state, and max hint",required:!0}],accessibility:{role:"combobox",ariaAttributes:["aria-autocomplete","aria-controls","aria-expanded","aria-multiselectable","aria-selected","aria-disabled"],keyboardInteractions:["↑↓ to navigate options","Enter to toggle selection","Escape to close","Backspace to remove last tag"],notes:'The input carries role="combobox" with aria-expanded and aria-controls pointing to the listbox. Each option has role="option" with aria-selected. Remove buttons on tags have descriptive aria-label.'}};function ir(e,n){return new Date(e,n+1,0).getDate()}function sr(e,n){return new Date(e,n,1).getDay()}function be(e,n){return e.getFullYear()===n.getFullYear()&&e.getMonth()===n.getMonth()&&e.getDate()===n.getDate()}function Te(e,n){return new Date(e.getFullYear(),e.getMonth(),e.getDate())<new Date(n.getFullYear(),n.getMonth(),n.getDate())}function rt(e,n){return new Date(e.getFullYear(),e.getMonth(),e.getDate())>new Date(n.getFullYear(),n.getMonth(),n.getDate())}const lr=["January","February","March","April","May","June","July","August","September","October","November","December"],cr=["Su","Mo","Tu","We","Th","Fr","Sa"];function le(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function ot({dir:e,onClick:n,disabled:a}){const[o,r]=p.useState(!1);return t.jsx("button",{type:"button",onClick:n,disabled:a,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),"aria-label":e==="prev"?"Previous month":"Next month",style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:28,height:28,border:"none",borderRadius:"var(--lucent-radius-md)",background:o&&!a?"var(--lucent-surface-secondary)":"transparent",color:a?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",cursor:a?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast)"},children:t.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:e==="prev"?"M10 12L6 8l4-4":"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})}function je({year:e,month:n,selected:a,today:o,min:r,max:i,onSelect:s,onPrevMonth:l,onNextMonth:c,highlightRange:u}){const f=ir(e,n),d=sr(e,n),[y,h]=p.useState(null),w=[...Array(d).fill(null),...Array.from({length:f},(v,g)=>g+1)];for(;w.length%7!==0;)w.push(null);return t.jsxs("div",{children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"var(--lucent-space-3)"},children:[t.jsx(ot,{dir:"prev",onClick:l}),t.jsxs(B,{weight:"medium",size:"sm",children:[lr[n]," ",e]}),t.jsx(ot,{dir:"next",onClick:c})]}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(7, 1fr)",gap:2,marginBottom:"var(--lucent-space-1)"},children:cr.map(v=>t.jsx("div",{style:{textAlign:"center"},children:t.jsx(B,{size:"xs",color:"secondary",children:v})},v))}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(7, 1fr)",gap:2},children:w.map((v,g)=>{if(!v)return t.jsx("div",{},g);const b=new Date(e,n,v),k=a?be(b,a):!1,D=be(b,o),S=(r?Te(b,r):!1)||(i?rt(b,i):!1);let x=!1;return u!=null&&u.start&&(u!=null&&u.end)&&(x=!Te(b,u.start)&&!rt(b,u.end)),t.jsx("button",{type:"button",disabled:S,onClick:()=>!S&&s(b),onMouseEnter:()=>h(v),onMouseLeave:()=>h(null),"aria-label":le(b),"aria-pressed":k,style:{display:"flex",alignItems:"center",justifyContent:"center",height:32,width:"100%",border:D&&!k?"1px solid var(--lucent-border-strong)":"1px solid transparent",borderRadius:"var(--lucent-radius-md)",background:k?"var(--lucent-accent-default)":x?"var(--lucent-accent-subtle)":y===v&&!S?"var(--lucent-surface-secondary)":"transparent",color:k?"var(--lucent-text-on-accent)":S?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontSize:"var(--lucent-font-size-sm)",fontFamily:"var(--lucent-font-family-base)",fontWeight:D?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",cursor:S?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast)"},children:v},g)})})]})}function dr({value:e,defaultValue:n,onChange:a,placeholder:o="Pick a date",disabled:r=!1,min:i,max:s,style:l}){const c=e!==void 0,[u,f]=p.useState(n),d=c?e:u,y=new Date,[h,w]=p.useState((d??y).getFullYear()),[v,g]=p.useState((d??y).getMonth()),[b,k]=p.useState(!1),[D,S]=p.useState(!1),x=p.useRef(null);p.useEffect(()=>{if(!b)return;const C=V=>{var R;(R=x.current)!=null&&R.contains(V.target)||k(!1)};return document.addEventListener("mousedown",C),()=>document.removeEventListener("mousedown",C)},[b]);const z=C=>{c||f(C),a==null||a(C),k(!1)},q=()=>{v===0?(g(11),w(C=>C-1)):g(C=>C-1)},T=()=>{v===11?(g(0),w(C=>C+1)):g(C=>C+1)};return t.jsxs("div",{ref:x,style:{position:"relative",display:"inline-block",...l},children:[t.jsxs("button",{type:"button",disabled:r,onClick:()=>!r&&k(C=>!C),onFocus:()=>S(!0),onBlur:()=>S(!1),"aria-haspopup":"dialog","aria-expanded":b,style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-2) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:`1px solid ${D?"var(--lucent-accent-default)":"var(--lucent-border-default)"}`,background:r?"var(--lucent-surface-secondary)":"var(--lucent-surface)",color:d?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",cursor:r?"not-allowed":"pointer",outline:D?"2px solid var(--lucent-focus-ring)":"none",outlineOffset:2,minWidth:160,transition:"border-color var(--lucent-duration-fast)"},children:[t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":!0,style:{flexShrink:0},children:[t.jsx("rect",{x:"1",y:"2",width:"12",height:"11",rx:"2",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M1 6h12",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M4 1v2M10 1v2",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round"})]}),t.jsx("span",{style:{flex:1,textAlign:"left"},children:d?le(d):o})]}),b&&t.jsx("div",{role:"dialog","aria-label":"Date picker",style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:1e3,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"var(--lucent-shadow-md)",padding:"var(--lucent-space-4)",minWidth:260},children:t.jsx(je,{year:h,month:v,...d!==void 0&&{selected:d},today:y,...i!==void 0&&{min:i},...s!==void 0&&{max:s},onSelect:z,onPrevMonth:q,onNextMonth:T})})]})}const ur={id:"date-picker",name:"DatePicker",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A single-date picker with a calendar popover, month navigation, today highlight, min/max constraints, and controlled or uncontrolled modes.",designIntent:`DatePicker deliberately avoids native <input type="date"> to guarantee consistent cross-browser appearance that matches the Lucent token system. The trigger button shows the selected date in YYYY-MM-DD format (ISO-sortable, unambiguous locale-wise) or a placeholder. The calendar popover renders as a role="dialog" and closes on outside click. Today is outlined rather than filled so it doesn't compete visually with the selected date. Disabled dates (outside min/max) are grayed out and non-interactive. The Calendar primitive is exported separately so DateRangePicker can compose two calendars side by side.`,props:[{name:"value",type:"object",required:!1,description:"Controlled selected Date. When provided the component is fully controlled."},{name:"defaultValue",type:"object",required:!1,description:"Initial selected Date for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called with the newly selected Date when the user picks a day."},{name:"placeholder",type:"string",required:!1,default:'"Pick a date"',description:"Trigger button text when no date is selected."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the trigger button and all interaction."},{name:"min",type:"object",required:!1,description:"Earliest selectable Date. Days before this are grayed out."},{name:"max",type:"object",required:!1,description:"Latest selectable Date. Days after this are grayed out."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled",code:"<DatePicker onChange={(d) => console.log(d)} />"},{title:"Controlled with constraints",code:`const [date, setDate] = useState<Date>();
338
+ />`}],compositionGraph:[{componentId:"tag",componentName:"Tag",role:"Selected value chips with dismiss button",required:!0},{componentId:"checkbox",componentName:"Checkbox",role:"Selection indicator in dropdown options",required:!0},{componentId:"text",componentName:"Text",role:"Option labels, empty state, and max hint",required:!0}],accessibility:{role:"combobox",ariaAttributes:["aria-autocomplete","aria-controls","aria-expanded","aria-multiselectable","aria-selected","aria-disabled"],keyboardInteractions:["↑↓ to navigate options","Enter to toggle selection","Escape to close","Backspace to remove last tag"],notes:'The input carries role="combobox" with aria-expanded and aria-controls pointing to the listbox. Each option has role="option" with aria-selected. Remove buttons on tags have descriptive aria-label.'}};function cr(e,n){return new Date(e,n+1,0).getDate()}function dr(e,n){return new Date(e,n,1).getDay()}function be(e,n){return e.getFullYear()===n.getFullYear()&&e.getMonth()===n.getMonth()&&e.getDate()===n.getDate()}function ve(e,n){return new Date(e.getFullYear(),e.getMonth(),e.getDate())<new Date(n.getFullYear(),n.getMonth(),n.getDate())}function rt(e,n){return new Date(e.getFullYear(),e.getMonth(),e.getDate())>new Date(n.getFullYear(),n.getMonth(),n.getDate())}const ur=["January","February","March","April","May","June","July","August","September","October","November","December"],pr=["Su","Mo","Tu","We","Th","Fr","Sa"];function le(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}const fr={sm:32,md:40,lg:46},hr={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-md)"};function ot({dir:e,onClick:n,disabled:a}){const[o,r]=f.useState(!1);return t.jsx("button",{type:"button",onClick:n,disabled:a,onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),"aria-label":e==="prev"?"Previous month":"Next month",style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:28,height:28,border:"none",borderRadius:"var(--lucent-radius-md)",background:o&&!a?"var(--lucent-surface-secondary)":"transparent",color:a?"var(--lucent-text-disabled)":"var(--lucent-text-secondary)",cursor:a?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast)"},children:t.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:e==="prev"?"M10 12L6 8l4-4":"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})}function je({year:e,month:n,selected:a,today:o,min:r,max:i,onSelect:s,onPrevMonth:l,onNextMonth:c,highlightRange:d,onDayHover:p}){const m=cr(e,n),h=dr(e,n),[u,S]=f.useState(null),y=[...Array(h).fill(null),...Array.from({length:m},(b,v)=>v+1)];for(;y.length%7!==0;)y.push(null);return t.jsxs("div",{children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"var(--lucent-space-3)"},children:[t.jsx(ot,{dir:"prev",onClick:l}),t.jsxs(P,{weight:"medium",size:"sm",children:[ur[n]," ",e]}),t.jsx(ot,{dir:"next",onClick:c})]}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(7, 1fr)",gap:2,marginBottom:"var(--lucent-space-1)"},children:pr.map(b=>t.jsx("div",{style:{textAlign:"center"},children:t.jsx(P,{size:"xs",color:"secondary",children:b})},b))}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(7, 1fr)",gap:2},children:y.map((b,v)=>{if(!b)return t.jsx("div",{},v);const w=new Date(e,n,b),j=a?be(w,a):!1,T=be(w,o),x=(r?ve(w,r):!1)||(i?rt(w,i):!1);let M=!1;return d!=null&&d.start&&(d!=null&&d.end)&&(M=!ve(w,d.start)&&!rt(w,d.end)),t.jsx("button",{type:"button",disabled:x,onClick:()=>!x&&s(w),onMouseEnter:()=>{S(b),p==null||p(w)},onMouseLeave:()=>{S(null),p==null||p(null)},"aria-label":le(w),"aria-pressed":j,style:{display:"flex",alignItems:"center",justifyContent:"center",height:32,width:"100%",border:T&&!j?"1px solid var(--lucent-border-strong)":"1px solid transparent",borderRadius:"var(--lucent-radius-md)",background:j?"var(--lucent-accent-default)":M?"var(--lucent-accent-subtle)":u===b&&!x?"var(--lucent-surface-secondary)":"transparent",color:j?"var(--lucent-text-on-accent)":x?"var(--lucent-text-disabled)":"var(--lucent-text-primary)",fontSize:"var(--lucent-font-size-sm)",fontFamily:"var(--lucent-font-family-base)",fontWeight:T?"var(--lucent-font-weight-medium)":"var(--lucent-font-weight-regular)",cursor:x?"not-allowed":"pointer",transition:"background var(--lucent-duration-fast)"},children:b},v)})})]})}function mr({value:e,defaultValue:n,onChange:a,placeholder:o="Pick a date",disabled:r=!1,min:i,max:s,size:l="md",style:c}){const d=e!==void 0,[p,m]=f.useState(n),h=d?e:p,u=new Date,[S,y]=f.useState((h??u).getFullYear()),[b,v]=f.useState((h??u).getMonth()),[w,j]=f.useState(!1),[T,x]=f.useState(!1),M=f.useRef(null);f.useEffect(()=>{if(!w)return;const q=E=>{var C;(C=M.current)!=null&&C.contains(E.target)||j(!1)};return document.addEventListener("mousedown",q),()=>document.removeEventListener("mousedown",q)},[w]);const F=q=>{d||m(q),a==null||a(q),j(!1)},k=()=>{b===0?(v(11),y(q=>q-1)):v(q=>q-1)},z=()=>{b===11?(v(0),y(q=>q+1)):v(q=>q+1)};return t.jsxs("div",{ref:M,style:{position:"relative",...c},children:[t.jsxs("button",{type:"button",disabled:r,onClick:()=>!r&&j(q=>!q),onFocus:()=>x(!0),onBlur:()=>x(!1),"aria-haspopup":"dialog","aria-expanded":w,style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",width:"100%",height:fr[l],boxSizing:"content-box",padding:"0 var(--lucent-space-3)",borderRadius:"var(--lucent-radius-lg)",border:`1px solid ${T?"var(--lucent-accent-default)":"var(--lucent-border-default)"}`,background:r?"var(--lucent-surface-secondary)":"var(--lucent-surface)",color:h?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:hr[l],cursor:r?"not-allowed":"pointer",outline:T?"2px solid var(--lucent-focus-ring)":"none",outlineOffset:2,transition:"border-color var(--lucent-duration-fast)"},children:[t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":!0,style:{flexShrink:0},children:[t.jsx("rect",{x:"1",y:"2",width:"12",height:"11",rx:"2",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M1 6h12",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M4 1v2M10 1v2",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round"})]}),t.jsx("span",{style:{flex:1,textAlign:"left"},children:h?le(h):o})]}),w&&t.jsx("div",{role:"dialog","aria-label":"Date picker",style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:1e3,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"var(--lucent-shadow-md)",padding:"var(--lucent-space-4)",minWidth:260},children:t.jsx(je,{year:S,month:b,...h!==void 0&&{selected:h},today:u,...i!==void 0&&{min:i},...s!==void 0&&{max:s},onSelect:F,onPrevMonth:k,onNextMonth:z})})]})}const gr={id:"date-picker",name:"DatePicker",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A single-date picker with a calendar popover, month navigation, today highlight, min/max constraints, and controlled or uncontrolled modes.",designIntent:`DatePicker deliberately avoids native <input type="date"> to guarantee consistent cross-browser appearance that matches the Lucent token system. The trigger button shows the selected date in YYYY-MM-DD format (ISO-sortable, unambiguous locale-wise) or a placeholder. The calendar popover renders as a role="dialog" and closes on outside click. Today is outlined rather than filled so it doesn't compete visually with the selected date. Disabled dates (outside min/max) are grayed out and non-interactive. The Calendar primitive is exported separately so DateRangePicker can compose two calendars side by side.`,props:[{name:"value",type:"object",required:!1,description:"Controlled selected Date. When provided the component is fully controlled."},{name:"defaultValue",type:"object",required:!1,description:"Initial selected Date for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called with the newly selected Date when the user picks a day."},{name:"placeholder",type:"string",required:!1,default:'"Pick a date"',description:"Trigger button text when no date is selected."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls trigger height and font size to match Input/Select.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the trigger button and all interaction."},{name:"min",type:"object",required:!1,description:"Earliest selectable Date. Days before this are grayed out."},{name:"max",type:"object",required:!1,description:"Latest selectable Date. Days after this are grayed out."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled",code:"<DatePicker onChange={(d) => console.log(d)} />"},{title:"Controlled with constraints",code:`const [date, setDate] = useState<Date>();
339
339
  <DatePicker
340
340
  value={date}
341
341
  onChange={setDate}
342
342
  min={new Date()}
343
343
  placeholder="Select a future date"
344
- />`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Month/year header and weekday labels",required:!0}],accessibility:{role:"dialog",ariaAttributes:["aria-haspopup","aria-expanded","aria-label","aria-pressed"],keyboardInteractions:["Enter/Space to open calendar","Click day to select","Escape closes popover (click outside)"],notes:'The calendar popover is role="dialog". Each day button has aria-label with the full date and aria-pressed for selected state. Full arrow-key navigation within the calendar grid is a planned enhancement.'}};function pr(e,n){return e?be(e.start,e.end)?le(e.start):`${le(e.start)} → ${le(e.end)}`:n}function fr({value:e,defaultValue:n,onChange:a,placeholder:o="Pick a date range",disabled:r=!1,min:i,max:s,style:l}){const c=e!==void 0,[u,f]=p.useState(n),d=c?e:u,[y,h]=p.useState(null),w=new Date,[v,g]=p.useState(((d==null?void 0:d.start)??w).getFullYear()),[b,k]=p.useState(((d==null?void 0:d.start)??w).getMonth()),D=b===11?0:b+1,S=b===11?v+1:v,[x,z]=p.useState(!1),[q,T]=p.useState(!1),C=p.useRef(null);p.useEffect(()=>{if(!x)return;const M=P=>{var G;(G=C.current)!=null&&G.contains(P.target)||(z(!1),h(null))};return document.addEventListener("mousedown",M),()=>document.removeEventListener("mousedown",M)},[x]);const V=M=>{if(!y)h(M);else{const[P,G]=Te(M,y)||be(M,y)?[M,y]:[y,M],H={start:P,end:G};c||f(H),a==null||a(H),h(null),z(!1)}},R=()=>{b===0?(k(11),g(M=>M-1)):k(M=>M-1)},I=()=>{b===11?(k(0),g(M=>M+1)):k(M=>M+1)},j=y?{start:y,end:y}:d?{start:d.start,end:d.end}:void 0;return t.jsxs("div",{ref:C,style:{position:"relative",display:"inline-block",...l},children:[t.jsxs("button",{type:"button",disabled:r,onClick:()=>!r&&z(M=>!M),onFocus:()=>T(!0),onBlur:()=>T(!1),"aria-haspopup":"dialog","aria-expanded":x,style:{display:"inline-flex",alignItems:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-2) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:`1px solid ${q?"var(--lucent-accent-default)":"var(--lucent-border-default)"}`,background:r?"var(--lucent-surface-secondary)":"var(--lucent-surface)",color:d?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:"var(--lucent-font-size-sm)",cursor:r?"not-allowed":"pointer",outline:q?"2px solid var(--lucent-focus-ring)":"none",outlineOffset:2,minWidth:220,transition:"border-color var(--lucent-duration-fast)"},children:[t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":!0,style:{flexShrink:0},children:[t.jsx("rect",{x:"1",y:"2",width:"12",height:"11",rx:"2",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M1 6h12",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M4 1v2M10 1v2",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round"})]}),t.jsx("span",{style:{flex:1,textAlign:"left"},children:pr(d,o)})]}),x&&t.jsxs("div",{role:"dialog","aria-label":"Date range picker",style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:1e3,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"var(--lucent-shadow-md)",padding:"var(--lucent-space-4)",display:"flex",gap:"var(--lucent-space-6)"},children:[t.jsx("div",{style:{minWidth:220},children:t.jsx(je,{year:v,month:b,...(d==null?void 0:d.start)!==void 0&&{selected:d.start},today:w,...i!==void 0&&{min:i},...s!==void 0&&{max:s},onSelect:V,onPrevMonth:R,onNextMonth:I,...j!==void 0&&{highlightRange:j}})}),t.jsx("div",{style:{width:1,background:"var(--lucent-border-subtle)",flexShrink:0}}),t.jsx("div",{style:{minWidth:220},children:t.jsx(je,{year:S,month:D,...(d==null?void 0:d.end)!==void 0&&{selected:d.end},today:w,...i!==void 0&&{min:i},...s!==void 0&&{max:s},onSelect:V,onPrevMonth:R,onNextMonth:I,...j!==void 0&&{highlightRange:j}})})]}),y&&x&&t.jsx("div",{style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:1001,pointerEvents:"none"}}),y&&x&&t.jsx("div",{style:{position:"absolute",bottom:-24,left:0},children:t.jsx(B,{size:"xs",color:"secondary",children:"Now pick the end date"})})]})}const hr={id:"date-range-picker",name:"DateRangePicker",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A two-calendar date range picker. First click sets the start date, second click sets the end; the selected interval is highlighted across both calendars.",designIntent:'DateRangePicker composes two Calendar primitives from DatePicker side by side, advancing in lockstep (left = current month, right = next month). Selection is a two-click flow: first click anchors the start, a hint appears ("Now pick the end date"), second click resolves the range with automatic start/end ordering so users can click in either direction. The highlight range (accent-subtle background) spans both calendars to give clear visual feedback for the selected interval. Navigation (prev/next month) advances both calendars together to maintain the one-month-apart constraint.',props:[{name:"value",type:"object",required:!1,description:"Controlled DateRange { start: Date; end: Date }. When provided the component is fully controlled."},{name:"defaultValue",type:"object",required:!1,description:"Initial DateRange for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called with the completed DateRange after the user picks both start and end."},{name:"placeholder",type:"string",required:!1,default:'"Pick a date range"',description:"Trigger button text when no range is selected."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the trigger button and all interaction."},{name:"min",type:"object",required:!1,description:"Earliest selectable Date."},{name:"max",type:"object",required:!1,description:"Latest selectable Date."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled",code:"<DateRangePicker onChange={({ start, end }) => console.log(start, end)} />"},{title:"Controlled",code:`const [range, setRange] = useState<DateRange>();
345
- <DateRangePicker value={range} onChange={setRange} min={new Date()} />`}],compositionGraph:[{componentId:"date-picker",componentName:"DatePicker",role:"Calendar primitive (two instances, left and right)",required:!0},{componentId:"text",componentName:"Text",role:"Mid-selection hint and calendar headers",required:!0}],accessibility:{role:"dialog",ariaAttributes:["aria-haspopup","aria-expanded","aria-label","aria-pressed"],keyboardInteractions:["Enter/Space to open","Click first day to set start","Click second day to set end","Escape/click outside to cancel"],notes:'Inherits Calendar accessibility from DatePicker. The two-step selection flow is reinforced with a visible "Now pick the end date" hint.'}};function Ce(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function mr(){return Math.random().toString(36).slice(2)}function gr({item:e,onRemove:n}){const[a,o]=p.useState(!1),r=e.progress,i=!!e.error;return t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-2) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:`1px solid ${i?"var(--lucent-danger-default)":"var(--lucent-border-default)"}`,background:"var(--lucent-surface)"},children:[t.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none","aria-hidden":!0,style:{flexShrink:0,color:"var(--lucent-text-secondary)"},children:[t.jsx("path",{d:"M5 2h7l4 4v12a1 1 0 01-1 1H5a1 1 0 01-1-1V3a1 1 0 011-1z",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M12 2v4h4",stroke:"currentColor",strokeWidth:"1.3"})]}),t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx(B,{size:"sm",truncate:!0,children:e.file.name}),i?t.jsx(B,{size:"xs",color:"danger",children:e.error}):t.jsx(B,{size:"xs",color:"secondary",children:Ce(e.file.size)}),r!==void 0&&!i&&t.jsx("div",{style:{marginTop:4,height:3,borderRadius:"var(--lucent-radius-full)",background:"var(--lucent-surface-secondary)",overflow:"hidden"},children:t.jsx("div",{style:{height:"100%",width:`${r}%`,borderRadius:"var(--lucent-radius-full)",background:r===100?"var(--lucent-success-default)":"var(--lucent-accent-default)",transition:"width 200ms var(--lucent-easing-default)"}})})]}),t.jsx("button",{type:"button",onClick:()=>n(e.id),onMouseEnter:()=>o(!0),onMouseLeave:()=>o(!1),"aria-label":`Remove ${e.file.name}`,style:{flexShrink:0,display:"inline-flex",alignItems:"center",justifyContent:"center",width:24,height:24,border:"none",borderRadius:"var(--lucent-radius-md)",background:a?"var(--lucent-surface-secondary)":"transparent",color:"var(--lucent-text-secondary)",cursor:"pointer",transition:"background var(--lucent-duration-fast)"},children:t.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M2 2l8 8M10 2l-8 8",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]})}function br({accept:e,multiple:n=!1,maxSize:a,value:o,onChange:r,onError:i,disabled:s=!1,style:l}){const c=o!==void 0,[u,f]=p.useState([]),d=c?o:u,[y,h]=p.useState(!1),[w,v]=p.useState(!1),g=p.useRef(null),b=p.useCallback(x=>{if(!x||s)return;const z=[];for(const T of Array.from(x)){if(a&&T.size>a){i==null||i(`"${T.name}" exceeds the ${Ce(a)} limit.`);continue}if(!n&&d.length+z.length>=1)break;z.push({id:mr(),file:T})}if(z.length===0)return;const q=n?[...d,...z]:z;c||f(q),r==null||r(q)},[s,d,c,a,n,r,i]),k=x=>{const z=d.filter(q=>q.id!==x);c||f(z),r==null||r(z)},D=x=>{x.preventDefault(),h(!1),b(x.dataTransfer.files)},S=x=>{b(x.target.files),x.target.value=""};return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-3)",...l},children:[t.jsxs("div",{role:"button",tabIndex:s?-1:0,"aria-label":"Upload files","aria-disabled":s,onClick:()=>{var x;return!s&&((x=g.current)==null?void 0:x.click())},onKeyDown:x=>{var z;(x.key==="Enter"||x.key===" ")&&(x.preventDefault(),(z=g.current)==null||z.click())},onFocus:()=>v(!0),onBlur:()=>v(!1),onDragOver:x=>{x.preventDefault(),s||h(!0)},onDragLeave:()=>h(!1),onDrop:D,style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-8) var(--lucent-space-6)",borderRadius:"var(--lucent-radius-lg)",border:`2px dashed ${s?"var(--lucent-border-default)":y||w?"var(--lucent-accent-default)":"var(--lucent-border-default)"}`,background:y?"var(--lucent-accent-subtle)":"var(--lucent-surface-secondary)",cursor:s?"not-allowed":"pointer",transition:"border-color var(--lucent-duration-fast), background var(--lucent-duration-fast)",outline:"none"},children:[t.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 32 32",fill:"none","aria-hidden":!0,style:{color:s?"var(--lucent-text-disabled)":y?"var(--lucent-accent-default)":"var(--lucent-text-secondary)"},children:[t.jsx("path",{d:"M16 20V10M16 10l-4 4M16 10l4 4",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M8 24h16",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round"})]}),t.jsxs("div",{style:{textAlign:"center"},children:[t.jsx(B,{color:s?"disabled":"primary",weight:"medium",children:y?"Drop to upload":"Drop files here or click to browse"}),(e||a)&&t.jsx(B,{size:"xs",color:"secondary",children:[e&&`Accepted: ${e}`,a&&`Max size: ${Ce(a)}`].filter(Boolean).join(" · ")})]}),t.jsx("input",{ref:g,type:"file",accept:e,multiple:n,disabled:s,onChange:S,style:{display:"none"},tabIndex:-1})]}),d.length>0&&t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)"},children:d.map(x=>t.jsx(gr,{item:x,onRemove:k},x.id))})]})}const vr={id:"file-upload",name:"FileUpload",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A drag-and-drop file upload zone with a file list, per-file progress bars, error display, and size/type validation.",designIntent:'FileUpload separates concerns between the drop zone (entry point) and the file list (status display). The drop zone uses a dashed border and an upload arrow icon to communicate droppability without words. Progress is modelled as a field on UploadFile rather than as a callback so the parent controls upload logic — this component is purely presentational for the upload state. The progress bar turns success-green at 100% to give clear completion feedback. Errors are shown inline on each file row (not as a toast) so the user knows exactly which file failed and why. The hidden <input type="file"> is triggered programmatically on click/keyboard so the drop zone can have a fully custom appearance.',props:[{name:"accept",type:"string",required:!1,description:'Accepted MIME types or extensions passed to the file input, e.g. "image/*,.pdf".'},{name:"multiple",type:"boolean",required:!1,default:"false",description:"Allow selecting multiple files at once."},{name:"maxSize",type:"number",required:!1,description:"Maximum file size in bytes. Files exceeding this trigger onError and are not added."},{name:"value",type:"array",required:!1,description:"Controlled array of UploadFile objects. Each has id, file (File), optional progress (0–100), and optional error string."},{name:"onChange",type:"function",required:!1,description:"Called with the updated UploadFile array after files are added or removed."},{name:"onError",type:"function",required:!1,description:"Called with an error message string when a file fails validation (e.g. exceeds maxSize)."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the drop zone and all file interaction."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled multi-file upload",code:`<FileUpload
344
+ />`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Month/year header and weekday labels",required:!0}],accessibility:{role:"dialog",ariaAttributes:["aria-haspopup","aria-expanded","aria-label","aria-pressed"],keyboardInteractions:["Enter/Space to open calendar","Click day to select","Escape closes popover (click outside)"],notes:'The calendar popover is role="dialog". Each day button has aria-label with the full date and aria-pressed for selected state. Full arrow-key navigation within the calendar grid is a planned enhancement.'}},br={sm:32,md:40,lg:46},vr={sm:"var(--lucent-font-size-sm)",md:"var(--lucent-font-size-md)",lg:"var(--lucent-font-size-md)"};function yr(e,n){return e?be(e.start,e.end)?le(e.start):`${le(e.start)} → ${le(e.end)}`:n}function xr({value:e,defaultValue:n,onChange:a,placeholder:o="Pick a date range",disabled:r=!1,min:i,max:s,size:l="md",style:c}){const d=e!==void 0,[p,m]=f.useState(n),h=d?e:p,[u,S]=f.useState(null),[y,b]=f.useState(null),v=new Date,[w,j]=f.useState(((h==null?void 0:h.start)??v).getFullYear()),[T,x]=f.useState(((h==null?void 0:h.start)??v).getMonth()),M=T===11?0:T+1,F=T===11?w+1:w,[k,z]=f.useState(!1),[q,E]=f.useState(!1),C=f.useRef(null);f.useEffect(()=>{if(!k)return;const N=G=>{var U;(U=C.current)!=null&&U.contains(G.target)||(z(!1),S(null))};return document.addEventListener("mousedown",N),()=>document.removeEventListener("mousedown",N)},[k]);const R=N=>{if(!u)S(N);else{const[G,U]=ve(N,u)||be(N,u)?[N,u]:[u,N],g={start:G,end:U};d||m(g),a==null||a(g),S(null),z(!1)}},I=()=>{T===0?(x(11),j(N=>N-1)):x(N=>N-1)},L=()=>{T===11?(x(0),j(N=>N+1)):x(N=>N+1)};let W;if(u&&y){const[N,G]=ve(y,u)?[y,u]:[u,y];W={start:N,end:G}}else u?W={start:u,end:u}:h&&(W={start:h.start,end:h.end});return t.jsxs("div",{ref:C,style:{position:"relative",...c},children:[t.jsxs("button",{type:"button",disabled:r,onClick:()=>!r&&z(N=>!N),onFocus:()=>E(!0),onBlur:()=>E(!1),"aria-haspopup":"dialog","aria-expanded":k,style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-2)",width:"100%",height:br[l],boxSizing:"content-box",padding:"0 var(--lucent-space-3)",borderRadius:"var(--lucent-radius-lg)",border:`1px solid ${q?"var(--lucent-accent-default)":"var(--lucent-border-default)"}`,background:r?"var(--lucent-surface-secondary)":"var(--lucent-surface)",color:h?"var(--lucent-text-primary)":"var(--lucent-text-secondary)",fontFamily:"var(--lucent-font-family-base)",fontSize:vr[l],cursor:r?"not-allowed":"pointer",outline:q?"2px solid var(--lucent-focus-ring)":"none",outlineOffset:2,transition:"border-color var(--lucent-duration-fast)"},children:[t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":!0,style:{flexShrink:0},children:[t.jsx("rect",{x:"1",y:"2",width:"12",height:"11",rx:"2",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M1 6h12",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M4 1v2M10 1v2",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round"})]}),t.jsx("span",{style:{flex:1,textAlign:"left"},children:yr(h,o)})]}),k&&t.jsxs("div",{role:"dialog","aria-label":"Date range picker",style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:1e3,background:"var(--lucent-surface-overlay)",border:"1px solid var(--lucent-border-default)",borderRadius:"var(--lucent-radius-lg)",boxShadow:"var(--lucent-shadow-md)",padding:"var(--lucent-space-4)",display:"flex",gap:"var(--lucent-space-6)"},children:[t.jsx("div",{style:{minWidth:220},children:t.jsx(je,{year:w,month:T,...(h==null?void 0:h.start)!==void 0&&{selected:h.start},today:v,...i!==void 0&&{min:i},...s!==void 0&&{max:s},onSelect:R,onPrevMonth:I,onNextMonth:L,...W!==void 0&&{highlightRange:W},...u&&{onDayHover:b}})}),t.jsx("div",{style:{width:1,background:"var(--lucent-border-subtle)",flexShrink:0}}),t.jsx("div",{style:{minWidth:220},children:t.jsx(je,{year:F,month:M,...(h==null?void 0:h.end)!==void 0&&{selected:h.end},today:v,...i!==void 0&&{min:i},...s!==void 0&&{max:s},onSelect:R,onPrevMonth:I,onNextMonth:L,...W!==void 0&&{highlightRange:W},...u&&{onDayHover:b}})})]}),u&&k&&t.jsx("div",{style:{position:"absolute",top:"calc(100% + 4px)",left:0,zIndex:1001,pointerEvents:"none"}}),u&&k&&t.jsx("div",{style:{position:"absolute",bottom:-24,left:0},children:t.jsx(P,{size:"xs",color:"secondary",children:"Now pick the end date"})})]})}const wr={id:"date-range-picker",name:"DateRangePicker",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A two-calendar date range picker. First click sets the start date, second click sets the end; the selected interval is highlighted across both calendars.",designIntent:'DateRangePicker composes two Calendar primitives from DatePicker side by side, advancing in lockstep (left = current month, right = next month). Selection is a two-click flow: first click anchors the start, a hint appears ("Now pick the end date"), second click resolves the range with automatic start/end ordering so users can click in either direction. The highlight range (accent-subtle background) spans both calendars to give clear visual feedback for the selected interval. Navigation (prev/next month) advances both calendars together to maintain the one-month-apart constraint.',props:[{name:"value",type:"object",required:!1,description:"Controlled DateRange { start: Date; end: Date }. When provided the component is fully controlled."},{name:"defaultValue",type:"object",required:!1,description:"Initial DateRange for uncontrolled usage."},{name:"onChange",type:"function",required:!1,description:"Called with the completed DateRange after the user picks both start and end."},{name:"placeholder",type:"string",required:!1,default:'"Pick a date range"',description:"Trigger button text when no range is selected."},{name:"size",type:"enum",required:!1,default:"md",description:"Controls trigger height and font size to match Input/Select.",enumValues:["sm","md","lg"]},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the trigger button and all interaction."},{name:"min",type:"object",required:!1,description:"Earliest selectable Date."},{name:"max",type:"object",required:!1,description:"Latest selectable Date."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled",code:"<DateRangePicker onChange={({ start, end }) => console.log(start, end)} />"},{title:"Controlled",code:`const [range, setRange] = useState<DateRange>();
345
+ <DateRangePicker value={range} onChange={setRange} min={new Date()} />`}],compositionGraph:[{componentId:"date-picker",componentName:"DatePicker",role:"Calendar primitive (two instances, left and right)",required:!0},{componentId:"text",componentName:"Text",role:"Mid-selection hint and calendar headers",required:!0}],accessibility:{role:"dialog",ariaAttributes:["aria-haspopup","aria-expanded","aria-label","aria-pressed"],keyboardInteractions:["Enter/Space to open","Click first day to set start","Click second day to set end","Escape/click outside to cancel"],notes:'Inherits Calendar accessibility from DatePicker. The two-step selection flow is reinforced with a visible "Now pick the end date" hint.'}};function Ce(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function kr(){return Math.random().toString(36).slice(2)}function Sr({item:e,onRemove:n}){const[a,o]=f.useState(!1),r=e.progress,i=!!e.error;return t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--lucent-space-3)",padding:"var(--lucent-space-2) var(--lucent-space-3)",borderRadius:"var(--lucent-radius-md)",border:`1px solid ${i?"var(--lucent-danger-default)":"var(--lucent-border-default)"}`,background:"var(--lucent-surface)"},children:[t.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none","aria-hidden":!0,style:{flexShrink:0,color:"var(--lucent-text-secondary)"},children:[t.jsx("path",{d:"M5 2h7l4 4v12a1 1 0 01-1 1H5a1 1 0 01-1-1V3a1 1 0 011-1z",stroke:"currentColor",strokeWidth:"1.3"}),t.jsx("path",{d:"M12 2v4h4",stroke:"currentColor",strokeWidth:"1.3"})]}),t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx(P,{size:"sm",truncate:!0,children:e.file.name}),i?t.jsx(P,{size:"xs",color:"danger",children:e.error}):t.jsx(P,{size:"xs",color:"secondary",children:Ce(e.file.size)}),r!==void 0&&!i&&t.jsx("div",{style:{marginTop:4,height:3,borderRadius:"var(--lucent-radius-full)",background:"var(--lucent-surface-secondary)",overflow:"hidden"},children:t.jsx("div",{style:{height:"100%",width:`${r}%`,borderRadius:"var(--lucent-radius-full)",background:r===100?"var(--lucent-success-default)":"var(--lucent-accent-default)",transition:"width 200ms var(--lucent-easing-default)"}})})]}),t.jsx("button",{type:"button",onClick:()=>n(e.id),onMouseEnter:()=>o(!0),onMouseLeave:()=>o(!1),"aria-label":`Remove ${e.file.name}`,style:{flexShrink:0,display:"inline-flex",alignItems:"center",justifyContent:"center",width:24,height:24,border:"none",borderRadius:"var(--lucent-radius-md)",background:a?"var(--lucent-surface-secondary)":"transparent",color:"var(--lucent-text-secondary)",cursor:"pointer",transition:"background var(--lucent-duration-fast)"},children:t.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M2 2l8 8M10 2l-8 8",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]})}function Tr({accept:e,multiple:n=!1,maxSize:a,value:o,onChange:r,onError:i,disabled:s=!1,style:l}){const c=o!==void 0,[d,p]=f.useState([]),m=c?o:d,[h,u]=f.useState(!1),[S,y]=f.useState(!1),b=f.useRef(null),v=f.useCallback(x=>{if(!x||s)return;const M=[];for(const k of Array.from(x)){if(a&&k.size>a){i==null||i(`"${k.name}" exceeds the ${Ce(a)} limit.`);continue}if(!n&&m.length+M.length>=1)break;M.push({id:kr(),file:k})}if(M.length===0)return;const F=n?[...m,...M]:M;c||p(F),r==null||r(F)},[s,m,c,a,n,r,i]),w=x=>{const M=m.filter(F=>F.id!==x);c||p(M),r==null||r(M)},j=x=>{x.preventDefault(),u(!1),v(x.dataTransfer.files)},T=x=>{v(x.target.files),x.target.value=""};return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-3)",...l},children:[t.jsxs("div",{role:"button",tabIndex:s?-1:0,"aria-label":"Upload files","aria-disabled":s,onClick:()=>{var x;return!s&&((x=b.current)==null?void 0:x.click())},onKeyDown:x=>{var M;(x.key==="Enter"||x.key===" ")&&(x.preventDefault(),(M=b.current)==null||M.click())},onFocus:()=>y(!0),onBlur:()=>y(!1),onDragOver:x=>{x.preventDefault(),s||u(!0)},onDragLeave:()=>u(!1),onDrop:j,style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"var(--lucent-space-2)",padding:"var(--lucent-space-8) var(--lucent-space-6)",borderRadius:"var(--lucent-radius-lg)",border:`2px dashed ${s?"var(--lucent-border-default)":h||S?"var(--lucent-accent-default)":"var(--lucent-border-default)"}`,background:h?"var(--lucent-accent-subtle)":"var(--lucent-surface-secondary)",cursor:s?"not-allowed":"pointer",transition:"border-color var(--lucent-duration-fast), background var(--lucent-duration-fast)",outline:"none"},children:[t.jsxs("svg",{width:"32",height:"32",viewBox:"0 0 32 32",fill:"none","aria-hidden":!0,style:{color:s?"var(--lucent-text-disabled)":h?"var(--lucent-accent-default)":"var(--lucent-text-secondary)"},children:[t.jsx("path",{d:"M16 20V10M16 10l-4 4M16 10l4 4",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"}),t.jsx("path",{d:"M8 24h16",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round"})]}),t.jsxs("div",{style:{textAlign:"center"},children:[t.jsx(P,{color:s?"disabled":"primary",weight:"medium",children:h?"Drop to upload":"Drop files here or click to browse"}),(e||a)&&t.jsx(P,{size:"xs",color:"secondary",children:[e&&`Accepted: ${e}`,a&&`Max size: ${Ce(a)}`].filter(Boolean).join(" · ")})]}),t.jsx("input",{ref:b,type:"file",accept:e,multiple:n,disabled:s,onChange:T,style:{display:"none"},tabIndex:-1})]}),m.length>0&&t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"var(--lucent-space-2)"},children:m.map(x=>t.jsx(Sr,{item:x,onRemove:w},x.id))})]})}const jr={id:"file-upload",name:"FileUpload",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A drag-and-drop file upload zone with a file list, per-file progress bars, error display, and size/type validation.",designIntent:'FileUpload separates concerns between the drop zone (entry point) and the file list (status display). The drop zone uses a dashed border and an upload arrow icon to communicate droppability without words. Progress is modelled as a field on UploadFile rather than as a callback so the parent controls upload logic — this component is purely presentational for the upload state. The progress bar turns success-green at 100% to give clear completion feedback. Errors are shown inline on each file row (not as a toast) so the user knows exactly which file failed and why. The hidden <input type="file"> is triggered programmatically on click/keyboard so the drop zone can have a fully custom appearance.',props:[{name:"accept",type:"string",required:!1,description:'Accepted MIME types or extensions passed to the file input, e.g. "image/*,.pdf".'},{name:"multiple",type:"boolean",required:!1,default:"false",description:"Allow selecting multiple files at once."},{name:"maxSize",type:"number",required:!1,description:"Maximum file size in bytes. Files exceeding this trigger onError and are not added."},{name:"value",type:"array",required:!1,description:"Controlled array of UploadFile objects. Each has id, file (File), optional progress (0–100), and optional error string."},{name:"onChange",type:"function",required:!1,description:"Called with the updated UploadFile array after files are added or removed."},{name:"onError",type:"function",required:!1,description:"Called with an error message string when a file fails validation (e.g. exceeds maxSize)."},{name:"disabled",type:"boolean",required:!1,default:"false",description:"Disables the drop zone and all file interaction."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer wrapper."}],usageExamples:[{title:"Uncontrolled multi-file upload",code:`<FileUpload
346
346
  multiple
347
347
  accept="image/*,.pdf"
348
348
  maxSize={5 * 1024 * 1024}
@@ -361,7 +361,7 @@ const handleChange = async (updated: UploadFile[]) => {
361
361
  }
362
362
  };
363
363
 
364
- <FileUpload value={files} onChange={handleChange} multiple />`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Drop zone label, file name, file size, and error messages",required:!0}],accessibility:{role:"button",ariaAttributes:["aria-label","aria-disabled"],keyboardInteractions:["Enter/Space to open file picker","Tab to focus drop zone"],notes:'The drop zone has role="button" with tabIndex=0 and responds to Enter/Space. Remove buttons on file rows have aria-label including the filename.'}},yr={default:"var(--lucent-border-strong)",success:"var(--lucent-success-default)",warning:"var(--lucent-warning-default)",danger:"var(--lucent-danger-default)",info:"var(--lucent-info-default)"},xr={default:"var(--lucent-surface-secondary)",success:"var(--lucent-success-subtle)",warning:"var(--lucent-warning-subtle)",danger:"var(--lucent-danger-subtle)",info:"var(--lucent-info-subtle)"};function wr({status:e}){return e==="success"?t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M2 5l2 2 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}):e==="danger"?t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M2 2l6 6M8 2L2 8",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})}):e==="warning"?t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M5 2v4M5 7.5v.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})}):null}function kr({items:e,style:n}){return t.jsx("ol",{style:{listStyle:"none",margin:0,padding:0,display:"flex",flexDirection:"column",...n},children:e.map((a,o)=>{const r=a.status??"default",i=yr[r],s=xr[r],l=o===e.length-1;return t.jsxs("li",{style:{display:"flex",gap:"var(--lucent-space-4)",position:"relative"},children:[t.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",flexShrink:0,width:28},children:[t.jsx("div",{style:{width:28,height:28,borderRadius:"var(--lucent-radius-full)",border:`2px solid ${i}`,background:s,display:"flex",alignItems:"center",justifyContent:"center",color:i,flexShrink:0,zIndex:1},children:a.icon??t.jsx(wr,{status:r})}),!l&&t.jsx("div",{style:{flex:1,width:2,background:"var(--lucent-border-subtle)",minHeight:"var(--lucent-space-4)",margin:"2px 0"}})]}),t.jsxs("div",{style:{flex:1,paddingBottom:l?0:"var(--lucent-space-6)",paddingTop:4},children:[t.jsxs("div",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"var(--lucent-space-3)",flexWrap:"wrap"},children:[t.jsx(B,{weight:"medium",size:"sm",children:a.title}),a.date&&t.jsx(B,{size:"xs",color:"secondary",children:a.date})]}),a.description&&t.jsx("div",{style:{marginTop:"var(--lucent-space-1)"},children:t.jsx(B,{size:"sm",color:"secondary",children:a.description})})]})]},a.id)})})}const Sr={id:"timeline",name:"Timeline",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A vertical ordered event list with status-colored dots, connector lines, optional dates, and custom icons.",designIntent:"Timeline renders as a semantic <ol> with each event as a <li>, preserving document order for assistive technologies. The dot and connector are rendered in a fixed-width left column so content in the right column can wrap freely without misaligning the spine. The connector line is omitted on the last item — there is nothing to connect to. Status colors follow the same semantic token set as Alert and Badge so danger/success/warning/info carry consistent meaning across the design system. Default status (no explicit icon) renders a plain dot; success/danger/warning get built-in iconography inside the dot. Custom icons slot in via the icon prop to handle domain-specific event types (e.g. a deploy icon, a payment icon).",props:[{name:"items",type:"array",required:!0,description:"Array of TimelineItem objects. Each has id, title, optional description, optional date string, optional status, and optional icon."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer <ol> wrapper."}],usageExamples:[{title:"Basic event log",code:`<Timeline
364
+ <FileUpload value={files} onChange={handleChange} multiple />`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Drop zone label, file name, file size, and error messages",required:!0}],accessibility:{role:"button",ariaAttributes:["aria-label","aria-disabled"],keyboardInteractions:["Enter/Space to open file picker","Tab to focus drop zone"],notes:'The drop zone has role="button" with tabIndex=0 and responds to Enter/Space. Remove buttons on file rows have aria-label including the filename.'}},Cr={default:"var(--lucent-border-strong)",success:"var(--lucent-success-default)",warning:"var(--lucent-warning-default)",danger:"var(--lucent-danger-default)",info:"var(--lucent-info-default)"},Dr={default:"var(--lucent-surface-secondary)",success:"var(--lucent-success-subtle)",warning:"var(--lucent-warning-subtle)",danger:"var(--lucent-danger-subtle)",info:"var(--lucent-info-subtle)"};function Ir({status:e}){return e==="success"?t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M2 5l2 2 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}):e==="danger"?t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M2 2l6 6M8 2L2 8",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})}):e==="warning"?t.jsx("svg",{width:"10",height:"10",viewBox:"0 0 10 10",fill:"none","aria-hidden":!0,children:t.jsx("path",{d:"M5 2v4M5 7.5v.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})}):null}function Mr({items:e,style:n}){return t.jsx("ol",{style:{listStyle:"none",margin:0,padding:0,display:"flex",flexDirection:"column",...n},children:e.map((a,o)=>{const r=a.status??"default",i=Cr[r],s=Dr[r],l=o===e.length-1;return t.jsxs("li",{style:{display:"flex",gap:"var(--lucent-space-4)",position:"relative"},children:[t.jsxs("div",{style:{display:"flex",flexDirection:"column",alignItems:"center",flexShrink:0,width:28},children:[t.jsx("div",{style:{width:28,height:28,borderRadius:"var(--lucent-radius-full)",border:`2px solid ${i}`,background:s,display:"flex",alignItems:"center",justifyContent:"center",color:i,flexShrink:0,zIndex:1},children:a.icon??t.jsx(Ir,{status:r})}),!l&&t.jsx("div",{style:{flex:1,width:2,background:"var(--lucent-border-subtle)",minHeight:"var(--lucent-space-4)",margin:"2px 0"}})]}),t.jsxs("div",{style:{flex:1,paddingBottom:l?0:"var(--lucent-space-6)",paddingTop:4},children:[t.jsxs("div",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:"var(--lucent-space-3)",flexWrap:"wrap"},children:[t.jsx(P,{weight:"medium",size:"sm",children:a.title}),a.date&&t.jsx(P,{size:"xs",color:"secondary",children:a.date})]}),a.description&&t.jsx("div",{style:{marginTop:"var(--lucent-space-1)"},children:t.jsx(P,{size:"sm",color:"secondary",children:a.description})})]})]},a.id)})})}const zr={id:"timeline",name:"Timeline",tier:"molecule",domain:"neutral",specVersion:"1.0",description:"A vertical ordered event list with status-colored dots, connector lines, optional dates, and custom icons.",designIntent:"Timeline renders as a semantic <ol> with each event as a <li>, preserving document order for assistive technologies. The dot and connector are rendered in a fixed-width left column so content in the right column can wrap freely without misaligning the spine. The connector line is omitted on the last item — there is nothing to connect to. Status colors follow the same semantic token set as Alert and Badge so danger/success/warning/info carry consistent meaning across the design system. Default status (no explicit icon) renders a plain dot; success/danger/warning get built-in iconography inside the dot. Custom icons slot in via the icon prop to handle domain-specific event types (e.g. a deploy icon, a payment icon).",props:[{name:"items",type:"array",required:!0,description:"Array of TimelineItem objects. Each has id, title, optional description, optional date string, optional status, and optional icon."},{name:"style",type:"object",required:!1,description:"Inline style overrides for the outer <ol> wrapper."}],usageExamples:[{title:"Basic event log",code:`<Timeline
365
365
  items={[
366
366
  { id: '1', title: 'Order placed', date: 'Mar 1, 2026', status: 'success' },
367
367
  { id: '2', title: 'Payment processed', date: 'Mar 1, 2026', status: 'success' },
@@ -374,11 +374,11 @@ const handleChange = async (updated: UploadFile[]) => {
374
374
  { id: 'review', title: 'PR #47 merged', icon: <GitMergeIcon />, date: '3h ago' },
375
375
  { id: 'alert', title: 'Error rate spike', status: 'warning', icon: <AlertIcon />, date: '4h ago' },
376
376
  ]}
377
- />`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Event title, description, and date label",required:!0}],accessibility:{role:"list",ariaAttributes:[],keyboardInteractions:["Standard document flow — no interactive elements unless custom icons include them"],notes:"Timeline is a semantic <ol> with <li> items. It is non-interactive by default. If items contain interactive elements (links, buttons), those elements carry their own keyboard behaviour."}},Tr={fontFamilyBase:'"DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',fontFamilyMono:'"DM Mono", "Fira Code", "Cascadia Code", monospace',fontFamilyDisplay:'"Georama", "DM Sans", sans-serif',fontSizeXs:"0.75rem",fontSizeSm:"0.875rem",fontSizeMd:"1rem",fontSizeLg:"1.125rem",fontSizeXl:"1.25rem",fontSize2xl:"1.5rem",fontSize3xl:"1.875rem",fontWeightRegular:"400",fontWeightMedium:"500",fontWeightSemibold:"600",fontWeightBold:"700",lineHeightTight:"1.25",lineHeightBase:"1.5",lineHeightRelaxed:"1.75",letterSpacingTight:"-0.02em",letterSpacingBase:"0em",letterSpacingWide:"0.04em"},jr={space0:"0px",space1:"0.25rem",space2:"0.5rem",space3:"0.75rem",space4:"1rem",space5:"1.25rem",space6:"1.5rem",space8:"2rem",space10:"2.5rem",space12:"3rem",space16:"4rem",space20:"5rem",space24:"6rem"},Cr={radiusNone:"0px",radiusSm:"0.25rem",radiusMd:"0.375rem",radiusLg:"0.5rem",radiusXl:"0.75rem",radiusFull:"9999px"},Dr={durationFast:"100ms",durationBase:"200ms",durationSlow:"350ms",easingDefault:"cubic-bezier(0.4, 0, 0.2, 1)",easingEmphasized:"cubic-bezier(0.2, 0, 0, 1)",easingDecelerate:"cubic-bezier(0, 0, 0.2, 1)"},Ir={shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"},Mr={shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.3)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.5)"},ce={...Tr,...jr,...Cr,...Dr,...Ir,bgBase:"#ffffff",bgSubtle:"#f9fafb",bgOverlay:"rgb(0 0 0 / 0.4)",surface:"#ffffff",surfaceSecondary:"#f3f4f6",surfaceRaised:"#ffffff",surfaceOverlay:"#ffffff",borderDefault:"#e5e7eb",borderSubtle:"#f3f4f6",borderStrong:"#9ca3af",textPrimary:"#111827",textSecondary:"#6b7280",textDisabled:"#9ca3af",textInverse:"#ffffff",textOnAccent:"#ffffff",accentDefault:"#111827",accentHover:"#1f2937",accentActive:"#374151",accentSubtle:"#f3f4f6",accentBorder:"#111827",successDefault:"#16a34a",successSubtle:"#f0fdf4",successText:"#15803d",warningDefault:"#d97706",warningSubtle:"#fffbeb",warningText:"#b45309",dangerDefault:"#dc2626",dangerHover:"#b91c1c",dangerSubtle:"#fef2f2",dangerText:"#b91c1c",infoDefault:"#2563eb",infoSubtle:"#eff6ff",infoText:"#1d4ed8",focusRing:"#111827"};function Ar(e){const n=parseInt(e.slice(1,3),16),a=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return{r:n,g:a,b:o}}function zr({r:e,g:n,b:a}){const o=r=>r.toString(16).padStart(2,"0");return`#${o(e)}${o(n)}${o(a)}`}function K(e){const{r:n,g:a,b:o}=Ar(e),r=n/255,i=a/255,s=o/255,l=Math.max(r,i,s),c=Math.min(r,i,s);let u=0,f=0;const d=(l+c)/2;if(l!==c){const y=l-c;switch(f=d>.5?y/(2-l-c):y/(l+c),l){case r:u=(i-s)/y+(i<s?6:0);break;case i:u=(s-r)/y+2;break;case s:u=(r-i)/y+4;break}u/=6}return[u*360,f,d]}function X(e,n,a){e=(e%360+360)%360,n=Math.min(1,Math.max(0,n)),a=Math.min(1,Math.max(0,a));const o=(1-Math.abs(2*a-1))*n,r=o*(1-Math.abs(e/60%2-1)),i=a-o/2;let s=0,l=0,c=0;return e<60?(s=o,l=r):e<120?(s=r,l=o):e<180?(l=o,c=r):e<240?(l=r,c=o):e<300?(s=r,c=o):(s=o,c=r),zr({r:Math.round((s+i)*255),g:Math.round((l+i)*255),b:Math.round((c+i)*255)})}function F(e,n){const[a,o,r]=K(e);return X(a,o,Math.min(1,Math.max(0,r+n)))}const Er=222,Rr=.12;function vt(e,n){return n<.04?[Er,Rr]:[e,n]}function Lr(e){const[n,a,o]=K(e),[r,i]=vt(n,a);return X(r,i,Math.max(.04,Math.min(.2,.07+(1-o))))}function we(e){const[n,a,o]=K(e),[r,i]=vt(n,a);return X(r,i,Math.max(.06,Math.min(.5,(1-o)*.6+.06)))}function ke(e){const[n,a,o]=K(e);return X(n,a,Math.max(.04,Math.min(.97,1-o+.04)))}function ie(e){const[n,a,o]=K(e);return X(n,a,Math.max(.02,Math.min(.98,1-o)))}function yt(e){const n=Lr(e.bgBase),[a,o,r]=K(n),i=s=>X(a,o,Math.min(.25,r+s));return{...e,...Mr,bgBase:n,bgSubtle:i(.02),bgOverlay:"rgb(0 0 0 / 0.6)",surface:i(.02),surfaceSecondary:i(.05),surfaceRaised:i(.08),surfaceOverlay:i(.08),borderDefault:we(e.borderDefault),borderSubtle:we(e.borderSubtle),borderStrong:we(e.borderStrong),textPrimary:ke(e.textPrimary),textSecondary:ke(e.textSecondary),textDisabled:ke(e.textDisabled),textInverse:n,textOnAccent:e.textOnAccent,accentDefault:ie(e.accentDefault),accentHover:ie(e.accentHover),accentActive:ie(e.accentActive),accentSubtle:ie(e.accentSubtle),accentBorder:e.accentBorder,successDefault:F(e.successDefault,.1),successSubtle:F(e.successDefault,-.25),successText:F(e.successText,.15),warningDefault:F(e.warningDefault,.1),warningSubtle:F(e.warningDefault,-.25),warningText:F(e.warningText,.15),dangerDefault:F(e.dangerDefault,.1),dangerHover:F(e.dangerHover,.1),dangerSubtle:F(e.dangerDefault,-.25),dangerText:F(e.dangerText,.15),infoDefault:F(e.infoDefault,.1),infoSubtle:F(e.infoDefault,-.25),infoText:F(e.infoText,.15),focusRing:ie(e.focusRing)}}const Ee=yt(ce);function Br(e){return"--lucent-"+e.replace(/([A-Z])/g,n=>`-${n.toLowerCase()}`).replace(/([a-z])(\d)/g,(n,a,o)=>`${a}-${o}`)}function xt(e,n=":root"){const a=Object.entries(e).map(([o,r])=>` ${Br(o)}: ${r};`).join(`
377
+ />`}],compositionGraph:[{componentId:"text",componentName:"Text",role:"Event title, description, and date label",required:!0}],accessibility:{role:"list",ariaAttributes:[],keyboardInteractions:["Standard document flow — no interactive elements unless custom icons include them"],notes:"Timeline is a semantic <ol> with <li> items. It is non-interactive by default. If items contain interactive elements (links, buttons), those elements carry their own keyboard behaviour."}},Ar={fontFamilyBase:'"DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',fontFamilyMono:'"DM Mono", "Fira Code", "Cascadia Code", monospace',fontFamilyDisplay:'"Georama", "DM Sans", sans-serif',fontSizeXs:"0.75rem",fontSizeSm:"0.875rem",fontSizeMd:"1rem",fontSizeLg:"1.125rem",fontSizeXl:"1.25rem",fontSize2xl:"1.5rem",fontSize3xl:"1.875rem",fontWeightRegular:"400",fontWeightMedium:"500",fontWeightSemibold:"600",fontWeightBold:"700",lineHeightTight:"1.25",lineHeightBase:"1.5",lineHeightRelaxed:"1.75",letterSpacingTight:"-0.02em",letterSpacingBase:"0em",letterSpacingWide:"0.04em"},Er={space0:"0px",space1:"0.25rem",space2:"0.5rem",space3:"0.75rem",space4:"1rem",space5:"1.25rem",space6:"1.5rem",space8:"2rem",space10:"2.5rem",space12:"3rem",space16:"4rem",space20:"5rem",space24:"6rem"},Rr={radiusNone:"0px",radiusSm:"0.25rem",radiusMd:"0.375rem",radiusLg:"0.5rem",radiusXl:"0.75rem",radiusFull:"9999px"},Lr={durationFast:"100ms",durationBase:"200ms",durationSlow:"350ms",easingDefault:"cubic-bezier(0.4, 0, 0.2, 1)",easingEmphasized:"cubic-bezier(0.2, 0, 0, 1)",easingDecelerate:"cubic-bezier(0, 0, 0.2, 1)"},Br={shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"},qr={shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.3)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.5)"},ce={...Ar,...Er,...Rr,...Lr,...Br,bgBase:"#ffffff",bgSubtle:"#f9fafb",bgOverlay:"rgb(0 0 0 / 0.4)",surface:"#ffffff",surfaceSecondary:"#f3f4f6",surfaceRaised:"#ffffff",surfaceOverlay:"#ffffff",borderDefault:"#e5e7eb",borderSubtle:"#f3f4f6",borderStrong:"#9ca3af",textPrimary:"#111827",textSecondary:"#6b7280",textDisabled:"#9ca3af",textInverse:"#ffffff",textOnAccent:"#ffffff",accentDefault:"#111827",accentHover:"#1f2937",accentActive:"#374151",accentSubtle:"#f3f4f6",accentBorder:"#111827",successDefault:"#16a34a",successSubtle:"#f0fdf4",successText:"#15803d",warningDefault:"#d97706",warningSubtle:"#fffbeb",warningText:"#b45309",dangerDefault:"#dc2626",dangerHover:"#b91c1c",dangerSubtle:"#fef2f2",dangerText:"#b91c1c",infoDefault:"#2563eb",infoSubtle:"#eff6ff",infoText:"#1d4ed8",focusRing:"#111827"};function Pr(e){const n=parseInt(e.slice(1,3),16),a=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return{r:n,g:a,b:o}}function Fr({r:e,g:n,b:a}){const o=r=>r.toString(16).padStart(2,"0");return`#${o(e)}${o(n)}${o(a)}`}function X(e){const{r:n,g:a,b:o}=Pr(e),r=n/255,i=a/255,s=o/255,l=Math.max(r,i,s),c=Math.min(r,i,s);let d=0,p=0;const m=(l+c)/2;if(l!==c){const h=l-c;switch(p=m>.5?h/(2-l-c):h/(l+c),l){case r:d=(i-s)/h+(i<s?6:0);break;case i:d=(s-r)/h+2;break;case s:d=(r-i)/h+4;break}d/=6}return[d*360,p,m]}function J(e,n,a){e=(e%360+360)%360,n=Math.min(1,Math.max(0,n)),a=Math.min(1,Math.max(0,a));const o=(1-Math.abs(2*a-1))*n,r=o*(1-Math.abs(e/60%2-1)),i=a-o/2;let s=0,l=0,c=0;return e<60?(s=o,l=r):e<120?(s=r,l=o):e<180?(l=o,c=r):e<240?(l=r,c=o):e<300?(s=r,c=o):(s=o,c=r),Fr({r:Math.round((s+i)*255),g:Math.round((l+i)*255),b:Math.round((c+i)*255)})}function $(e,n){const[a,o,r]=X(e);return J(a,o,Math.min(1,Math.max(0,r+n)))}const Nr=222,$r=.12;function yt(e,n){return n<.04?[Nr,$r]:[e,n]}function Wr(e){const[n,a,o]=X(e),[r,i]=yt(n,a);return J(r,i,Math.max(.04,Math.min(.2,.07+(1-o))))}function ke(e){const[n,a,o]=X(e),[r,i]=yt(n,a);return J(r,i,Math.max(.06,Math.min(.5,(1-o)*.6+.06)))}function Se(e){const[n,a,o]=X(e);return J(n,a,Math.max(.04,Math.min(.97,1-o+.04)))}function ie(e){const[n,a,o]=X(e);return J(n,a,Math.max(.02,Math.min(.98,1-o)))}function xt(e){const n=Wr(e.bgBase),[a,o,r]=X(n),i=s=>J(a,o,Math.min(.25,r+s));return{...e,...qr,bgBase:n,bgSubtle:i(.02),bgOverlay:"rgb(0 0 0 / 0.6)",surface:i(.02),surfaceSecondary:i(.05),surfaceRaised:i(.08),surfaceOverlay:i(.08),borderDefault:ke(e.borderDefault),borderSubtle:ke(e.borderSubtle),borderStrong:ke(e.borderStrong),textPrimary:Se(e.textPrimary),textSecondary:Se(e.textSecondary),textDisabled:Se(e.textDisabled),textInverse:n,textOnAccent:e.textOnAccent,accentDefault:ie(e.accentDefault),accentHover:ie(e.accentHover),accentActive:ie(e.accentActive),accentSubtle:ie(e.accentSubtle),accentBorder:e.accentBorder,successDefault:$(e.successDefault,.1),successSubtle:$(e.successDefault,-.25),successText:$(e.successText,.15),warningDefault:$(e.warningDefault,.1),warningSubtle:$(e.warningDefault,-.25),warningText:$(e.warningText,.15),dangerDefault:$(e.dangerDefault,.1),dangerHover:$(e.dangerHover,.1),dangerSubtle:$(e.dangerDefault,-.25),dangerText:$(e.dangerText,.15),infoDefault:$(e.infoDefault,.1),infoSubtle:$(e.infoDefault,-.25),infoText:$(e.infoText,.15),focusRing:ie(e.focusRing)}}const Ee=xt(ce);function Or(e){return"--lucent-"+e.replace(/([A-Z])/g,n=>`-${n.toLowerCase()}`).replace(/([a-z])(\d)/g,(n,a,o)=>`${a}-${o}`)}function wt(e,n=":root"){const a=Object.entries(e).map(([o,r])=>` ${Or(o)}: ${r};`).join(`
378
378
  `);return`${n} {
379
379
  ${a}
380
- }`}function qr(e){const n=parseInt(e.slice(1,3),16)/255,a=parseInt(e.slice(3,5),16)/255,o=parseInt(e.slice(5,7),16)/255,r=i=>i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4);return .2126*r(n)+.7152*r(a)+.0722*r(o)}const Pr=.2126729,Fr=.7151522,Nr=.072175,$r=.56,Wr=.57,Or=.65,Vr=.62,it=.022,Hr=1.414,Gr=1.14,Ur=1.14,st=.027,lt=.027;function ct(e){const n=parseInt(e.slice(1,3),16)/255,a=parseInt(e.slice(3,5),16)/255,o=parseInt(e.slice(5,7),16)/255,r=Math.pow(n,2.4),i=Math.pow(a,2.4),s=Math.pow(o,2.4);let l=Pr*r+Fr*i+Nr*s;return l<0&&(l=0),l<it?l+Math.pow(it-l,Hr):l}function ve(e,n){const a=ct(e),o=ct(n);let r;if(a>o){const i=(Math.pow(a,$r)-Math.pow(o,Wr))*Gr;r=i<st?0:i-st}else{const i=(Math.pow(a,Or)-Math.pow(o,Vr))*Ur;r=i>-lt?0:i+lt}return r*100}function Re(e){const n=Math.abs(ve(e,"#ffffff")),a=Math.abs(ve(e,"#000000"));return n>=a?"#ffffff":"#000000"}function _r(e,n,a=60){if(Math.abs(ve(e,n))>=a)return e;const o=parseInt(e.slice(1,3),16)/255,r=parseInt(e.slice(3,5),16)/255,i=parseInt(e.slice(5,7),16)/255,s=Math.max(o,r,i),l=Math.min(o,r,i);let c=0,u=0,f=(s+l)/2;if(s!==l){const h=s-l;u=f>.5?h/(2-s-l):h/(s+l),s===o?c=((r-i)/h+(r<i?6:0))/6:s===r?c=((i-o)/h+2)/6:c=((o-r)/h+4)/6}const y=qr(n)>.5?-.005:.005;for(let h=0;h<100;h++){f=Math.min(1,Math.max(0,f+y));const w=Yr(c,u,f);if(Math.abs(ve(w,n))>=a)return w}return e}function Yr(e,n,a){const o=(c,u,f)=>(f<0&&(f+=1),f>1&&(f-=1),f<.16666666666666666?c+(u-c)*6*f:f<.5?u:f<.6666666666666666?c+(u-c)*(.6666666666666666-f)*6:c);let r,i,s;if(n===0)r=i=s=a;else{const c=a<.5?a*(1+n):a+n-a*n,u=2*a-c;r=o(u,c,e+1/3),i=o(u,c,e),s=o(u,c,e-1/3)}const l=c=>Math.round(c*255).toString(16).padStart(2,"0");return`#${l(r)}${l(i)}${l(s)}`}const ye={subtle:{light:.95,dark:.12},text:{light:.28,dark:.78}};function fe(e,n){const[a,o]=K(e);return X(a,o*.5,n?ye.subtle.light:ye.subtle.dark)}function he(e,n){const[a,o]=K(e);return X(a,o,n?ye.text.light:ye.text.dark)}function Le(e,n,a){const o={},r=a==="light";return"borderDefault"in e&&("borderSubtle"in e||(o.borderSubtle=F(n.borderDefault,r?.05:-.02)),"borderStrong"in e||(o.borderStrong=F(n.borderDefault,r?-.27:.19))),"bgBase"in e&&("bgSubtle"in e||(o.bgSubtle=F(n.bgBase,r?-.02:.02))),"surface"in e&&("surfaceSecondary"in e||(o.surfaceSecondary=F(n.surface,r?-.04:.03)),"surfaceRaised"in e||(o.surfaceRaised=F(n.surface,r?0:.06)),"surfaceOverlay"in e||(o.surfaceOverlay=F(n.surface,r?0:.06))),"textPrimary"in e&&("textSecondary"in e||(o.textSecondary=F(n.textPrimary,r?.2:-.15)),"textDisabled"in e||(o.textDisabled=F(n.textPrimary,r?.35:-.4))),"accentDefault"in e&&("accentHover"in e||(o.accentHover=F(n.accentDefault,r?.05:-.07)),"accentActive"in e||(o.accentActive=F(n.accentDefault,r?.13:-.14)),"accentSubtle"in e||(o.accentSubtle=F(n.accentDefault,r?.85:-.6))),"successDefault"in e&&("successSubtle"in e||(o.successSubtle=fe(n.successDefault,r)),"successText"in e||(o.successText=he(n.successDefault,r))),"warningDefault"in e&&("warningSubtle"in e||(o.warningSubtle=fe(n.warningDefault,r)),"warningText"in e||(o.warningText=he(n.warningDefault,r))),"dangerDefault"in e&&("dangerHover"in e||(o.dangerHover=F(n.dangerDefault,r?.05:-.07)),"dangerSubtle"in e||(o.dangerSubtle=fe(n.dangerDefault,r)),"dangerText"in e||(o.dangerText=he(n.dangerDefault,r))),"infoDefault"in e&&("infoSubtle"in e||(o.infoSubtle=fe(n.infoDefault,r)),"infoText"in e||(o.infoText=he(n.infoDefault,r))),o}function Be(e,n="light"){const o={...n==="dark"?Ee:ce,...e},r=Le(e,o,n),i=n==="light"?F(o.accentDefault,-.15):F(o.accentDefault,.15);return{...o,...r,textOnAccent:Re(o.accentDefault),accentBorder:i}}const qe={name:"default",light:{bgBase:"#ffffff",surface:"#ffffff",borderDefault:"#e5e7eb",textPrimary:"#111827",accentDefault:"#111827",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#111318",surface:"#181a20",borderDefault:"#2e3039",textPrimary:"#f3f4f6",accentDefault:"#f9fafb",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},wt={name:"brand",light:{bgBase:"#fffefb",surface:"#fffdf7",borderDefault:"#e8e3d6",textPrimary:"#1a1710",accentDefault:"#e9c96b",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#151310",surface:"#1c1a15",borderDefault:"#33302a",textPrimary:"#f5f3ee",accentDefault:"#e9c96b",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Pe={name:"indigo",light:{bgBase:"#fdfcff",surface:"#faf9fe",borderDefault:"#e0dde9",textPrimary:"#1a1726",accentDefault:"#6366f1",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#12111a",surface:"#191820",borderDefault:"#2e2d3a",textPrimary:"#f0eef6",accentDefault:"#818cf8",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Kr={name:"violet",light:{bgBase:"#fdfcfe",surface:"#faf8fd",borderDefault:"#e2dce9",textPrimary:"#1c1726",accentDefault:"#8b5cf6",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#13111a",surface:"#1a1822",borderDefault:"#302d3b",textPrimary:"#f0edf7",accentDefault:"#a78bfa",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},kt={name:"emerald",light:{bgBase:"#fbfefc",surface:"#f7fcf9",borderDefault:"#dbe8df",textPrimary:"#0f1f15",accentDefault:"#10b981",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0f1512",surface:"#151c18",borderDefault:"#263330",textPrimary:"#ecf5f0",accentDefault:"#34d399",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Xr={name:"teal",light:{bgBase:"#fbfefd",surface:"#f6fcfa",borderDefault:"#d4e5e0",textPrimary:"#152420",accentDefault:"#0d9488",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0f1514",surface:"#161d1c",borderDefault:"#283836",textPrimary:"#e4f3f0",accentDefault:"#2dd4bf",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Fe={name:"rose",light:{bgBase:"#fffcfd",surface:"#fef9fa",borderDefault:"#ecdde1",textPrimary:"#24121a",accentDefault:"#f43f5e",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#161012",surface:"#1d1518",borderDefault:"#3a282e",textPrimary:"#f8ecf0",accentDefault:"#fb7185",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Jr={name:"coral",light:{bgBase:"#fffcfb",surface:"#fef9f7",borderDefault:"#e9ddd8",textPrimary:"#261a16",accentDefault:"#e8624a",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#b91c1c",infoDefault:"#2563eb"},dark:{bgBase:"#171210",surface:"#1e1816",borderDefault:"#3b312c",textPrimary:"#f5ece8",accentDefault:"#f38b76",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Zr={name:"amber",light:{bgBase:"#fffefb",surface:"#fefcf6",borderDefault:"#e8e1d0",textPrimary:"#261f0f",accentDefault:"#d97706",successDefault:"#16a34a",warningDefault:"#b45309",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#171310",surface:"#1e1a15",borderDefault:"#3a3329",textPrimary:"#f5f0e6",accentDefault:"#f59e0b",successDefault:"#22c55e",warningDefault:"#d97706",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},St={name:"ocean",light:{bgBase:"#fbfdff",surface:"#f6fafd",borderDefault:"#d9e4ec",textPrimary:"#0f1a24",accentDefault:"#0ea5e9",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0e1318",surface:"#141a20",borderDefault:"#243038",textPrimary:"#ebf2f8",accentDefault:"#38bdf8",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Qr={name:"slate",light:{bgBase:"#fafbfc",surface:"#f7f8fa",borderDefault:"#dde1e6",textPrimary:"#1a1d23",accentDefault:"#475569",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0f1116",surface:"#161920",borderDefault:"#2b3040",textPrimary:"#e8ecf4",accentDefault:"#94a3b8",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},eo={name:"sage",light:{bgBase:"#fbfcfb",surface:"#f5f7f5",borderDefault:"#d8ddd6",textPrimary:"#1a2019",accentDefault:"#5f8c6e",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#101410",surface:"#171c17",borderDefault:"#2c372c",textPrimary:"#e4ede6",accentDefault:"#86b394",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Ne={name:"sharp",tokens:{radiusNone:"0px",radiusSm:"0.125rem",radiusMd:"0.1875rem",radiusLg:"0.25rem",radiusXl:"0.375rem",radiusFull:"9999px"}},$e={name:"rounded",tokens:{radiusNone:"0px",radiusSm:"0.25rem",radiusMd:"0.375rem",radiusLg:"0.5rem",radiusXl:"0.75rem",radiusFull:"9999px"}},We={name:"pill",tokens:{radiusNone:"0px",radiusSm:"0.5rem",radiusMd:"0.75rem",radiusLg:"1rem",radiusXl:"1.5rem",radiusFull:"9999px"}},Oe={name:"compact",tokens:{space0:"0px",space1:"0.2rem",space2:"0.4rem",space3:"0.6rem",space4:"0.8rem",space5:"1rem",space6:"1.2rem",space8:"1.6rem",space10:"2rem",space12:"2.4rem",space16:"3.2rem",space20:"4rem",space24:"4.8rem"}},Ve={name:"default",tokens:{space0:"0px",space1:"0.25rem",space2:"0.5rem",space3:"0.75rem",space4:"1rem",space5:"1.25rem",space6:"1.5rem",space8:"2rem",space10:"2.5rem",space12:"3rem",space16:"4rem",space20:"5rem",space24:"6rem"}},He={name:"spacious",tokens:{space0:"0px",space1:"0.3125rem",space2:"0.625rem",space3:"0.9375rem",space4:"1.25rem",space5:"1.5625rem",space6:"1.875rem",space8:"2.5rem",space10:"3.125rem",space12:"3.75rem",space16:"5rem",space20:"6.25rem",space24:"7.5rem"}},Ge={name:"flat",light:{shadowNone:"none",shadowSm:"none",shadowMd:"none",shadowLg:"none",shadowXl:"none"},dark:{shadowNone:"none",shadowSm:"none",shadowMd:"none",shadowLg:"none",shadowXl:"none"}},Ue={name:"subtle",light:{shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"},dark:{shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.3)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.5)"}},_e={name:"elevated",light:{shadowNone:"none",shadowSm:"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",shadowMd:"0 4px 8px -1px rgb(0 0 0 / 0.15), 0 2px 6px -2px rgb(0 0 0 / 0.12)",shadowLg:"0 12px 20px -4px rgb(0 0 0 / 0.18), 0 6px 10px -4px rgb(0 0 0 / 0.12)",shadowXl:"0 24px 36px -8px rgb(0 0 0 / 0.2), 0 10px 16px -6px rgb(0 0 0 / 0.14)"},dark:{shadowNone:"none",shadowSm:"0 1px 3px 0 rgb(0 0 0 / 0.45), 0 1px 2px -1px rgb(0 0 0 / 0.4)",shadowMd:"0 4px 8px -1px rgb(0 0 0 / 0.55), 0 2px 6px -2px rgb(0 0 0 / 0.5)",shadowLg:"0 12px 20px -4px rgb(0 0 0 / 0.6), 0 6px 10px -4px rgb(0 0 0 / 0.5)",shadowXl:"0 24px 36px -8px rgb(0 0 0 / 0.65), 0 10px 16px -6px rgb(0 0 0 / 0.55)"}},Tt={name:"modern",palette:Pe,shape:$e,density:Ve,shadow:Ue},jt={name:"enterprise",palette:qe,shape:Ne,density:Oe,shadow:Ge},Ct={name:"playful",palette:Fe,shape:We,density:He,shadow:_e},to={default:qe,brand:wt,indigo:Pe,violet:Kr,emerald:kt,teal:Xr,rose:Fe,coral:Jr,amber:Zr,ocean:St,slate:Qr,sage:eo},no={sharp:Ne,rounded:$e,pill:We},ao={compact:Oe,default:Ve,spacious:He},ro={flat:Ge,subtle:Ue,elevated:_e},oo={modern:Tt,enterprise:jt,playful:Ct};function io(e){return typeof e=="string"?to[e]:e}function so(e){return typeof e=="string"?no[e]:e}function lo(e){return typeof e=="string"?ao[e]:e}function co(e){return typeof e=="string"?ro[e]:e}function Dt(e,n){let a,o,r,i;if(typeof e=="string"){const l=oo[e];if(!l)return{};a=l.palette,o=l.shape,r=l.density,i=l.shadow}else e.palette!==void 0&&(a=io(e.palette)),e.shape!==void 0&&(o=so(e.shape)),e.density!==void 0&&(r=lo(e.density)),e.shadow!==void 0&&(i=co(e.shadow));const s={};if(a){const l=Be(a[n],n);Object.assign(s,l)}return o&&Object.assign(s,o.tokens),r&&Object.assign(s,r.tokens),i&&Object.assign(s,i[n]),s}const It=p.createContext({theme:"light",tokens:ce});function uo({theme:e="light",preset:n,tokens:a,anchors:o,children:r}){const i=p.useId().replace(/:/g,""),s=n?Dt(n,e):void 0,l=(()=>{if(o){const g=Be(o,e);if(s){const b={};for(const[k,D]of Object.entries(s))(k.startsWith("space")||k.startsWith("radius")||k.startsWith("shadow")||k.startsWith("duration")||k.startsWith("easing"))&&(b[k]=D);return{...g,...b}}return g}const u=e==="dark"?Ee:ce,f=s?{...s,...a}:a,d=f?{...u,...f}:u,y=f?Le(f,d,e):{},h=(f==null?void 0:f.accentBorder)??(e==="light"?F(d.accentDefault,-.15):F(d.accentDefault,.15)),w=(f==null?void 0:f.textOnAccent)??Re(d.accentDefault),v=_r(d.accentDefault,w);return{...d,...y,accentDefault:v,textOnAccent:w,accentBorder:h}})(),c=`html { font-size: 14px; }
381
- `+xt(l,":root");return p.useLayoutEffect(()=>{let u=document.getElementById(`lucent-tokens-${i}`);return u||(u=document.createElement("style"),u.id=`lucent-tokens-${i}`,document.head.appendChild(u)),u.textContent=c,()=>{var f;(f=document.getElementById(`lucent-tokens-${i}`))==null||f.remove()}},[i,c]),t.jsx(It.Provider,{value:{theme:e,tokens:l},children:r})}function po(){return p.useContext(It)}const fo={bgBase:{description:"Main page/canvas background. The lowest elevation layer — everything sits on top of this.",lightGuidance:"Near-white. Typically #ffffff or a very faint tint (L > 0.96).",darkGuidance:"Near-black with a subtle cool or warm tint. Typically L 0.07–0.10 (e.g. #0f0f11, #111318).",derives:["bgSubtle"]},surface:{description:'Component surface color. Used for cards, input backgrounds, table rows, list items — any component that "floats" above the page canvas.',lightGuidance:"Very slightly off-white — just enough to read as distinct from bgBase. Typically L 0.96–0.98 (e.g. #f9fafb, #f8f8f8).",darkGuidance:"Slightly lighter than bgBase. Typically L 0.11–0.15 (e.g. #1a1a1e, #18181b).",derives:["surfaceSecondary","surfaceRaised","surfaceOverlay"]},borderDefault:{description:"Default border and divider color. Used on input outlines, card borders, table cell borders, section dividers.",lightGuidance:"A mid-light gray. Enough contrast to be legible on bgBase, not so dark it draws attention. Typically L 0.85–0.92 (e.g. #e5e7eb, #d1d5db).",darkGuidance:"A dim gray that reads against dark surfaces. Typically L 0.18–0.26 (e.g. #2d2d35, #374151).",derives:["borderSubtle","borderStrong"]},textPrimary:{description:"Primary body text. High contrast against bgBase — the default color for headings, labels, and body copy.",lightGuidance:"Very dark — near-black. Typically L 0.04–0.15 (e.g. #111827, #0f172a). Must pass WCAG AA against bgBase.",darkGuidance:"Very light — near-white. Typically L 0.88–0.96 (e.g. #f9fafb, #e2e8f0). Must pass WCAG AA against bgBase.",derives:["textSecondary","textDisabled"]},accentDefault:{description:"Primary brand/action color. Drives the visual identity — used on primary buttons, active nav links, focus rings, badges, and progress indicators.",lightGuidance:"Pick a color with enough contrast against both bgBase (white) and textOnAccent (computed automatically). Saturated mid-tones work well. E.g. indigo #6366f1, violet #8b5cf6, emerald #10b981. Monochrome default is #111827 (near-black).",darkGuidance:"In dark mode the accent typically lightens so it stays visible. This is handled automatically via deriveDarkFromLight() — you can supply the same light-mode accent and the dark variant is computed.",derives:["accentHover","accentActive","accentSubtle","accentBorder","textOnAccent"]},successDefault:{description:'Positive/success state color. Used on success alerts, completed step indicators, "online" status badges, and confirmation toasts.',lightGuidance:"A readable green in the mid-to-dark range. E.g. #22c55e (Tailwind green-500), #16a34a (green-600). Avoid very pale greens — they fail WCAG against white.",darkGuidance:"Slightly lighter than the light-mode value so it reads against dark surfaces. createTheme() handles this automatically.",derives:["successSubtle","successText"]},warningDefault:{description:'Cautionary/warning state color. Used on warning banners, pending/in-review badges, and "needs attention" indicators.',lightGuidance:"An amber or orange-yellow. E.g. #f59e0b (Tailwind amber-500), #d97706 (amber-600). Avoid pure yellow — insufficient contrast on white.",darkGuidance:"Slightly lighter than light-mode. createTheme() handles this automatically.",derives:["warningSubtle","warningText"]},dangerDefault:{description:'Error/destructive state color. Used on error messages, delete-confirmation buttons, form field errors, and "offline" or "failed" status.',lightGuidance:"A mid-to-dark red. E.g. #ef4444 (Tailwind red-500), #dc2626 (red-600).",darkGuidance:"Slightly lighter than light-mode. createTheme() handles this automatically.",derives:["dangerHover","dangerSubtle","dangerText"]},infoDefault:{description:'Neutral informational state color. Used on info banners, help tooltips, "new feature" callouts, and link colors in some contexts.',lightGuidance:"A mid blue. E.g. #3b82f6 (Tailwind blue-500), #2563eb (blue-600).",darkGuidance:"Slightly lighter than light-mode. createTheme() handles this automatically.",derives:["infoSubtle","infoText"]}},ho={id:"lucent-provider",name:"LucentProvider",tier:"provider",domain:"neutral",specVersion:"1.0",description:"Root configuration wrapper that injects Lucent design tokens as CSS custom properties. Accepts a design preset for instant theming, 9 anchor colors (via `anchors`) for zero-config theming, or granular token overrides (via `tokens`) for full control.",designIntent:'LucentProvider is the single source of truth for the visual identity of any Lucent-powered UI. Its primary design goal is to make custom theming accessible to both humans and LLMs with minimal effort.\n\nPRESET MODE (fastest path): Pass `preset` with a named preset ("modern", "enterprise", "playful") or an object mixing dimensions: `{ palette: "indigo", shape: "pill", density: "compact", shadow: "elevated" }`. Presets bundle palette colors, border radius, spacing, and shadows into one cohesive design. Available palettes: default, brand, indigo, emerald, rose, ocean. Shapes: sharp, rounded, pill. Densities: compact, default, spacious. Shadows: flat, subtle, elevated. Presets work with both light and dark themes automatically.\n\nANCHOR MODE (recommended for LLMs building custom themes): Pass `anchors` with 9 semantic colors and the provider automatically derives all 30+ variant tokens — hover/active/subtle states, WCAG-compliant contrast text, status subtle tints, surface elevation steps, and more. An LLM generating a themed UI only needs to reason about 9 colors, not the full token surface.\n\nTOKEN MODE (for granular control): Pass `tokens` as a partial override object. Any token not supplied falls back to the base light or dark theme. Derivation still runs — e.g. if you supply only `accentDefault`, the provider auto-derives `accentHover`, `accentActive`, `accentSubtle`, `accentBorder`, and `textOnAccent`.\n\nPRECEDENCE (later wins): base theme → preset → anchors → tokens. You can combine preset with tokens to start from a preset and tweak individual values.\n\nWCAG auto-computation: `textOnAccent` is always computed from the resolved accent color via relative luminance — it will be #000000 or #ffffff, whichever passes AA contrast. Consumers can override it if they have brand-specific requirements.\n\nDARK MODE: Pass `theme="dark"` alongside any prop. Presets include both light and dark palettes. Anchor colors are applied to the dark base palette; derivation runs with dark-calibrated lightness deltas.\n\nDO NOT nest multiple LucentProviders unless intentionally theming a sub-tree differently (e.g. an inverted sidebar). The outermost provider wins for `:root` CSS vars.',props:[{name:"preset",type:"PresetProp",required:!1,description:'Design preset for instant theming. Pass a combined name ("modern", "enterprise", "playful") or an object to mix dimensions: { palette?: "default"|"brand"|"indigo"|"emerald"|"rose"|"ocean", shape?: "sharp"|"rounded"|"pill", density?: "compact"|"default"|"spacious", shadow?: "flat"|"subtle"|"elevated" }. You can also pass imported preset objects directly for tree-shaking. Precedence: base theme → preset → anchors → tokens.'},{name:"anchors",type:"ThemeAnchors",required:!1,description:"Minimal theming API: supply 9 semantic anchor colors and all variant tokens are derived automatically. See ThemeAnchorsSpec for guidance on each key. When provided alongside a preset, anchors override the preset's palette colors but preset shape/density/shadow tokens are preserved. When provided without a preset, the `tokens` prop is ignored. Keys: bgBase, surface, borderDefault, textPrimary, accentDefault, successDefault, warningDefault, dangerDefault, infoDefault."},{name:"theme",type:"enum",required:!1,default:'"light"',enumValues:["light","dark"],description:'Selects the base token palette. "light" uses lightTokens as the starting point; "dark" uses darkTokens. Applies to both anchor-mode and token-mode.'},{name:"tokens",type:"Partial<LucentTokens>",required:!1,description:"Granular token overrides. Any token not supplied falls back to the base theme. Variant derivation still runs for anchor tokens found in this object (e.g. supplying `accentDefault` auto-derives hover/active/subtle variants). Ignored when `anchors` is provided."},{name:"children",type:"ReactNode",required:!0,description:"The subtree to theme. Typically your entire app, or a section that needs independent theming."}],usageExamples:[{title:"Preset mode — combined preset (simplest)",description:"Pick a curated preset that bundles palette, shape, density, and shadow tokens. Works with both light and dark themes.",code:`import { LucentProvider } from 'lucent-ui';
380
+ }`}function Vr(e){const n=parseInt(e.slice(1,3),16)/255,a=parseInt(e.slice(3,5),16)/255,o=parseInt(e.slice(5,7),16)/255,r=i=>i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4);return .2126*r(n)+.7152*r(a)+.0722*r(o)}const Hr=.2126729,Gr=.7151522,Ur=.072175,_r=.56,Yr=.57,Kr=.65,Xr=.62,it=.022,Jr=1.414,Zr=1.14,Qr=1.14,st=.027,lt=.027;function ct(e){const n=parseInt(e.slice(1,3),16)/255,a=parseInt(e.slice(3,5),16)/255,o=parseInt(e.slice(5,7),16)/255,r=Math.pow(n,2.4),i=Math.pow(a,2.4),s=Math.pow(o,2.4);let l=Hr*r+Gr*i+Ur*s;return l<0&&(l=0),l<it?l+Math.pow(it-l,Jr):l}function ye(e,n){const a=ct(e),o=ct(n);let r;if(a>o){const i=(Math.pow(a,_r)-Math.pow(o,Yr))*Zr;r=i<st?0:i-st}else{const i=(Math.pow(a,Kr)-Math.pow(o,Xr))*Qr;r=i>-lt?0:i+lt}return r*100}function Re(e){const n=Math.abs(ye(e,"#ffffff")),a=Math.abs(ye(e,"#000000"));return n>=a?"#ffffff":"#000000"}function eo(e,n,a=60){if(Math.abs(ye(e,n))>=a)return e;const o=parseInt(e.slice(1,3),16)/255,r=parseInt(e.slice(3,5),16)/255,i=parseInt(e.slice(5,7),16)/255,s=Math.max(o,r,i),l=Math.min(o,r,i);let c=0,d=0,p=(s+l)/2;if(s!==l){const u=s-l;d=p>.5?u/(2-s-l):u/(s+l),s===o?c=((r-i)/u+(r<i?6:0))/6:s===r?c=((i-o)/u+2)/6:c=((o-r)/u+4)/6}const h=Vr(n)>.5?-.005:.005;for(let u=0;u<100;u++){p=Math.min(1,Math.max(0,p+h));const S=to(c,d,p);if(Math.abs(ye(S,n))>=a)return S}return e}function to(e,n,a){const o=(c,d,p)=>(p<0&&(p+=1),p>1&&(p-=1),p<.16666666666666666?c+(d-c)*6*p:p<.5?d:p<.6666666666666666?c+(d-c)*(.6666666666666666-p)*6:c);let r,i,s;if(n===0)r=i=s=a;else{const c=a<.5?a*(1+n):a+n-a*n,d=2*a-c;r=o(d,c,e+1/3),i=o(d,c,e),s=o(d,c,e-1/3)}const l=c=>Math.round(c*255).toString(16).padStart(2,"0");return`#${l(r)}${l(i)}${l(s)}`}const xe={subtle:{light:.95,dark:.12},text:{light:.28,dark:.78}};function fe(e,n){const[a,o]=X(e);return J(a,o*.5,n?xe.subtle.light:xe.subtle.dark)}function he(e,n){const[a,o]=X(e);return J(a,o,n?xe.text.light:xe.text.dark)}function Le(e,n,a){const o={},r=a==="light";return"borderDefault"in e&&("borderSubtle"in e||(o.borderSubtle=$(n.borderDefault,r?.05:-.02)),"borderStrong"in e||(o.borderStrong=$(n.borderDefault,r?-.27:.19))),"bgBase"in e&&("bgSubtle"in e||(o.bgSubtle=$(n.bgBase,r?-.02:.02))),"surface"in e&&("surfaceSecondary"in e||(o.surfaceSecondary=$(n.surface,r?-.04:.03)),"surfaceRaised"in e||(o.surfaceRaised=$(n.surface,r?0:.06)),"surfaceOverlay"in e||(o.surfaceOverlay=$(n.surface,r?0:.06))),"textPrimary"in e&&("textSecondary"in e||(o.textSecondary=$(n.textPrimary,r?.2:-.15)),"textDisabled"in e||(o.textDisabled=$(n.textPrimary,r?.35:-.4))),"accentDefault"in e&&("accentHover"in e||(o.accentHover=$(n.accentDefault,r?.05:-.07)),"accentActive"in e||(o.accentActive=$(n.accentDefault,r?.13:-.14)),"accentSubtle"in e||(o.accentSubtle=$(n.accentDefault,r?.85:-.6))),"successDefault"in e&&("successSubtle"in e||(o.successSubtle=fe(n.successDefault,r)),"successText"in e||(o.successText=he(n.successDefault,r))),"warningDefault"in e&&("warningSubtle"in e||(o.warningSubtle=fe(n.warningDefault,r)),"warningText"in e||(o.warningText=he(n.warningDefault,r))),"dangerDefault"in e&&("dangerHover"in e||(o.dangerHover=$(n.dangerDefault,r?.05:-.07)),"dangerSubtle"in e||(o.dangerSubtle=fe(n.dangerDefault,r)),"dangerText"in e||(o.dangerText=he(n.dangerDefault,r))),"infoDefault"in e&&("infoSubtle"in e||(o.infoSubtle=fe(n.infoDefault,r)),"infoText"in e||(o.infoText=he(n.infoDefault,r))),o}function Be(e,n="light"){const o={...n==="dark"?Ee:ce,...e},r=Le(e,o,n),i=n==="light"?$(o.accentDefault,-.15):$(o.accentDefault,.15);return{...o,...r,textOnAccent:Re(o.accentDefault),accentBorder:i}}const qe={name:"default",light:{bgBase:"#ffffff",surface:"#ffffff",borderDefault:"#e5e7eb",textPrimary:"#111827",accentDefault:"#111827",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#111318",surface:"#181a20",borderDefault:"#2e3039",textPrimary:"#f3f4f6",accentDefault:"#f9fafb",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},kt={name:"brand",light:{bgBase:"#fffefb",surface:"#fffdf7",borderDefault:"#e8e3d6",textPrimary:"#1a1710",accentDefault:"#e9c96b",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#151310",surface:"#1c1a15",borderDefault:"#33302a",textPrimary:"#f5f3ee",accentDefault:"#e9c96b",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Pe={name:"indigo",light:{bgBase:"#fdfcff",surface:"#faf9fe",borderDefault:"#e0dde9",textPrimary:"#1a1726",accentDefault:"#6366f1",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#12111a",surface:"#191820",borderDefault:"#2e2d3a",textPrimary:"#f0eef6",accentDefault:"#818cf8",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},no={name:"violet",light:{bgBase:"#fdfcfe",surface:"#faf8fd",borderDefault:"#e2dce9",textPrimary:"#1c1726",accentDefault:"#8b5cf6",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#13111a",surface:"#1a1822",borderDefault:"#302d3b",textPrimary:"#f0edf7",accentDefault:"#a78bfa",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},St={name:"emerald",light:{bgBase:"#fbfefc",surface:"#f7fcf9",borderDefault:"#dbe8df",textPrimary:"#0f1f15",accentDefault:"#10b981",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0f1512",surface:"#151c18",borderDefault:"#263330",textPrimary:"#ecf5f0",accentDefault:"#34d399",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},ao={name:"teal",light:{bgBase:"#fbfefd",surface:"#f6fcfa",borderDefault:"#d4e5e0",textPrimary:"#152420",accentDefault:"#0d9488",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0f1514",surface:"#161d1c",borderDefault:"#283836",textPrimary:"#e4f3f0",accentDefault:"#2dd4bf",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Fe={name:"rose",light:{bgBase:"#fffcfd",surface:"#fef9fa",borderDefault:"#ecdde1",textPrimary:"#24121a",accentDefault:"#f43f5e",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#161012",surface:"#1d1518",borderDefault:"#3a282e",textPrimary:"#f8ecf0",accentDefault:"#fb7185",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},ro={name:"coral",light:{bgBase:"#fffcfb",surface:"#fef9f7",borderDefault:"#e9ddd8",textPrimary:"#261a16",accentDefault:"#e8624a",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#b91c1c",infoDefault:"#2563eb"},dark:{bgBase:"#171210",surface:"#1e1816",borderDefault:"#3b312c",textPrimary:"#f5ece8",accentDefault:"#f38b76",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},oo={name:"amber",light:{bgBase:"#fffefb",surface:"#fefcf6",borderDefault:"#e8e1d0",textPrimary:"#261f0f",accentDefault:"#d97706",successDefault:"#16a34a",warningDefault:"#b45309",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#171310",surface:"#1e1a15",borderDefault:"#3a3329",textPrimary:"#f5f0e6",accentDefault:"#f59e0b",successDefault:"#22c55e",warningDefault:"#d97706",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Tt={name:"ocean",light:{bgBase:"#fbfdff",surface:"#f6fafd",borderDefault:"#d9e4ec",textPrimary:"#0f1a24",accentDefault:"#0ea5e9",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0e1318",surface:"#141a20",borderDefault:"#243038",textPrimary:"#ebf2f8",accentDefault:"#38bdf8",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},io={name:"slate",light:{bgBase:"#fafbfc",surface:"#f7f8fa",borderDefault:"#dde1e6",textPrimary:"#1a1d23",accentDefault:"#475569",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#0f1116",surface:"#161920",borderDefault:"#2b3040",textPrimary:"#e8ecf4",accentDefault:"#94a3b8",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},so={name:"sage",light:{bgBase:"#fbfcfb",surface:"#f5f7f5",borderDefault:"#d8ddd6",textPrimary:"#1a2019",accentDefault:"#5f8c6e",successDefault:"#16a34a",warningDefault:"#d97706",dangerDefault:"#dc2626",infoDefault:"#2563eb"},dark:{bgBase:"#101410",surface:"#171c17",borderDefault:"#2c372c",textPrimary:"#e4ede6",accentDefault:"#86b394",successDefault:"#22c55e",warningDefault:"#f59e0b",dangerDefault:"#ef4444",infoDefault:"#3b82f6"}},Ne={name:"sharp",tokens:{radiusNone:"0px",radiusSm:"0.125rem",radiusMd:"0.1875rem",radiusLg:"0.25rem",radiusXl:"0.375rem",radiusFull:"9999px"}},$e={name:"rounded",tokens:{radiusNone:"0px",radiusSm:"0.25rem",radiusMd:"0.375rem",radiusLg:"0.5rem",radiusXl:"0.75rem",radiusFull:"9999px"}},We={name:"pill",tokens:{radiusNone:"0px",radiusSm:"0.5rem",radiusMd:"0.75rem",radiusLg:"1rem",radiusXl:"1.5rem",radiusFull:"9999px"}},Oe={name:"compact",tokens:{space0:"0px",space1:"0.2rem",space2:"0.4rem",space3:"0.6rem",space4:"0.8rem",space5:"1rem",space6:"1.2rem",space8:"1.6rem",space10:"2rem",space12:"2.4rem",space16:"3.2rem",space20:"4rem",space24:"4.8rem"}},Ve={name:"default",tokens:{space0:"0px",space1:"0.25rem",space2:"0.5rem",space3:"0.75rem",space4:"1rem",space5:"1.25rem",space6:"1.5rem",space8:"2rem",space10:"2.5rem",space12:"3rem",space16:"4rem",space20:"5rem",space24:"6rem"}},He={name:"spacious",tokens:{space0:"0px",space1:"0.3125rem",space2:"0.625rem",space3:"0.9375rem",space4:"1.25rem",space5:"1.5625rem",space6:"1.875rem",space8:"2.5rem",space10:"3.125rem",space12:"3.75rem",space16:"5rem",space20:"6.25rem",space24:"7.5rem"}},Ge={name:"flat",light:{shadowNone:"none",shadowSm:"none",shadowMd:"none",shadowLg:"none",shadowXl:"none"},dark:{shadowNone:"none",shadowSm:"none",shadowMd:"none",shadowLg:"none",shadowXl:"none"}},Ue={name:"subtle",light:{shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"},dark:{shadowNone:"none",shadowSm:"0 1px 2px 0 rgb(0 0 0 / 0.3)",shadowMd:"0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4)",shadowLg:"0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4)",shadowXl:"0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.5)"}},_e={name:"elevated",light:{shadowNone:"none",shadowSm:"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",shadowMd:"0 4px 8px -1px rgb(0 0 0 / 0.15), 0 2px 6px -2px rgb(0 0 0 / 0.12)",shadowLg:"0 12px 20px -4px rgb(0 0 0 / 0.18), 0 6px 10px -4px rgb(0 0 0 / 0.12)",shadowXl:"0 24px 36px -8px rgb(0 0 0 / 0.2), 0 10px 16px -6px rgb(0 0 0 / 0.14)"},dark:{shadowNone:"none",shadowSm:"0 1px 3px 0 rgb(0 0 0 / 0.45), 0 1px 2px -1px rgb(0 0 0 / 0.4)",shadowMd:"0 4px 8px -1px rgb(0 0 0 / 0.55), 0 2px 6px -2px rgb(0 0 0 / 0.5)",shadowLg:"0 12px 20px -4px rgb(0 0 0 / 0.6), 0 6px 10px -4px rgb(0 0 0 / 0.5)",shadowXl:"0 24px 36px -8px rgb(0 0 0 / 0.65), 0 10px 16px -6px rgb(0 0 0 / 0.55)"}},jt={name:"modern",palette:Pe,shape:$e,density:Ve,shadow:Ue},Ct={name:"enterprise",palette:qe,shape:Ne,density:Oe,shadow:Ge},Dt={name:"playful",palette:Fe,shape:We,density:He,shadow:_e},lo={default:qe,brand:kt,indigo:Pe,violet:no,emerald:St,teal:ao,rose:Fe,coral:ro,amber:oo,ocean:Tt,slate:io,sage:so},co={sharp:Ne,rounded:$e,pill:We},uo={compact:Oe,default:Ve,spacious:He},po={flat:Ge,subtle:Ue,elevated:_e},fo={modern:jt,enterprise:Ct,playful:Dt};function ho(e){return typeof e=="string"?lo[e]:e}function mo(e){return typeof e=="string"?co[e]:e}function go(e){return typeof e=="string"?uo[e]:e}function bo(e){return typeof e=="string"?po[e]:e}function It(e,n){let a,o,r,i;if(typeof e=="string"){const l=fo[e];if(!l)return{};a=l.palette,o=l.shape,r=l.density,i=l.shadow}else e.palette!==void 0&&(a=ho(e.palette)),e.shape!==void 0&&(o=mo(e.shape)),e.density!==void 0&&(r=go(e.density)),e.shadow!==void 0&&(i=bo(e.shadow));const s={};if(a){const l=Be(a[n],n);Object.assign(s,l)}return o&&Object.assign(s,o.tokens),r&&Object.assign(s,r.tokens),i&&Object.assign(s,i[n]),s}const Mt=f.createContext({theme:"light",tokens:ce});function vo({theme:e="light",preset:n,tokens:a,anchors:o,children:r}){const i=f.useId().replace(/:/g,""),s=n?It(n,e):void 0,l=(()=>{if(o){const b=Be(o,e);if(s){const v={};for(const[w,j]of Object.entries(s))(w.startsWith("space")||w.startsWith("radius")||w.startsWith("shadow")||w.startsWith("duration")||w.startsWith("easing"))&&(v[w]=j);return{...b,...v}}return b}const d=e==="dark"?Ee:ce,p=s?{...s,...a}:a,m=p?{...d,...p}:d,h=p?Le(p,m,e):{},u=(p==null?void 0:p.accentBorder)??(e==="light"?$(m.accentDefault,-.15):$(m.accentDefault,.15)),S=(p==null?void 0:p.textOnAccent)??Re(m.accentDefault),y=eo(m.accentDefault,S);return{...m,...h,accentDefault:y,textOnAccent:S,accentBorder:u}})(),c=`html { font-size: 14px; }
381
+ `+wt(l,":root");return f.useLayoutEffect(()=>{let d=document.getElementById(`lucent-tokens-${i}`);return d||(d=document.createElement("style"),d.id=`lucent-tokens-${i}`,document.head.appendChild(d)),d.textContent=c,()=>{var p;(p=document.getElementById(`lucent-tokens-${i}`))==null||p.remove()}},[i,c]),t.jsx(Mt.Provider,{value:{theme:e,tokens:l},children:r})}function yo(){return f.useContext(Mt)}const xo={bgBase:{description:"Main page/canvas background. The lowest elevation layer — everything sits on top of this.",lightGuidance:"Near-white. Typically #ffffff or a very faint tint (L > 0.96).",darkGuidance:"Near-black with a subtle cool or warm tint. Typically L 0.07–0.10 (e.g. #0f0f11, #111318).",derives:["bgSubtle"]},surface:{description:'Component surface color. Used for cards, input backgrounds, table rows, list items — any component that "floats" above the page canvas.',lightGuidance:"Very slightly off-white — just enough to read as distinct from bgBase. Typically L 0.96–0.98 (e.g. #f9fafb, #f8f8f8).",darkGuidance:"Slightly lighter than bgBase. Typically L 0.11–0.15 (e.g. #1a1a1e, #18181b).",derives:["surfaceSecondary","surfaceRaised","surfaceOverlay"]},borderDefault:{description:"Default border and divider color. Used on input outlines, card borders, table cell borders, section dividers.",lightGuidance:"A mid-light gray. Enough contrast to be legible on bgBase, not so dark it draws attention. Typically L 0.85–0.92 (e.g. #e5e7eb, #d1d5db).",darkGuidance:"A dim gray that reads against dark surfaces. Typically L 0.18–0.26 (e.g. #2d2d35, #374151).",derives:["borderSubtle","borderStrong"]},textPrimary:{description:"Primary body text. High contrast against bgBase — the default color for headings, labels, and body copy.",lightGuidance:"Very dark — near-black. Typically L 0.04–0.15 (e.g. #111827, #0f172a). Must pass WCAG AA against bgBase.",darkGuidance:"Very light — near-white. Typically L 0.88–0.96 (e.g. #f9fafb, #e2e8f0). Must pass WCAG AA against bgBase.",derives:["textSecondary","textDisabled"]},accentDefault:{description:"Primary brand/action color. Drives the visual identity — used on primary buttons, active nav links, focus rings, badges, and progress indicators.",lightGuidance:"Pick a color with enough contrast against both bgBase (white) and textOnAccent (computed automatically). Saturated mid-tones work well. E.g. indigo #6366f1, violet #8b5cf6, emerald #10b981. Monochrome default is #111827 (near-black).",darkGuidance:"In dark mode the accent typically lightens so it stays visible. This is handled automatically via deriveDarkFromLight() — you can supply the same light-mode accent and the dark variant is computed.",derives:["accentHover","accentActive","accentSubtle","accentBorder","textOnAccent"]},successDefault:{description:'Positive/success state color. Used on success alerts, completed step indicators, "online" status badges, and confirmation toasts.',lightGuidance:"A readable green in the mid-to-dark range. E.g. #22c55e (Tailwind green-500), #16a34a (green-600). Avoid very pale greens — they fail WCAG against white.",darkGuidance:"Slightly lighter than the light-mode value so it reads against dark surfaces. createTheme() handles this automatically.",derives:["successSubtle","successText"]},warningDefault:{description:'Cautionary/warning state color. Used on warning banners, pending/in-review badges, and "needs attention" indicators.',lightGuidance:"An amber or orange-yellow. E.g. #f59e0b (Tailwind amber-500), #d97706 (amber-600). Avoid pure yellow — insufficient contrast on white.",darkGuidance:"Slightly lighter than light-mode. createTheme() handles this automatically.",derives:["warningSubtle","warningText"]},dangerDefault:{description:'Error/destructive state color. Used on error messages, delete-confirmation buttons, form field errors, and "offline" or "failed" status.',lightGuidance:"A mid-to-dark red. E.g. #ef4444 (Tailwind red-500), #dc2626 (red-600).",darkGuidance:"Slightly lighter than light-mode. createTheme() handles this automatically.",derives:["dangerHover","dangerSubtle","dangerText"]},infoDefault:{description:'Neutral informational state color. Used on info banners, help tooltips, "new feature" callouts, and link colors in some contexts.',lightGuidance:"A mid blue. E.g. #3b82f6 (Tailwind blue-500), #2563eb (blue-600).",darkGuidance:"Slightly lighter than light-mode. createTheme() handles this automatically.",derives:["infoSubtle","infoText"]}},wo={id:"lucent-provider",name:"LucentProvider",tier:"provider",domain:"neutral",specVersion:"1.0",description:"Root configuration wrapper that injects Lucent design tokens as CSS custom properties. Accepts a design preset for instant theming, 9 anchor colors (via `anchors`) for zero-config theming, or granular token overrides (via `tokens`) for full control.",designIntent:'LucentProvider is the single source of truth for the visual identity of any Lucent-powered UI. Its primary design goal is to make custom theming accessible to both humans and LLMs with minimal effort.\n\nPRESET MODE (fastest path): Pass `preset` with a named preset ("modern", "enterprise", "playful") or an object mixing dimensions: `{ palette: "indigo", shape: "pill", density: "compact", shadow: "elevated" }`. Presets bundle palette colors, border radius, spacing, and shadows into one cohesive design. Available palettes: default, brand, indigo, emerald, rose, ocean. Shapes: sharp, rounded, pill. Densities: compact, default, spacious. Shadows: flat, subtle, elevated. Presets work with both light and dark themes automatically.\n\nANCHOR MODE (recommended for LLMs building custom themes): Pass `anchors` with 9 semantic colors and the provider automatically derives all 30+ variant tokens — hover/active/subtle states, WCAG-compliant contrast text, status subtle tints, surface elevation steps, and more. An LLM generating a themed UI only needs to reason about 9 colors, not the full token surface.\n\nTOKEN MODE (for granular control): Pass `tokens` as a partial override object. Any token not supplied falls back to the base light or dark theme. Derivation still runs — e.g. if you supply only `accentDefault`, the provider auto-derives `accentHover`, `accentActive`, `accentSubtle`, `accentBorder`, and `textOnAccent`.\n\nPRECEDENCE (later wins): base theme → preset → anchors → tokens. You can combine preset with tokens to start from a preset and tweak individual values.\n\nWCAG auto-computation: `textOnAccent` is always computed from the resolved accent color via relative luminance — it will be #000000 or #ffffff, whichever passes AA contrast. Consumers can override it if they have brand-specific requirements.\n\nDARK MODE: Pass `theme="dark"` alongside any prop. Presets include both light and dark palettes. Anchor colors are applied to the dark base palette; derivation runs with dark-calibrated lightness deltas.\n\nDO NOT nest multiple LucentProviders unless intentionally theming a sub-tree differently (e.g. an inverted sidebar). The outermost provider wins for `:root` CSS vars.',props:[{name:"preset",type:"PresetProp",required:!1,description:'Design preset for instant theming. Pass a combined name ("modern", "enterprise", "playful") or an object to mix dimensions: { palette?: "default"|"brand"|"indigo"|"emerald"|"rose"|"ocean", shape?: "sharp"|"rounded"|"pill", density?: "compact"|"default"|"spacious", shadow?: "flat"|"subtle"|"elevated" }. You can also pass imported preset objects directly for tree-shaking. Precedence: base theme → preset → anchors → tokens.'},{name:"anchors",type:"ThemeAnchors",required:!1,description:"Minimal theming API: supply 9 semantic anchor colors and all variant tokens are derived automatically. See ThemeAnchorsSpec for guidance on each key. When provided alongside a preset, anchors override the preset's palette colors but preset shape/density/shadow tokens are preserved. When provided without a preset, the `tokens` prop is ignored. Keys: bgBase, surface, borderDefault, textPrimary, accentDefault, successDefault, warningDefault, dangerDefault, infoDefault."},{name:"theme",type:"enum",required:!1,default:'"light"',enumValues:["light","dark"],description:'Selects the base token palette. "light" uses lightTokens as the starting point; "dark" uses darkTokens. Applies to both anchor-mode and token-mode.'},{name:"tokens",type:"Partial<LucentTokens>",required:!1,description:"Granular token overrides. Any token not supplied falls back to the base theme. Variant derivation still runs for anchor tokens found in this object (e.g. supplying `accentDefault` auto-derives hover/active/subtle variants). Ignored when `anchors` is provided."},{name:"children",type:"ReactNode",required:!0,description:"The subtree to theme. Typically your entire app, or a section that needs independent theming."}],usageExamples:[{title:"Preset mode — combined preset (simplest)",description:"Pick a curated preset that bundles palette, shape, density, and shadow tokens. Works with both light and dark themes.",code:`import { LucentProvider } from 'lucent-ui';
382
382
 
383
383
  <LucentProvider preset="modern">
384
384
  <App />
@@ -474,6 +474,6 @@ const myTheme = createTheme({
474
474
  <App />
475
475
  </main>
476
476
  </div>
477
- </LucentProvider>`}],compositionGraph:[]},mo={accentDefault:"#e9c96b",accentHover:"#ddb84e",accentActive:"#c9a33b",accentSubtle:"#fef9ec",focusRing:"#e9c96b"};function O(e,n){return{field:e,message:n}}function Mt(e){const n=[];if(typeof e!="object"||e===null)return{valid:!1,errors:[O("manifest","Must be a non-null object")]};const a=e,o=["id","name","description","designIntent","specVersion"];for(const i of o)(typeof a[i]!="string"||a[i].trim()==="")&&n.push(O(i,"Must be a non-empty string"));typeof a.id=="string"&&!/^[a-z][a-z0-9-]*$/.test(a.id)&&n.push(O("id",'Must be kebab-case (e.g. "button", "form-field")'));const r=["atom","molecule","block","flow","overlay","provider"];return r.includes(a.tier)||n.push(O("tier",`Must be one of: ${r.join(", ")}`)),(typeof a.domain!="string"||a.domain.trim()==="")&&n.push(O("domain","Must be a non-empty string")),Array.isArray(a.props)?a.props.forEach((i,s)=>{const l=i,c=`props[${s}]`;(typeof l.name!="string"||l.name==="")&&n.push(O(`${c}.name`,"Must be a non-empty string")),(typeof l.type!="string"||l.type==="")&&n.push(O(`${c}.type`,"Must be a non-empty string")),typeof l.required!="boolean"&&n.push(O(`${c}.required`,"Must be a boolean")),(typeof l.description!="string"||l.description==="")&&n.push(O(`${c}.description`,"Must be a non-empty string"))}):n.push(O("props","Must be an array")),Array.isArray(a.usageExamples)?a.usageExamples.length===0?n.push(O("usageExamples","Must have at least one example")):a.usageExamples.forEach((i,s)=>{const l=i,c=`usageExamples[${s}]`;(typeof l.title!="string"||l.title==="")&&n.push(O(`${c}.title`,"Must be a non-empty string")),(typeof l.code!="string"||l.code==="")&&n.push(O(`${c}.code`,"Must be a non-empty string"))}):n.push(O("usageExamples","Must be an array")),Array.isArray(a.compositionGraph)||n.push(O("compositionGraph","Must be an array (empty array is fine for atoms)")),typeof a.specVersion=="string"&&!/^\d+\.\d+$/.test(a.specVersion)&&n.push(O("specVersion",'Must be "MAJOR.MINOR" format, e.g. "0.1"')),{valid:n.length===0,errors:n}}function go(e){const n=Mt(e);if(!n.valid){const a=n.errors.map(o=>` ${o.field}: ${o.message}`).join(`
477
+ </LucentProvider>`}],compositionGraph:[]},ko={accentDefault:"#e9c96b",accentHover:"#ddb84e",accentActive:"#c9a33b",accentSubtle:"#fef9ec",focusRing:"#e9c96b"};function _(e,n){return{field:e,message:n}}function zt(e){const n=[];if(typeof e!="object"||e===null)return{valid:!1,errors:[_("manifest","Must be a non-null object")]};const a=e,o=["id","name","description","designIntent","specVersion"];for(const i of o)(typeof a[i]!="string"||a[i].trim()==="")&&n.push(_(i,"Must be a non-empty string"));typeof a.id=="string"&&!/^[a-z][a-z0-9-]*$/.test(a.id)&&n.push(_("id",'Must be kebab-case (e.g. "button", "form-field")'));const r=["atom","molecule","block","flow","overlay","provider"];return r.includes(a.tier)||n.push(_("tier",`Must be one of: ${r.join(", ")}`)),(typeof a.domain!="string"||a.domain.trim()==="")&&n.push(_("domain","Must be a non-empty string")),Array.isArray(a.props)?a.props.forEach((i,s)=>{const l=i,c=`props[${s}]`;(typeof l.name!="string"||l.name==="")&&n.push(_(`${c}.name`,"Must be a non-empty string")),(typeof l.type!="string"||l.type==="")&&n.push(_(`${c}.type`,"Must be a non-empty string")),typeof l.required!="boolean"&&n.push(_(`${c}.required`,"Must be a boolean")),(typeof l.description!="string"||l.description==="")&&n.push(_(`${c}.description`,"Must be a non-empty string"))}):n.push(_("props","Must be an array")),Array.isArray(a.usageExamples)?a.usageExamples.length===0?n.push(_("usageExamples","Must have at least one example")):a.usageExamples.forEach((i,s)=>{const l=i,c=`usageExamples[${s}]`;(typeof l.title!="string"||l.title==="")&&n.push(_(`${c}.title`,"Must be a non-empty string")),(typeof l.code!="string"||l.code==="")&&n.push(_(`${c}.code`,"Must be a non-empty string"))}):n.push(_("usageExamples","Must be an array")),Array.isArray(a.compositionGraph)||n.push(_("compositionGraph","Must be an array (empty array is fine for atoms)")),typeof a.specVersion=="string"&&!/^\d+\.\d+$/.test(a.specVersion)&&n.push(_("specVersion",'Must be "MAJOR.MINOR" format, e.g. "0.1"')),{valid:n.length===0,errors:n}}function So(e){const n=zt(e);if(!n.valid){const a=n.errors.map(o=>` ${o.field}: ${o.message}`).join(`
478
478
  `);throw new Error(`Invalid ComponentManifest:
479
- ${a}`)}}function bo(e){if(typeof e!="object"||e===null)return!1;const n=e;return typeof n.name=="string"&&typeof n.type=="string"&&typeof n.required=="boolean"&&typeof n.description=="string"}const vo="1.0",yo="0.1.0";exports.Alert=Ra;exports.AlertManifest=La;exports.Avatar=Kt;exports.AvatarManifest=Xt;exports.Badge=Ht;exports.BadgeManifest=Gt;exports.Breadcrumb=Wa;exports.Button=De;exports.ButtonManifest=Ft;exports.COLOR_PICKER_MANIFEST=ua;exports.COLOR_SWATCH_MANIFEST=pa;exports.COMMAND_PALETTE_MANIFEST=nr;exports.Card=Sa;exports.CardBleed=Ta;exports.CardManifest=ja;exports.Checkbox=Ie;exports.CheckboxManifest=rn;exports.CodeBlock=Hn;exports.CodeBlockManifest=Gn;exports.Collapsible=Ha;exports.ColorPicker=gt;exports.ColorSwatch=se;exports.CommandPalette=tr;exports.DATA_TABLE_MANIFEST=Za;exports.DATE_PICKER_MANIFEST=ur;exports.DATE_RANGE_PICKER_MANIFEST=hr;exports.DataTable=Ya;exports.DatePicker=dr;exports.DateRangePicker=fr;exports.Divider=en;exports.DividerManifest=tn;exports.EmptyState=Ba;exports.EmptyStateManifest=qa;exports.FILE_UPLOAD_MANIFEST=vr;exports.FileUpload=br;exports.FormField=ha;exports.FormFieldManifest=ma;exports.Icon=Dn;exports.IconManifest=In;exports.Input=Y;exports.InputManifest=$t;exports.LUCENT_UI_VERSION=yo;exports.LucentProvider=uo;exports.LucentProviderManifest=ho;exports.MANIFEST_SPEC_VERSION=vo;exports.MULTI_SELECT_MANIFEST=or;exports.MultiSelect=rr;exports.NavLink=Bn;exports.PageLayout=Ua;exports.Radio=ln;exports.RadioGroup=ft;exports.RadioGroupUncontrolled=cn;exports.RadioManifest=dn;exports.SEGMENTED_CONTROL_MANIFEST=fa;exports.SearchInput=va;exports.SearchInputManifest=ya;exports.SegmentedControl=Ae;exports.Select=Me;exports.SelectManifest=bn;exports.Skeleton=Na;exports.SkeletonManifest=$a;exports.Slider=Nn;exports.SliderManifest=$n;exports.Spinner=ut;exports.SpinnerManifest=Qt;exports.TIMELINE_MANIFEST=Sr;exports.Table=ne;exports.TableManifest=Zn;exports.Tabs=Oa;exports.Tag=xn;exports.TagManifest=wn;exports.Text=B;exports.TextManifest=Ln;exports.Textarea=dt;exports.TextareaManifest=Wt;exports.ThemeAnchorsSpec=fo;exports.Timeline=kr;exports.Toggle=fn;exports.ToggleManifest=hn;exports.Tooltip=Tn;exports.TooltipManifest=jn;exports.assertManifest=go;exports.brandPalette=wt;exports.brandTokens=mo;exports.compactDensity=Oe;exports.createTheme=Be;exports.darkTokens=Ee;exports.defaultDensity=Ve;exports.defaultPalette=qe;exports.deriveDarkFromLight=yt;exports.deriveTokens=Le;exports.elevatedShadow=_e;exports.emeraldPalette=kt;exports.enterprisePreset=jt;exports.flatShadow=Ge;exports.getContrastText=Re;exports.indigoPalette=Pe;exports.isValidPropDescriptor=bo;exports.lightTokens=ce;exports.makeLibraryCSS=xt;exports.modernPreset=Tt;exports.oceanPalette=St;exports.pillShape=We;exports.playfulPreset=Ct;exports.resolvePreset=Dt;exports.rosePalette=Fe;exports.roundedShape=$e;exports.sharpShape=Ne;exports.spaciousDensity=He;exports.subtleShadow=Ue;exports.useLucent=po;exports.validateManifest=Mt;
479
+ ${a}`)}}function To(e){if(typeof e!="object"||e===null)return!1;const n=e;return typeof n.name=="string"&&typeof n.type=="string"&&typeof n.required=="boolean"&&typeof n.description=="string"}const jo="1.0",Co="0.1.0";exports.Alert=Ra;exports.AlertManifest=La;exports.Avatar=Xt;exports.AvatarManifest=Jt;exports.Badge=Gt;exports.BadgeManifest=Ut;exports.Breadcrumb=Wa;exports.Button=De;exports.ButtonManifest=Nt;exports.COLOR_PICKER_MANIFEST=ua;exports.COLOR_SWATCH_MANIFEST=pa;exports.COMMAND_PALETTE_MANIFEST=nr;exports.Card=Sa;exports.CardBleed=Ta;exports.CardManifest=ja;exports.Checkbox=Ie;exports.CheckboxManifest=on;exports.CodeBlock=Hn;exports.CodeBlockManifest=Gn;exports.Collapsible=Ha;exports.ColorPicker=bt;exports.ColorSwatch=se;exports.CommandPalette=tr;exports.DATA_TABLE_MANIFEST=Za;exports.DATE_PICKER_MANIFEST=gr;exports.DATE_RANGE_PICKER_MANIFEST=wr;exports.DataTable=Ya;exports.DatePicker=mr;exports.DateRangePicker=xr;exports.Divider=tn;exports.DividerManifest=nn;exports.EmptyState=Ba;exports.EmptyStateManifest=qa;exports.FILE_UPLOAD_MANIFEST=jr;exports.FileUpload=Tr;exports.FormField=ha;exports.FormFieldManifest=ma;exports.Icon=Dn;exports.IconManifest=In;exports.Input=K;exports.InputManifest=Wt;exports.LUCENT_UI_VERSION=Co;exports.LucentProvider=vo;exports.LucentProviderManifest=wo;exports.MANIFEST_SPEC_VERSION=jo;exports.MULTI_SELECT_MANIFEST=lr;exports.MultiSelect=sr;exports.NavLink=Bn;exports.PageLayout=Ua;exports.Radio=cn;exports.RadioGroup=ft;exports.RadioGroupUncontrolled=dn;exports.RadioManifest=un;exports.SEGMENTED_CONTROL_MANIFEST=fa;exports.SearchInput=va;exports.SearchInputManifest=ya;exports.SegmentedControl=ze;exports.Select=Me;exports.SelectManifest=vn;exports.Skeleton=Na;exports.SkeletonManifest=$a;exports.Slider=Nn;exports.SliderManifest=$n;exports.Spinner=ut;exports.SpinnerManifest=en;exports.TIMELINE_MANIFEST=zr;exports.Table=ae;exports.TableManifest=Zn;exports.Tabs=Oa;exports.Tag=ht;exports.TagManifest=wn;exports.Text=P;exports.TextManifest=Ln;exports.Textarea=dt;exports.TextareaManifest=Ot;exports.ThemeAnchorsSpec=xo;exports.Timeline=Mr;exports.Toggle=hn;exports.ToggleManifest=mn;exports.Tooltip=Tn;exports.TooltipManifest=jn;exports.assertManifest=So;exports.brandPalette=kt;exports.brandTokens=ko;exports.compactDensity=Oe;exports.createTheme=Be;exports.darkTokens=Ee;exports.defaultDensity=Ve;exports.defaultPalette=qe;exports.deriveDarkFromLight=xt;exports.deriveTokens=Le;exports.elevatedShadow=_e;exports.emeraldPalette=St;exports.enterprisePreset=Ct;exports.flatShadow=Ge;exports.getContrastText=Re;exports.indigoPalette=Pe;exports.isValidPropDescriptor=To;exports.lightTokens=ce;exports.makeLibraryCSS=wt;exports.modernPreset=jt;exports.oceanPalette=Tt;exports.pillShape=We;exports.playfulPreset=Dt;exports.resolvePreset=It;exports.rosePalette=Fe;exports.roundedShape=$e;exports.sharpShape=Ne;exports.spaciousDensity=He;exports.subtleShadow=Ue;exports.useLucent=yo;exports.validateManifest=zt;