staffa 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +45 -23
  2. package/dist/components/box.d.ts +2 -2
  3. package/dist/components/box.js +3 -4
  4. package/dist/components/button.d.ts +9 -11
  5. package/dist/components/button.js +16 -18
  6. package/dist/components/buttonChooser.d.ts +5 -5
  7. package/dist/components/buttonChooser.js +7 -5
  8. package/dist/components/buttonGroup.d.ts +3 -3
  9. package/dist/components/buttonGroup.js +5 -5
  10. package/dist/components/dialog.d.ts +2 -2
  11. package/dist/components/dialog.js +10 -10
  12. package/dist/components/form.d.ts +4 -4
  13. package/dist/components/form.js +6 -6
  14. package/dist/components/main.d.ts +5 -5
  15. package/dist/components/main.js +28 -40
  16. package/dist/components/menu.d.ts +4 -4
  17. package/dist/components/menu.js +8 -6
  18. package/dist/components/tabs.d.ts +3 -3
  19. package/dist/components/tabs.js +1 -1
  20. package/dist/components/toast.d.ts +1 -3
  21. package/dist/components/toast.js +2 -2
  22. package/dist/components/tooltip.js +2 -2
  23. package/dist/core.d.ts +10 -4
  24. package/dist/core.js +13 -0
  25. package/dist/index.d.ts +19 -65
  26. package/dist/index.js +18 -48
  27. package/dist/staffa.esm.js +1 -1
  28. package/dist/theme.d.ts +0 -7
  29. package/dist/theme.js +37 -14
  30. package/package.json +9 -2
  31. package/src/components/box.ts +5 -5
  32. package/src/components/button.ts +21 -22
  33. package/src/components/buttonChooser.ts +10 -8
  34. package/src/components/buttonGroup.ts +5 -4
  35. package/src/components/dialog.ts +10 -10
  36. package/src/components/form.ts +8 -8
  37. package/src/components/main.ts +31 -40
  38. package/src/components/menu.ts +9 -7
  39. package/src/components/tabs.ts +4 -4
  40. package/src/components/toast.ts +3 -5
  41. package/src/components/tooltip.ts +2 -2
  42. package/src/core.ts +16 -5
  43. package/src/index.ts +21 -76
  44. package/src/theme.ts +36 -22
@@ -1 +1 @@
1
- import C from"aberdeen";var N="staffa:darkMode",re=C.proxy({value:Ae()});function Ae(){try{let e=localStorage.getItem(N);if(e==="dark")return!0;if(e==="light")return!1}catch{}}function J(e){re.value=e;try{e===void 0?localStorage.removeItem(N):localStorage.setItem(N,e?"dark":"light")}catch{}}function P(e=!1){let t=re.value;return t===void 0&&!e?C.darkMode():t}C(()=>{P()?C.insertGlobalCss({":root":"--s-primary:#8b7bff --s-secondary:#ef7fd0 --s-danger:#ff6b6b --s-success:#46d39a --s-warning:#fbbf24 --s-neutral:#3c4352 --s-page:#0e1015 --s-panel:#181b22 --s-raised:#222632 --s-ink:#e8eaf0 --s-on-accent:#0c0a14 --s-focus:rgba(139,123,255,0.45) --s-radius:12px --s-radius-lg:18px --s-shadow: 0 10px 34px rgba(0,0,0,0.5);",":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral":"--s-link:#6db3ff"}):C.insertGlobalCss({":root":"--s-primary:#6c5ce7 --s-secondary:#d6459e --s-danger:#e23b3b --s-success:#1f9d6b --s-warning:#d97706 --s-neutral:#c7ccda --s-page:#f3f4f8 --s-panel:#ffffff --s-raised:#eceef4 --s-ink:#1b1e27 --s-on-accent:#0c0a14 --s-focus:rgba(108,92,231,0.35) --s-radius:12px --s-radius-lg:18px --s-shadow: 0 10px 30px rgba(20,24,40,0.13);",":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral":"--s-link:#2563eb"})});C.setSpacingCssVars();C.insertGlobalCss({":root":"--s-gradient: linear-gradient(135deg, $s-primary, $s-secondary); --s-glow: 0 8px 24px color-mix(in srgb, $s-primary 32%, transparent); --s-page-bg: radial-gradient(120% 80% at 100% 0%, color-mix(in oklab, $s-secondary, transparent 86%), transparent 56%), radial-gradient(120% 80% at 0% 0%, color-mix(in oklab, $s-primary, transparent 87%), transparent 56%), $s-page;",":root, .s-s.base":"--s-a:$s-ink --s-b:$s-page",".s-s.base":"background: $s-page-bg;",".s-s.panel":"--s-a:$s-ink --s-b:$s-panel",".s-s.raised":"--s-a:$s-ink --s-b:$s-raised",".s-s.neutral":"--s-a:$s-ink --s-b:$s-neutral",".s-s.primary":"--s-a:$s-on-accent --s-b:$s-primary",".s-s.secondary":"--s-a:$s-on-accent --s-b:$s-secondary",".s-s.danger":"--s-a:$s-on-accent --s-b:$s-danger",".s-s.success":"--s-a:$s-on-accent --s-b:$s-success",".s-s.warning":"--s-a:$s-on-accent --s-b:$s-warning",".s-s.gradient":"--s-a:$s-on-accent --s-b:$s-primary",":root, .s-s":"--s-fg:$s-a --s-bg:$s-b --s-fg-muted: color-mix(in oklab, $s-fg, $s-bg 42%); --s-fg-faint: color-mix(in oklab, $s-fg, $s-bg 64%); --s-border: color-mix(in oklab, $s-fg, $s-bg 82%); --s-border-strong: color-mix(in oklab, $s-fg, $s-bg 68%); scrollbar-width:thin scrollbar-color: $s-border-strong transparent; background:$s-bg color:$s-fg",".s-s::-webkit-scrollbar, .s-s ::-webkit-scrollbar":"width:10px height:10px",".s-s::-webkit-scrollbar-track, .s-s ::-webkit-scrollbar-track":"background:transparent",".s-s::-webkit-scrollbar-thumb, .s-s ::-webkit-scrollbar-thumb":"background:$s-border-strong border-radius:99px border: 2px solid transparent; background-clip:padding-box",".s-s::-webkit-scrollbar-thumb:hover, .s-s ::-webkit-scrollbar-thumb:hover":"background:$s-fg-faint background-clip:padding-box",".s-s.tonal":"--s-fg:$s-b --s-bg: color-mix(in srgb, $s-b 16%, transparent);",".s-s.outlined":"--s-fg:$s-b --s-bg:inherit background:transparent --s-border: color-mix(in srgb, $s-fg 55%, $s-bg);",".s-s.filled":"--s-fg:$s-a --s-bg:$s-b background:$s-bg;",".s-s.gradient:not(.tonal):not(.outlined)":"background: $s-gradient;",":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral":"--s-accent:$s-primary",".s-s.primary, .s-s.secondary, .s-s.danger, .s-s.success, .s-s.warning, .s-s.gradient":"--s-accent:$s-fg --s-link:$s-fg"});C.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased",a:"color: $s-link; text-decoration:underline text-underline-offset:2px; transition: color 0.12s, filter 0.12s;","a:hover":"filter: brightness(1.15)","input, button, textarea, select":"font:inherit color:inherit","code, kbd, samp, pre":"font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;",code:"background: color-mix(in oklab, $s-fg, $s-bg 86%); padding: 0.12em 0.34em; r:4px font-size:0.9em",pre:"background: color-mix(in oklab, $s-fg, $s-bg 92%); p:$3 r: $s-radius; overflow:auto","pre code":"background:transparent p:0","img, svg, video, canvas":"max-width:100% h:auto",hr:"border:0 border-top: 1px solid $s-border;","::placeholder":"color: $s-fg-faint; opacity:1",":focus-visible":"outline: 2px solid $s-focus; outline-offset:2px",small:"color:$s-fg-muted font-size:0.9em","@media (prefers-reduced-motion: reduce)":{"*, *::before, *::after":"transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important;"}});C.insertGlobalCss({".s-preload, .s-preload *, .s-preload *::before, .s-preload *::after":"transition: none !important; animation: none !important;"});if(typeof document<"u"&&typeof requestAnimationFrame=="function"){let e=document.documentElement;e.classList.add("s-preload"),requestAnimationFrame(()=>requestAnimationFrame(()=>e.classList.remove("s-preload")))}var Oe="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";C.insertGlobalCss({[`${Oe}`]:{"&":"margin:0","&:not(:first-child)":"margin-top:$3"},"h1, h2, h3, h4, h5, h6":{"&":"line-height:1.15 font-weight:700 text-wrap:balance","&:not(:first-child)":"margin-top:1.4em"},h1:"font-size:2em font-weight:800 letter-spacing:-0.022em",h2:"font-size:1.55em letter-spacing:-0.018em",h3:"font-size:1.3em letter-spacing:-0.011em",h4:"font-size:1.1em",h5:"font-size:0.95em letter-spacing:0.005em",h6:"font-size:0.8em fg:$s-fg-muted text-transform:uppercase letter-spacing:0.07em","ul, ol":{"&":"padding-left:1.5em","> li:not(:first-child), li > &:not(:first-child)":"margin-top:$1"},blockquote:"border-left: 3px solid $s-border; padding-left: $3; fg: $s-fg-muted",table:"border-collapse:collapse","th, td":"text-align:left padding: $1 $2; border-bottom: 1px solid $s-border; vertical-align:top",th:"font-weight:600","thead th":"border-bottom: 2px solid $s-border-strong;",dt:"font-weight:600",dd:"margin-left: 1.5em",figcaption:"fg:$s-fg-muted font-size:0.9em margin-top:$1 text-align:center"});import i from"aberdeen";import Ce from"aberdeen";var Ee=0;function S(e="s"){return`${e}-${++Ee}`}function u(e,...t){e!=null&&(typeof e=="function"?e(...t):Ce("rich=",e))}import h from"aberdeen";h.insertGlobalCss({".s-field":{"&":"display:flex flex-direction:column gap:$1","> label":"font-weight:600 font-size:0.9em fg:$s-fg user-select:none"},".s-req":"fg:$s-danger margin-left:2px",".s-help":"font-size:0.82em fg:$s-fg-muted",".s-error":"font-size:0.82em fg:$s-danger",".s-input":{"&":"w:100% bg:$s-panel fg:$s-ink border: 1px solid $s-border; r:$s-radius padding: 0.55em 0.7em; transition: border-color 0.15s, box-shadow 0.15s;","&:hover:not(:disabled)":"border-color:$s-border-strong","&:focus-visible":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus; outline:none","&:disabled":"opacity:0.6 cursor:not-allowed","&[aria-invalid=true]":"border-color:$s-danger"}});function L(e,t){let n=e.id??S("field"),o=()=>!!e.error;h("div.s-field",e.attrs,()=>{h(()=>{e.label!=null&&h(`label for=${n}`,()=>{u(e.label),e.required&&h("span.s-req aria-hidden=true #*")})}),t(n,o),h(()=>{e.help!=null&&!e.error&&h("div.s-help",()=>u(e.help))}),h(()=>{e.error&&h("div.s-error role=alert #",e.error)})})}function I(e,t,n,o){h(`id=${t}`),e.name&&h(`name=${e.name}`),h(()=>{e.disabled&&h("disabled=true")}),h(()=>{e.required&&h("aria-required=true")}),h(()=>h("aria-invalid=",n()?"true":"false")),o&&h("bind=",o)}i.insertGlobalCss({".s-ac":{"&":"position:relative","> .s-control":"display:flex flex-wrap:wrap align-items:center gap:$1 bg:$s-panel fg:$s-ink border: 1px solid $s-border; r:$s-radius padding: 0.3em 0.4em; cursor:text; transition: border-color 0.15s, box-shadow 0.15s;","> .s-control:hover":"border-color:$s-border-strong","> .s-control:focus-within":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus;","&[aria-invalid=true] > .s-control":"border-color:$s-danger",".s-chip":"display:inline-flex align-items:center gap:$1 font-size:0.85em bg:$s-raised border: 1px solid $s-border; r:$s-radius padding: 0.1em 0.2em 0.1em 0.5em;",".s-chip > button":"cursor:pointer border:0 background:transparent fg:$s-fg-muted font-size:1.1em line-height:1 padding: 0 0.2em; r:4px",".s-chip > button:hover":"fg:$s-fg background:$s-border",input:"flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em","> .s-menu":"position:absolute top:100% left:0 right:0 z-index:20 margin-top:4px max-height:15rem overflow-y:auto list-style:none p:$1 margin-bottom:0 bg:$s-panel border: 1px solid $s-border; r:$s-radius box-shadow:$s-shadow","> .s-menu li":"margin:0",".s-option":"padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",".s-option[aria-selected=true]":"background: color-mix(in srgb, $s-fg 10%, transparent);",".s-add":"fg:$s-accent font-style:italic",".s-empty":"padding: 0.45em 0.6em; fg:$s-fg-muted"}});function Te(e){return typeof e=="string"?{value:e,label:e}:{value:e.value,label:e.label??e.value}}function ie(e){let t=S("ac-menu"),n=i.proxy({query:"",open:!1,active:0}),o=()=>(typeof e.options=="function"?e.options():e.options).map(Te),r=()=>{let c=e.bind?.value;return c==null||c===""?[]:Array.isArray(c)?c:[c]},s=c=>o().find(v=>v.value===c)?.label??c;if(!e.multi){let c=e.bind?i.peek(e.bind,"value"):void 0;typeof c=="string"&&c&&(n.query=i.peek(()=>s(c)))}let a=()=>{let c=new Set(r()),v=o();e.multi&&(v=v.filter(g=>!c.has(g.value)));let b=n.query.trim().toLowerCase();return b&&(v=v.filter(g=>g.label.toLowerCase().includes(b))),v},l=(c,v)=>{if(e.multi){let b=Array.isArray(e.bind?.value)?[...e.bind.value]:[];b.includes(c)||b.push(c),e.bind&&(e.bind.value=b),n.query=""}else e.bind&&(e.bind.value=c),n.query=s(c),n.open=!1;n.active=0,v?.focus()},p=c=>{if(!e.bind)return;let v=e.bind.value??[];e.bind.value=v.filter(b=>b!==c)};L(e,(c,v)=>{i("div.s-ac",e.inputAttrs,()=>{i(()=>i("aria-invalid=",v()?"true":"false"));let b;i("div.s-control",()=>{i("click=",()=>b?.focus()),i(()=>{if(e.multi)for(let g of r())i("span.s-chip",()=>{i("span #",i.peek(()=>s(g))),i("button type=button aria-label=",`Remove ${g}`,()=>{i("#\xD7"),i("click=",y=>{y.stopPropagation(),p(g),b?.focus()})})})}),b=i("input type=text role=combobox autocomplete=off",()=>{i(`id=${c} aria-controls=${t} aria-autocomplete=list`),e.placeholder!=null&&i("placeholder=",e.placeholder),e.disabled&&i("disabled=true"),e.required&&i("aria-required=true"),i("bind=",i.ref(n,"query")),i(()=>i("aria-expanded=",n.open?"true":"false")),i(()=>{let y=a()[n.active];i("aria-activedescendant=",n.open&&y?`${t}-opt-${n.active}`:"")}),i("input=",()=>{n.open=!0,n.active=0}),i("focus=",()=>{n.open=!0}),i("blur=",()=>{setTimeout(()=>we(),150)}),i("keydown=",g=>V(g,b))})}),i(()=>{if(!n.open)return;let g=a(),y=n.query.trim(),oe=e.allowCustom!==!1&&y!==""&&!g.some(G=>G.label.toLowerCase()===y.toLowerCase());i("ul.s-menu role=listbox",`id=${t}`,()=>{g.forEach((G,_)=>{i("li.s-option role=option",`id=${t}-opt-${_}`,()=>{i(()=>i("aria-selected=",n.active===_?"true":"false")),i("#",G.label),i("mousedown=",ke=>ke.preventDefault()),i("click=",()=>l(G.value,b)),i("mousemove=",()=>{n.active=_})})}),oe&&i("li.s-option.s-add role=option",()=>{i("#",`Add "${y}"`),i("mousedown=",G=>G.preventDefault()),i("click=",()=>l(y,b))}),g.length===0&&!oe&&i("li.s-empty #No matches")})}),i(()=>{if(e.name)if(e.multi)for(let g of r())i("input type=hidden",()=>{i("name=",e.name),i("value=",g)});else i("input type=hidden",()=>{i("name=",e.name),i("value=",r()[0]??"")})})})});function V(c,v){let b=a(),g=b.length-1;if(c.key==="ArrowDown")c.preventDefault(),n.open=!0,n.active=Math.min(g,n.active+1);else if(c.key==="ArrowUp")c.preventDefault(),n.active=Math.max(0,n.active-1);else if(c.key==="Enter"){c.preventDefault();let y=b[n.active];y?l(y.value,v):e.allowCustom!==!1&&n.query.trim()?l(n.query.trim(),v):n.open&&(n.open=!1)}else if(c.key==="Escape")n.open=!1,e.multi||(n.query=s(r()[0]??""));else if(c.key==="Backspace"&&e.multi&&n.query===""){let y=r();y.length&&p(y[y.length-1])}}function we(){n.open=!1,e.multi?n.query="":e.allowCustom!==!1&&n.query.trim()?l(n.query.trim()):n.query=s(r()[0]??"")}}import q from"aberdeen";q.insertGlobalCss({".s-box":{"&":"display:flex flex-direction:column border: 1px solid $s-border; r: $s-radius-lg; overflow:hidden box-shadow: $s-shadow;","&:not(:first-child)":"margin-top: $3","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border-bottom: 1px solid $s-border; font-weight:600","> footer":"display:flex align-items:center gap:$2 padding: $2 $3; border-top: 1px solid $s-border;","> div":"p:$3 gap:$3"}});function se(e={}){let t=typeof e=="function"?{content:e}:e;q("section.s-box.s-s.panel",t.attrs,()=>{q(()=>{t.header!=null&&q("header.s-s.raised",t.headerAttrs,()=>u(t.header))}),q("div",t.contentAttrs,()=>{t.content&&t.content()}),q(()=>{t.footer!=null&&q("footer.s-s.raised",t.footerAttrs,()=>u(t.footer))})})}import M from"aberdeen";M.insertGlobalCss({".s-btn":{"&":"display:inline-flex align-items:center justify-content:center gap:$2 font-weight:600 line-height:1.2 white-space:nowrap cursor:pointer text-decoration:none border: 1px solid $s-border; r: $s-radius; padding: 0.5em 1em; transition: background 0.15s, border-color 0.15s, color 0.15s, filter 0.15s, box-shadow 0.15s, transform 0.08s;","&:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus;","&:disabled, &[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none filter:saturate(0.6)","&:hover":"filter: brightness(1.08); transform: translateY(-1px)","&.tonal:hover, &.outlined:hover":"background: color-mix(in srgb, $s-b 26%, transparent);","&.gradient:not(.tonal):not(.outlined)":"border:0 box-shadow: $s-glow;","&.gradient:not(.tonal):not(.outlined):hover":"filter: brightness(1.06); box-shadow: 0 10px 28px color-mix(in srgb, $s-primary 42%, transparent); transform: translateY(-1px);","&:active:not(:disabled):not([aria-disabled=true])":"transform: translateY(1px)","&.small, .small > &":"padding: 0.32em 0.7em; font-size:0.85em","&.large, .large > &":"padding: 0.66em 1.3em; font-size:1.1em"}});var Se=/\.(gradient|primary|secondary|neutral|danger|success|warning|base|panel|raised)(\.|\s|$)/;function A(e={}){let t=typeof e=="string"?{text:e}:typeof e=="function"?{content:e}:e,n=t.href!=null?"a":"button",o=t.attrs&&Se.test(t.attrs)?"":".gradient";M(`${n}.s-btn.s-s${o}`,t.attrs,()=>{t.href!=null?(M(`href=${t.href} role=button`),t.disabled&&M("aria-disabled=true")):(M("type=",t.type??"button"),t.disabled&&M("disabled=true")),t.ariaLabel&&M("aria-label=",t.ariaLabel),t.click&&M("click=",t.click),u(t.icon),t.content?t.content():t.text!=null&&M("#",t.text)})}import Q from"aberdeen";import ae from"aberdeen";ae.insertGlobalCss({".s-bgroup":{"&":"display:inline-flex align-items:stretch","&.s-spaced":"gap:$2 flex-wrap:wrap","&.s-vertical":"flex-direction:column","&.s-attached":"gap:0","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child)":"margin-left:-1px","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached:not(.s-vertical) > .s-btn:first-child:not(:last-child)":"border-top-right-radius:0 border-bottom-right-radius:0","&.s-attached:not(.s-vertical) > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-bottom-left-radius:0","&.s-attached.s-vertical > .s-btn:not(:first-child)":"margin-top:-1px","&.s-attached.s-vertical > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached.s-vertical > .s-btn:first-child:not(:last-child)":"border-bottom-left-radius:0 border-bottom-right-radius:0","&.s-attached.s-vertical > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-top-right-radius:0","&.s-attached > .s-btn:hover, &.s-attached > .s-btn:focus-visible":"z-index:1"}});function B(e={}){let n=`.s-${e.layout??"attached"}${e.vertical?".s-vertical":""}`;ae(`div.s-bgroup${n} role=group`,e.attrs,()=>{if(e.buttons)for(let o of e.buttons)A(o);e.content&&e.content()})}function le(e){Q(()=>{let t=e.bind.value;B({attrs:e.attrs,buttons:Object.entries(e.options).map(([n,o])=>({text:typeof o=="string"?o:void 0,content:typeof o=="function"?o:void 0,attrs:t===n?".primary":".neutral .outlined",click:()=>{e.bind.value=e.allowDeselect&&t===n?null:n}}))})}),e.name&&Q(()=>Q(`input type=hidden name=${e.name} value=`,e.bind.value??""))}import m from"aberdeen";m.insertGlobalCss({".s-check":{"&":"display:flex flex-direction:column gap:$1","> label":"display:flex align-items:center gap:$2 cursor:pointer user-select:none","> label:has(input:disabled)":"cursor:not-allowed opacity:0.6",input:"width:1.15em height:1.15em accent-color:$s-accent cursor:inherit m:0"}});function de(e={}){let t=e.id??S("check");m("div.s-check",e.attrs,()=>{m(`label for=${t}`,()=>{m("input type=checkbox",e.inputAttrs,()=>{m(`id=${t}`),e.name&&m(`name=${e.name}`),e.checked&&!e.bind&&m("checked=true"),e.change&&m("change=",e.change),m(()=>{e.disabled&&m("disabled=true")}),m(()=>{e.required&&m("aria-required=true")}),e.bind&&m("bind=",e.bind)}),m(()=>{e.label!=null&&u(e.label),e.required&&m("span.s-req aria-hidden=true #*")})}),m(()=>{e.help!=null&&!e.error&&m("div.s-help",()=>u(e.help))}),m(()=>{e.error&&m("div.s-error role=alert #",e.error)})})}import z from"aberdeen";z.insertGlobalCss({".s-form":{"&":"display:flex flex-direction:column gap:$3","&.grid":"display:grid grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap:$3","&.grid > .s-wide, &.grid > footer":"grid-column: 1 / -1;","> footer":"display:flex align-items:center gap:$2 flex-wrap:wrap margin-top:$1"}});function ce(e={}){let t=typeof e=="function"?{content:e}:e;z("form.s-form",t.attrs,()=>{z(()=>{z(".grid=",t.layout==="grid")}),z("submit=",n=>{if(n.preventDefault(),t.submit){let o=new FormData(n.target),r={};for(let s of new Set(o.keys())){let a=o.getAll(s);r[s]=a.length===1?a[0]:a}t.submit(r,n)}}),t.content&&t.content(),z(()=>{t.actions&&z("footer",t.actionsAttrs,()=>t.actions?.())})})}import d from"aberdeen";import x from"aberdeen";import{matchCurrent as Me}from"aberdeen/route";x.insertGlobalCss({".s-menu-list":"position:fixed z-index:350 min-width:10rem display:flex flex-direction:column p:$1 border: 1px solid $s-border; r:$s-radius-lg box-shadow:$s-shadow overflow-y:auto max-height:min(80vh,28rem) transition: opacity 0.15s, transform 0.15s;",".s-menu-list.hidden":"opacity:0 pointer-events:none transform:translateY(-6px)",".s-menu-item, .s-menu-item-link":"display:flex align-items:center gap:$2 w:100% padding: 0.5em 0.65em; r:$s-radius cursor:pointer text-align:left font-size:0.9em border:0 background:transparent fg:$s-fg text-decoration:none transition: background 0.12s, color 0.12s, transform 0.12s, box-shadow 0.12s;",".s-menu-item:hover:not([aria-disabled=true]):not([aria-current=page]), .s-menu-item-link:hover:not([aria-current=page])":"background: color-mix(in srgb, $s-fg 10%, transparent);",".s-menu-item[aria-current=page], .s-menu-item-link[aria-current=page]":"color:$s-on-accent font-weight:600 background: $s-gradient; box-shadow: 0 3px 10px color-mix(in srgb, $s-primary 38%, transparent);",".s-menu-item[aria-current=page] .s-menu-icon, .s-menu-item-link[aria-current=page] .s-menu-icon":"color:$s-on-accent",".s-menu-item[aria-current=page]:hover, .s-menu-item-link[aria-current=page]:hover":"filter:brightness(1.06)",".s-menu-item:focus-visible, .s-menu-item-link:focus-visible":"outline:none background: color-mix(in srgb, $s-fg 10%, transparent); box-shadow: 0 0 0 2px inset $s-focus;",".s-menu-item[aria-disabled=true], .s-menu-item-link[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none",".s-menu-icon":"fg:$s-fg-muted flex-shrink:0","hr.s-menu-sep":"border:0 height:1px margin: $1 0.6rem; background: linear-gradient(to right, transparent, $s-border-strong 18%, $s-border-strong 82%, transparent);"});function W(e,t){x("keydown=",n=>{if(n.key!=="ArrowDown"&&n.key!=="ArrowUp"&&n.key!=="Home"&&n.key!=="End")return;n.preventDefault();let r=[...n.currentTarget.querySelectorAll(".s-menu-item, .s-menu-item-link")].filter(p=>p.getAttribute("aria-disabled")!=="true");if(!r.length)return;let s=r.indexOf(document.activeElement),a=n.key==="ArrowUp"?-1:1,l=n.key==="Home"?0:n.key==="End"?r.length-1:s<0?a>0?0:r.length-1:(s+a+r.length)%r.length;r[l].focus()});for(let n of e){if(typeof n=="function"){n();continue}if("separator"in n){x("hr.s-menu-sep");continue}x(n.href?"a.s-menu-item-link":"button.s-menu-item type=button",n.attrs,()=>{n.href&&(x("href=",n.href),n.target&&x("target=",n.target),x(()=>{Me(n.href)&&x("aria-current=page")})),n.disabled&&x("aria-disabled=true"),x("click=",o=>{if(n.disabled){o.preventDefault();return}t?.(),n.click?.(o)}),n.icon&&x("span.s-menu-icon",()=>u(n.icon)),u(n.label)})}}var H=x.proxy({opts:null});function j(){let e=H.opts?.anchor;H.opts=null,e?.focus()}function Le(e,t){let n=e.offsetWidth,o=e.offsetHeight,r=window.innerWidth,s=window.innerHeight,a=4,l=t.left;l+n>r-8&&(l=Math.max(8,t.right-n));let p=t.bottom+a;p+o>s-8&&t.top-o-a>=8&&(p=t.top-o-a),e.style.left=Math.max(8,l)+"px",e.style.top=Math.max(8,p)+"px"}x.mount(document.body,()=>{let e=H.opts;if(!e)return;let t=x("div.s-menu-list.s-s.panel create=hidden destroy=hidden",e.dropdownAttrs,()=>{W(e.items,j)}),n=r=>{let s=r.target;!t.contains(s)&&!e.anchor.contains(s)&&j()},o=r=>{(r.key==="Escape"||r.key==="Tab")&&(r.preventDefault(),j())};document.addEventListener("click",n,!0),document.addEventListener("keydown",o,!0),x.clean(()=>{document.removeEventListener("click",n,!0),document.removeEventListener("keydown",o,!0)}),requestAnimationFrame(()=>{document.body.contains(t)&&(Le(t,e.anchor.getBoundingClientRect()),t.querySelector(".s-menu-item:not([aria-disabled=true]), .s-menu-item-link:not([aria-disabled=true])")?.focus())})});function X(e){return H.opts=e,j}function Y(e){let t=null;x.clean(()=>{H.opts?.anchor===t&&j()}),A({icon:()=>x("span aria-hidden=true #\u2630"),ariaLabel:"Open menu",attrs:".neutral .outlined",...e.button,click:n=>{if(t=n.currentTarget,H.opts?.anchor===t){j();return}X({items:e.items,anchor:t,dropdownAttrs:e.dropdownAttrs})}})}d.insertGlobalCss({".s-main":{"&":"display:flex flex-direction:column min-height:100vh max-height:100vh container-type:inline-size","> header":"border-bottom: 1px solid $s-border; position:sticky top:0 z-index:10","> footer":"border-top: 1px solid $s-border; fg:$s-fg-muted","> header > .s-bar, > footer > .s-bar":"display:flex align-items:center width:100% margin-inline:auto gap:$3 padding: $2 $3;","> header .s-header-icon":"display:flex align-items:center font-size:1.4em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent;","> header .s-titles":"display:flex flex-direction:column min-width:0 flex:1","> header .s-title":"font-weight:800 font-size:1.1em line-height:1.2 overflow:hidden text-overflow:ellipsis white-space:nowrap letter-spacing:-0.01em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent; width:fit-content max-width:100%","> header .s-subtitle":"fg:$s-fg-muted font-size:0.85em overflow:hidden text-overflow:ellipsis white-space:nowrap","> header .s-menu":"display:flex align-items:center gap:$2",".s-body":"flex:1 overflow:hidden display:flex flex-direction:row min-height:0 justify-content:center",".s-body-inner":"flex:1 display:flex flex-direction:row min-height:0","&.s-nav-right .s-body-inner":"flex-direction:row-reverse",".s-nav-sep":"width:1px flex-shrink:0 align-self:stretch margin: 0.6rem 0; border:0 background: linear-gradient(to bottom, transparent, $s-border-strong 18%, $s-border-strong 82%, transparent);","> main, .s-body main":"flex:1 overflow-y:auto display:flex flex-direction:column","> main > .s-content, .s-body main > .s-content":"width:100% flex:1 p:$3","> main.s-scroll-y, .s-body main.s-scroll-y":"margin-right:$3"},".s-nav-panel":{"&":"display:flex flex-direction:column overflow-y:auto flex-shrink:0 max-width:228px padding:$3 gap:$1 background:transparent"},".s-main.s-nav-left .s-nav-trigger, .s-main.s-nav-right .s-nav-trigger":"display:none",".s-main.s-nav-btn-only .s-nav-panel":"display:none",".s-main.s-nav-btn-only .s-nav-trigger":"display:flex","@container (max-width: 640px)":{".s-main.s-nav-left .s-nav-panel, .s-main.s-nav-right .s-nav-panel, .s-main .s-nav-sep":"display:none",".s-main.s-nav-left .s-nav-trigger, .s-main.s-nav-right .s-nav-trigger":"display:flex",".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0"}});function pe(e={}){let t=e.nav,n=e.navPosition??"left",o=t!=null&&t.items.length>0,r=o?n==="button"?".s-nav-btn-only":`.s-nav-${n}`:"";d(`div.s-main.s-s.base${r}`,e.attrs,()=>{d(()=>{(e.title!=null||e.subtitle!=null||e.icon!=null||e.menu!=null||o)&&d("header.s-s.raised",e.topbarAttrs,()=>{d("div.s-bar",()=>{d(()=>{e.maxWidth!=null&&d("max-width:",e.maxWidth)}),d(()=>{o&&d("div.s-nav-trigger",()=>{Y({...t,button:{icon:()=>d("span aria-hidden=true #\u2630"),ariaLabel:"Open navigation",attrs:".neutral .outlined .small",...t.button}})})}),d(()=>{e.icon!=null&&d("div.s-header-icon",()=>u(e.icon))}),d("div.s-titles",()=>{d(()=>{e.title!=null&&d("div.s-title",()=>u(e.title))}),d(()=>{e.subtitle!=null&&d("div.s-subtitle",()=>u(e.subtitle))})}),d(()=>{e.menu&&d("div.s-menu",()=>e.menu?.())})})})}),o&&n!=="button"?d("div.s-body",()=>{d("div.s-body-inner",()=>{d(()=>{e.maxWidth!=null&&d("max-width:",e.maxWidth)}),d(`nav.s-nav-panel.s-s.raised.s-nav-${n}`,e.navAttrs,()=>{W(t.items)}),d("div.s-nav-sep aria-hidden=true"),ue(e,!1)})}):ue(e,!0),d(()=>{e.footer!=null&&d("footer",()=>{d("div.s-bar",()=>{d(()=>{e.maxWidth!=null&&d("max-width:",e.maxWidth)}),u(e.footer)})})})})}function ue(e,t){let n=d("main",()=>{d("div.s-content",e.contentAttrs,()=>{t&&d(()=>{e.maxWidth!=null&&d("margin-inline:auto max-width:",e.maxWidth)}),e.content&&e.content()})});Be(n)}function Be(e){if(typeof ResizeObserver>"u")return;let t=()=>e.classList.toggle("s-scroll-y",e.offsetWidth>e.clientWidth),n=new ResizeObserver(t);n.observe(e),e.firstElementChild&&n.observe(e.firstElementChild),t(),d.clean(()=>n.disconnect())}import f from"aberdeen";import F from"aberdeen";function U(e={}){L(e,(t,n)=>{F("input.s-input",e.inputAttrs,()=>{F("type=",e.type??"text"),e.placeholder!=null&&F("placeholder=",e.placeholder),e.autocomplete!=null&&F("autocomplete=",e.autocomplete),e.value!=null&&!e.bind&&F("value=",e.value),e.input&&F("input=",e.input),e.change&&F("change=",e.change),I(e,t,n,e.bind)})})}f.insertGlobalCss({".s-backdrop":{"&":"position:fixed inset:0 z-index:200 display:block background: rgba(0,0,0,0.55); transition: opacity 0.4s ease-in-out;","&.hidden":"opacity:0 pointer-events:none"},".s-dialog":{"&":"position:fixed z-index:200 top:50% left:50% display:flex flex-direction:column transform:translate(-50%,-50%) min-width:20rem max-width:min(90vw,44rem) max-height:min(88vh,800px) border: 1px solid $s-border; r: $s-radius-lg; box-shadow: $s-shadow; overflow:hidden transition: opacity 0.2s ease-out, transform 0.2s ease-out;","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border-bottom: 1px solid $s-border; font-weight:600 flex-shrink:0","> footer":"display:flex align-items:center gap:$2 padding: $2 $3; border-top: 1px solid $s-border; flex-shrink:0","> div":"p:$3 gap:$3 display:flex flex-direction:column overflow-y:auto flex:1 min-height:0","&.hidden":"opacity:0 pointer-events:none transform: translate(-50%, calc(-50% + 20px)); pointer-events:none"}});var D=f.proxy({}),Z=0,qe=f.derive(()=>{let e=Object.keys(D);if(e.length)return e[e.length-1]});f.mount(document.body,()=>{f.onEach(D,({resolve:e,opts:t},n)=>{let o=()=>{delete D[n]};f.clean(()=>{t.onClose?.(),e()});let r=f.derive(()=>qe.value!=n);f("div.s-backdrop create=hidden destroy=hidden .hidden=",r,"click=",()=>{t.allowCancel!==!1&&o()}),f("div.s-dialog.s-s.panel create=hidden destroy=hidden",t.attrs,()=>{f(()=>{t.header!=null&&f("header.s-s.raised",t.headerAttrs,()=>u(t.header))}),f("div",t.contentAttrs,()=>{u(t.content,o)}),f(()=>{t.footer!=null&&f("footer.s-s.raised",t.footerAttrs,()=>u(t.footer))})})})});function K(e){Z||document.addEventListener("keydown",n=>{if(n.key==="Escape"&&e.allowCancel!==!1){let o=f.unproxy(D);for(let r=Z;r>0;r--)if(o[r]){o[r].opts.allowCancel!==!1&&delete D[r];break}}});let t=++Z;return e.cancelWithScope!==!1&&f.clean(()=>{delete D[t]}),new Promise(n=>{D[t]={resolve:n,opts:e}})}function fe(e,t={}){return K({header:"Alert",allowCancel:!0,content:n=>{f("p",()=>{f("#",e)}),B({layout:"spaced",attrs:"align-self:flex-end",content:()=>{A({text:"OK",click:n})}})},...t})}function me(e,t={}){return new Promise(n=>{let o=!1;K({header:"Confirm",allowCancel:!0,content:r=>{f("p",()=>{f("#",e)}),B({layout:"spaced",attrs:"align-self:flex-end",content:()=>{A({text:"Cancel",attrs:".neutral .outlined",click:r}),A({text:"OK",click:()=>{o=!0,r()}})}})},...t,onClose:()=>{n(o),t.onClose?.()}})})}function be(e,t="",n={}){return new Promise(o=>{let r=null;K({header:"Input",allowCancel:!0,content:s=>{f("p",()=>{f("#",e)});let a=f.proxy({value:t});f("form display:contents",()=>{f("submit=",l=>{l.preventDefault(),r=a.value,s()}),U({bind:f.ref(a,"value")}),B({layout:"spaced",attrs:"align-self:flex-end",content:()=>{A({text:"Cancel",attrs:".neutral .outlined",type:"button",click:s}),A({text:"OK",type:"submit"})}})})},...n,onClose:()=>{o(r),n.onClose?.()}})})}import k from"aberdeen";k.insertGlobalCss({".s-select_wrap":{"&":"position:relative display:block",select:"w:100% cursor:pointer padding-right:2.2em; appearance:none","&::after":"content: '\u25BE'; position:absolute right:0.7em top:50%; transform: translateY(-50%); pointer-events:none fg:$s-fg-muted font-size:0.85em"}});function ge(e){L(e,(t,n)=>{k("div.s-select_wrap",e.inputAttrs,()=>{k("select.s-input",()=>{I(e,t,n),k("change=",o=>{e.bind&&(e.bind.value=o.target.value)}),k(()=>{let o=typeof e.options=="function"?e.options():e.options,r=e.bind?.value??"";e.placeholder!=null&&k("option",()=>{k("value= disabled=true hidden=true"),r||k("selected=true"),k("#",e.placeholder)});for(let s of o){let a=typeof s=="string"?{value:s,label:s}:{value:s.value,label:s.label??s.value};k("option",()=>{k("value=",a.value),a.value===r&&k("selected=true"),k("#",a.label)})}})})})})}import $ from"aberdeen";$.insertGlobalCss({".s-tabs":{"&":"display:flex flex-direction:column gap:$3",".s-tablist":"display:flex gap:$1 align-items:stretch overflow-x:auto scrollbar-width:none border-bottom: 1px solid $s-border;",".s-tablist::-webkit-scrollbar":"display:none",".s-tab":"display:inline-flex align-items:center gap:$2 cursor:pointer background:transparent border:0 color: $s-fg-muted; font-weight:600 padding: 0.6em 0.9em; border-bottom: 3px solid transparent; margin-bottom:-1px transition: color 0.15s, background 0.15s, border-color 0.15s;",".s-tab:hover:not(:disabled), .s-tab[aria-selected=true]":"color: $s-fg;",".s-tab:disabled":"opacity:0.5 cursor:not-allowed",".s-tab:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; r: $s-radius;",".s-tab[aria-selected=true]":"border-image: $s-gradient 1;",".s-tabpanel":"display:block"}});function he(e){let t=S("tabs"),n=(s,a)=>s.id??String(a),o=e.bind??$.proxy(n(e.tabs[0]??{label:""},0)),r=(s,a)=>{s.disabled||(o.value=n(s,a))};$("div.s-tabs",e.attrs,()=>{$("div.s-tablist role=tablist",()=>{e.tabs.forEach((s,a)=>{let l=n(s,a);$("button.s-tab type=button role=tab",()=>{$(`id=${t}-tab-${l} aria-controls=${t}-panel-${l}`),$(()=>{let p=o.value===l;$("aria-selected=",p?"true":"false"),$("tabindex=",p?"0":"-1")}),s.disabled&&$("disabled=true"),$("click=",()=>r(s,a)),$("keydown=",p=>ze(p,e.tabs,a,r)),u(s.icon),u(s.label)})})}),$("div.s-tabpanel role=tabpanel",e.contentAttrs,()=>{$(()=>{let s=o.value,a=e.tabs.findIndex((p,V)=>n(p,V)===s),l=e.tabs[a]??e.tabs[0];l&&($(`id=${t}-panel-${n(l,a)} aria-labelledby=${t}-tab-${n(l,a)}`),l.content?.())})})})}function ze(e,t,n,o){let r=n;if(e.key==="ArrowRight"||e.key==="ArrowDown")r=(n+1)%t.length;else if(e.key==="ArrowLeft"||e.key==="ArrowUp")r=(n-1+t.length)%t.length;else if(e.key==="Home")r=0;else if(e.key==="End")r=t.length-1;else return;e.preventDefault();let s=r>=n?1:-1;for(let a=0;a<t.length;a++){let l=t[r];if(l&&!l.disabled){o(l,r),e.currentTarget?.parentElement?.children[r]?.focus();return}r=(r+s+t.length)%t.length}}import E from"aberdeen";E.insertGlobalCss({"textarea.s-input":"resize:vertical min-height:3em line-height:1.45","textarea.s-input.s-autoGrow":"resize:none min-height:2.5em overflow-y:hidden"});function ve(e={}){let t=e.autoGrow!==!1;L(e,(n,o)=>{let r=E("textarea.s-input",e.inputAttrs,()=>{t?(E(".s-autoGrow"),E("input=",s=>{xe(s.currentTarget),e.input&&e.input(s)})):(E("rows=",e.rows??4),E("resize:",e.resize??"vertical"),e.input&&E("input=",e.input)),e.placeholder!=null&&E("placeholder=",e.placeholder),e.value!=null&&!e.bind&&E("value=",e.value),e.change&&E("change=",e.change),I(e,n,o,e.bind)});t&&requestAnimationFrame(()=>xe(r))})}function xe(e){e.style.height="auto",e.style.height=`${e.scrollHeight}px`}import w from"aberdeen";import{grow as Fe,shrink as De}from"aberdeen/transitions";w.insertGlobalCss({".s-toasts":"position:fixed bottom:$3 right:$3 z-index:400 display:flex flex-direction:column gap:$2 pointer-events:none max-width:min(90vw,24rem) w:24rem",".s-toast":{"&":"display:flex align-items:flex-start gap:$2 padding: $3; border: 1px solid $s-border; r:$s-radius box-shadow:$s-shadow pointer-events:auto",".s-toast-body":"display:flex flex-direction:column gap:$1 flex:1 min-width:0",".s-toast-title":"font-weight:700 line-height:1.3",".s-toast-msg":"font-size:0.9em fg:$s-fg-muted line-height:1.4",".s-toast-close":"cursor:pointer border:0 background:transparent fg:$s-fg-muted font-size:1.1em line-height:1 padding: 0 0.15em; r:4px flex-shrink:0 align-self:flex-start",".s-toast-close:hover":"fg:$s-fg",".s-toast-close:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; fg:$s-fg"}});var Ge=0,te=w.proxy({});w.mount(document.body,()=>{w("div.s-toasts aria-live=polite aria-atomic=false",()=>{w.onEach(te,e=>{let{opts:t}=e,n=t.type==="danger"||t.type==="warning"?"alert":"status",o=t.type??"neutral";w(`div.s-toast.s-s.${o} role=${n}`,"create=",Fe,"destroy=",De,t.attrs,()=>{w("div.s-toast-body",()=>{w(()=>{t.title!=null&&w("div.s-toast-title",()=>u(t.title))}),w("div.s-toast-msg",()=>u(t.message))}),w(()=>{t.dismissible!==!1&&w("button.s-toast-close type=button aria-label=Dismiss",()=>{w("#\xD7"),w("click=",()=>ee(e.id))})})})})})});function ee(e){delete te[e]}function ye(e){let t=++Ge;te[t]={id:t,opts:e};let n=e.duration??4e3,o;return n>0&&(o=setTimeout(()=>ee(t),n)),()=>{o!=null&&clearTimeout(o),ee(t)}}import O from"aberdeen";O.insertGlobalCss({".s-tt-tip":{"&":"position:fixed z-index:500 max-width:20rem w:max-content bg:$s-raised fg:$s-fg border: 1px solid $s-border-strong; r:$s-radius box-shadow:$s-shadow padding: 0.3em 0.65em; font-size:0.85em line-height:1.4 pointer-events:none"}});var R=O.proxy(void 0),T=null;typeof window<"u"&&window.addEventListener("scroll",()=>{R.value=void 0},{capture:!0,passive:!0});function Ie(e,t,n,o){let s=window.innerWidth,a=window.innerHeight,l=0,p=0;return o==="bottom"?(l=e.left+(e.width-t)/2,p=e.bottom+7,p+n>a-8&&(p=e.top-n-7)):o==="left"?(l=e.left-t-7,p=e.top+(e.height-n)/2,l<8&&(l=e.right+7)):o==="right"?(l=e.right+7,p=e.top+(e.height-n)/2,l+t>s-8&&(l=e.left-t-7)):(l=e.left+(e.width-t)/2,p=e.top-n-7,p<8&&(p=e.bottom+7)),{x:Math.max(8,Math.min(l,s-t-8)),y:Math.max(8,Math.min(p,a-n-8))}}function ne(){T&&clearTimeout(T),T=setTimeout(()=>{R.value=void 0,T=null},100)}O.mount(document.body,()=>{let e=R.value;if(!e)return;let{opts:t,anchor:n}=e,o=t.placement??"top",r=O("div.s-tt-tip role=tooltip visibility:hidden",t.attrs,()=>{O("mouseenter=",()=>{T&&(clearTimeout(T),T=null)}),O("mouseleave=",ne),u(t.tip)});requestAnimationFrame(()=>{if(!document.body.contains(r))return;let{x:s,y:a}=Ie(n.getBoundingClientRect(),r.offsetWidth,r.offsetHeight,o);r.style.left=s+"px",r.style.top=a+"px",r.style.visibility=""})});function $e(e){let t=n=>{T&&(clearTimeout(T),T=null),R.value={opts:e,anchor:n.currentTarget}};O("mouseenter=",t),O("mouseleave=",ne),O("focusin=",t),O("focusout=",ne),O.clean(()=>{R.value?.opts===e&&(R.value=void 0)})}var je={main:pe,box:se,dialog:K,alert:fe,confirm:me,prompt:be,form:ce,menuButton:Y,showFloatingMenu:X,textline:U,textarea:ve,checkbox:de,tabs:he,button:A,buttonChooser:le,buttonGroup:B,autocomplete:ie,select:ge,toast:ye,addTooltip:$e,setDarkMode:J,getDarkMode:P},pn=je;export{je as S,pn as default,W as drawMenu,u as drawSlot,P as getDarkMode,J as setDarkMode,S as uniqueId};
1
+ import O from"aberdeen";var U="staffa:darkMode",ne=O.proxy({value:ce()});function ce(){try{let e=localStorage.getItem(U);if(e==="dark")return!0;if(e==="light")return!1}catch{}}function ue(e){ne.value=e;try{e===void 0?localStorage.removeItem(U):localStorage.setItem(U,e?"dark":"light")}catch{}}function oe(e=!1){let t=ne.value;return t===void 0&&!e?O.darkMode():t}O(()=>{oe()?O.insertGlobalCss({":root":"--s-primary:#8b7bff --s-secondary:#ef7fd0 --s-danger:#ff6b6b --s-success:#46d39a --s-warning:#fbbf24 --s-neutral: color-mix(in oklab, #3d4047, $s-tint 14%); --s-page: color-mix(in oklab, #0e0f12, $s-tint 5%); --s-panel: color-mix(in oklab, #17181c, $s-tint 6%); --s-raised: color-mix(in oklab, #212327, $s-tint 8%); --s-ink: color-mix(in oklab, #e9eaec, $s-tint 8%); --s-on-accent:#0c0a14 --s-focus: color-mix(in srgb, $s-primary 45%, transparent); --s-radius:12px --s-radius-lg:18px --s-shadow: 0 10px 34px rgba(0,0,0,0.5);",":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral":"--s-link:#6db3ff"}):O.insertGlobalCss({":root":"--s-primary:#6c5ce7 --s-secondary:#d6459e --s-danger:#e23b3b --s-success:#1f9d6b --s-warning:#d97706 --s-neutral: color-mix(in oklab, #c9cbd0, $s-tint 14%); --s-page: color-mix(in oklab, #f3f4f6, $s-tint 5%); --s-panel: color-mix(in oklab, #ffffff, $s-tint 2%); --s-raised: color-mix(in oklab, #edeef0, $s-tint 7%); --s-ink: color-mix(in oklab, #1d1f24, $s-tint 7%); --s-on-accent:#0c0a14 --s-focus: color-mix(in srgb, $s-primary 35%, transparent); --s-radius:12px --s-radius-lg:18px --s-shadow: 0 10px 30px rgba(20,24,40,0.13);",":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral":"--s-link:#2563eb"})});O.setSpacingCssVars();O.insertGlobalCss({":root":"--s-tint: color-mix(in oklab, $s-primary, $s-secondary); --s-gradient: linear-gradient(135deg, $s-primary, $s-secondary); --s-gradient-surface: linear-gradient(170deg, color-mix(in oklab, $s-primary 85%, $s-secondary), color-mix(in oklab, $s-primary 30%, $s-secondary)); --s-glow: 0 5px 16px color-mix(in srgb, $s-primary 26%, transparent); --s-page-bg: radial-gradient(120% 80% at 100% 0%, color-mix(in oklab, $s-secondary, transparent 86%), transparent 56%), radial-gradient(120% 80% at 0% 0%, color-mix(in oklab, $s-primary, transparent 87%), transparent 56%), $s-page;",":root, .s-s.base":"--s-a:$s-ink --s-b:$s-page",".s-s.base":"background: $s-page-bg;",".s-s.panel":"--s-a:$s-ink --s-b:$s-panel",".s-s.raised":"--s-a:$s-ink --s-b:$s-raised",".s-s.neutral":"--s-a:$s-ink --s-b:$s-neutral",".s-s.primary":"--s-a:$s-on-accent --s-b:$s-primary",".s-s.secondary":"--s-a:$s-on-accent --s-b:$s-secondary",".s-s.danger":"--s-a:$s-on-accent --s-b:$s-danger",".s-s.success":"--s-a:$s-on-accent --s-b:$s-success",".s-s.warning":"--s-a:$s-on-accent --s-b:$s-warning",".s-s.gradient":"--s-a:$s-on-accent --s-b:$s-primary",":root, .s-s":"--s-fg:$s-a --s-bg:$s-b --s-fg-muted: color-mix(in oklab, $s-fg, $s-bg 42%); --s-fg-faint: color-mix(in oklab, $s-fg, $s-bg 64%); --s-border: color-mix(in oklab, $s-fg, $s-bg 82%); --s-border-strong: color-mix(in oklab, $s-fg, $s-bg 68%); scrollbar-width:thin scrollbar-color: $s-border-strong transparent; background:$s-bg color:$s-fg",".s-s::-webkit-scrollbar, .s-s ::-webkit-scrollbar":"width:10px height:10px",".s-s::-webkit-scrollbar-track, .s-s ::-webkit-scrollbar-track":"background:transparent",".s-s::-webkit-scrollbar-thumb, .s-s ::-webkit-scrollbar-thumb":"background:$s-border-strong border-radius:99px border: 2px solid transparent; background-clip:padding-box",".s-s::-webkit-scrollbar-thumb:hover, .s-s ::-webkit-scrollbar-thumb:hover":"background:$s-fg-faint background-clip:padding-box",".s-s.tonal":"--s-fg:$s-b --s-bg: color-mix(in srgb, $s-b 16%, transparent);",".s-s.outlined":"--s-fg:$s-b --s-bg:inherit background:transparent --s-border: color-mix(in srgb, $s-fg 55%, $s-bg);",".s-s.filled":"--s-fg:$s-a --s-bg:$s-b background:$s-bg;",".s-s.gradient:not(.tonal):not(.outlined)":"background: $s-gradient-surface;",":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral":"--s-accent:$s-primary",".s-s.primary, .s-s.secondary, .s-s.danger, .s-s.success, .s-s.warning, .s-s.gradient":"--s-accent:$s-fg --s-link:$s-fg"});O.insertGlobalCss({"*, *::before, *::after":"box-sizing:border-box",html:"text-size-adjust:100%",body:"m:0 line-height:1.5 font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased",a:"color: $s-link; text-decoration:underline text-underline-offset:2px; transition: color 0.12s, filter 0.12s;","a:hover":"filter: brightness(1.15)","input, button, textarea, select":"font:inherit color:inherit","code, kbd, samp, pre":"font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;",code:"background: color-mix(in oklab, $s-fg, $s-bg 86%); padding: 0.12em 0.34em; r:4px font-size:0.9em",pre:"background: color-mix(in oklab, $s-fg, $s-bg 92%); p:$3 r: $s-radius; overflow:auto","pre code":"background:transparent p:0","img, svg, video, canvas":"max-width:100% h:auto",hr:"border:0 border-top: 1px solid $s-border;","::placeholder":"color: $s-fg-faint; opacity:1",":focus-visible":"outline: 2px solid $s-focus; outline-offset:2px",small:"color:$s-fg-muted font-size:0.9em","@media (prefers-reduced-motion: reduce)":{"*, *::before, *::after":"transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important;"}});O.insertGlobalCss({".s-preload, .s-preload *, .s-preload *::before, .s-preload *::after":"transition: none !important; animation: none !important;"});if(typeof document<"u"&&typeof requestAnimationFrame=="function"){let e=document.documentElement;e.classList.add("s-preload"),requestAnimationFrame(()=>requestAnimationFrame(()=>e.classList.remove("s-preload")))}var pe="p, ul, ol, dl, blockquote, pre, table, figure, hr, h1, h2, h3, h4, h5, h6";O.insertGlobalCss({[`${pe}`]:{"&":"margin:0","&:not(:first-child)":"margin-top:$3"},"h1, h2, h3, h4, h5, h6":{"&":"line-height:1.15 font-weight:700 text-wrap:balance","&:not(:first-child)":"margin-top:1.4em"},h1:"font-size:2em font-weight:800 letter-spacing:-0.022em",h2:"font-size:1.55em letter-spacing:-0.018em",h3:"font-size:1.3em letter-spacing:-0.011em",h4:"font-size:1.1em",h5:"font-size:0.95em letter-spacing:0.005em",h6:"font-size:0.8em fg:$s-fg-muted text-transform:uppercase letter-spacing:0.07em","ul, ol":{"&":"padding-left:1.5em","> li:not(:first-child), li > &:not(:first-child)":"margin-top:$1"},blockquote:"border-left: 3px solid $s-border; padding-left: $3; fg: $s-fg-muted",table:"border-collapse:collapse","th, td":"text-align:left padding: $1 $2; border-bottom: 1px solid $s-border; vertical-align:top",th:"font-weight:600","thead th":"border-bottom: 2px solid $s-border-strong;",dt:"font-weight:600",dd:"margin-left: 1.5em",figcaption:"fg:$s-fg-muted font-size:0.9em margin-top:$1 text-align:center"});import r from"aberdeen";import ie from"aberdeen";var fe=0;function C(e="s"){return`${e}-${++fe}`}function a(e,...t){e!=null&&(typeof e=="function"?e(...t):ie("rich=",e))}function M(e){let t=document.createElement("div");t.style.display="contents",document.body.appendChild(t),ie.mount(t,e)}import h from"aberdeen";h.insertGlobalCss({".s-field":{"&":"display:flex flex-direction:column gap:$1","> label":"font-weight:600 font-size:0.9em fg:$s-fg user-select:none"},".s-req":"fg:$s-danger margin-left:2px",".s-help":"font-size:0.82em fg:$s-fg-muted",".s-error":"font-size:0.82em fg:$s-danger",".s-input":{"&":"w:100% bg:$s-panel fg:$s-ink border: 1px solid $s-border; r:$s-radius padding: 0.55em 0.7em; transition: border-color 0.15s, box-shadow 0.15s;","&:hover:not(:disabled)":"border-color:$s-border-strong","&:focus-visible":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus; outline:none","&:disabled":"opacity:0.6 cursor:not-allowed","&[aria-invalid=true]":"border-color:$s-danger"}});function L(e,t){let n=e.id??C("field"),i=()=>!!e.error;h("div.s-field",e.attrs,()=>{h(()=>{e.label!=null&&h(`label for=${n}`,()=>{a(e.label),e.required&&h("span.s-req aria-hidden=true #*")})}),t(n,i),h(()=>{e.help!=null&&!e.error&&h("div.s-help",()=>a(e.help))}),h(()=>{e.error&&h("div.s-error role=alert #",e.error)})})}function H(e,t,n,i){h(`id=${t}`),e.name&&h(`name=${e.name}`),h(()=>{e.disabled&&h("disabled=true")}),h(()=>{e.required&&h("aria-required=true")}),h(()=>h("aria-invalid=",n()?"true":"false")),i&&h("bind=",i)}r.insertGlobalCss({".s-ac":{"&":"position:relative","> .s-control":"display:flex flex-wrap:wrap align-items:center gap:$1 bg:$s-panel fg:$s-ink border: 1px solid $s-border; r:$s-radius padding: 0.3em 0.4em; cursor:text; transition: border-color 0.15s, box-shadow 0.15s;","> .s-control:hover":"border-color:$s-border-strong","> .s-control:focus-within":"border-color:$s-accent box-shadow: 0 0 0 3px $s-focus;","&[aria-invalid=true] > .s-control":"border-color:$s-danger",".s-chip":"display:inline-flex align-items:center gap:$1 font-size:0.85em bg:$s-raised border: 1px solid $s-border; r:$s-radius padding: 0.1em 0.2em 0.1em 0.5em;",".s-chip > button":"cursor:pointer border:0 background:transparent fg:$s-fg-muted font-size:1.1em line-height:1 padding: 0 0.2em; r:4px",".s-chip > button:hover":"fg:$s-fg background:$s-border",input:"flex:1 min-width:6ch border:0 background:transparent color:inherit outline:none padding:0.25em","> .s-menu":"position:absolute top:100% left:0 right:0 z-index:20 margin-top:4px max-height:15rem overflow-y:auto list-style:none p:$1 margin-bottom:0 bg:$s-panel border: 1px solid $s-border; r:$s-radius box-shadow:$s-shadow","> .s-menu li":"margin:0",".s-option":"padding: 0.45em 0.6em; r:6px cursor:pointer transition: background 0.1s;",".s-option[aria-selected=true]":"background: color-mix(in srgb, $s-fg 10%, transparent);",".s-add":"fg:$s-accent font-style:italic",".s-empty":"padding: 0.45em 0.6em; fg:$s-fg-muted"}});function me(e){return typeof e=="string"?{value:e,label:e}:{value:e.value,label:e.label??e.value}}function be(e){let t=C("ac-menu"),n=r.proxy({query:"",open:!1,active:0}),i=()=>(typeof e.options=="function"?e.options():e.options).map(me),o=()=>{let c=e.bind?.value;return c==null||c===""?[]:Array.isArray(c)?c:[c]},s=c=>i().find(x=>x.value===c)?.label??c;if(!e.multi){let c=e.bind?r.peek(e.bind,"value"):void 0;typeof c=="string"&&c&&(n.query=r.peek(()=>s(c)))}let l=()=>{let c=new Set(o()),x=i();e.multi&&(x=x.filter(g=>!c.has(g.value)));let b=n.query.trim().toLowerCase();return b&&(x=x.filter(g=>g.label.toLowerCase().includes(b))),x},d=(c,x)=>{if(e.multi){let b=Array.isArray(e.bind?.value)?[...e.bind.value]:[];b.includes(c)||b.push(c),e.bind&&(e.bind.value=b),n.query=""}else e.bind&&(e.bind.value=c),n.query=s(c),n.open=!1;n.active=0,x?.focus()},p=c=>{if(!e.bind)return;let x=e.bind.value??[];e.bind.value=x.filter(b=>b!==c)};L(e,(c,x)=>{r("div.s-ac",e.inputAttrs,()=>{r(()=>r("aria-invalid=",x()?"true":"false"));let b;r("div.s-control",()=>{r("click=",()=>b?.focus()),r(()=>{if(e.multi)for(let g of o())r("span.s-chip",()=>{r("span #",r.peek(()=>s(g))),r("button type=button aria-label=",`Remove ${g}`,()=>{r("#\xD7"),r("click=",y=>{y.stopPropagation(),p(g),b?.focus()})})})}),b=r("input type=text role=combobox autocomplete=off",()=>{r(`id=${c} aria-controls=${t} aria-autocomplete=list`),e.placeholder!=null&&r("placeholder=",e.placeholder),e.disabled&&r("disabled=true"),e.required&&r("aria-required=true"),r("bind=",r.ref(n,"query")),r(()=>r("aria-expanded=",n.open?"true":"false")),r(()=>{let y=l()[n.active];r("aria-activedescendant=",n.open&&y?`${t}-opt-${n.active}`:"")}),r("input=",()=>{n.open=!0,n.active=0}),r("focus=",()=>{n.open=!0}),r("blur=",()=>{setTimeout(()=>le(),150)}),r("keydown=",g=>W(g,b))})}),r(()=>{if(!n.open)return;let g=l(),y=n.query.trim(),te=e.allowCustom!==!1&&y!==""&&!g.some(I=>I.label.toLowerCase()===y.toLowerCase());r("ul.s-menu role=listbox",`id=${t}`,()=>{g.forEach((I,Y)=>{r("li.s-option role=option",`id=${t}-opt-${Y}`,()=>{r(()=>r("aria-selected=",n.active===Y?"true":"false")),r("#",I.label),r("mousedown=",de=>de.preventDefault()),r("click=",()=>d(I.value,b)),r("mousemove=",()=>{n.active=Y})})}),te&&r("li.s-option.s-add role=option",()=>{r("#",`Add "${y}"`),r("mousedown=",I=>I.preventDefault()),r("click=",()=>d(y,b))}),g.length===0&&!te&&r("li.s-empty #No matches")})}),r(()=>{if(e.name)if(e.multi)for(let g of o())r("input type=hidden",()=>{r("name=",e.name),r("value=",g)});else r("input type=hidden",()=>{r("name=",e.name),r("value=",o()[0]??"")})})})});function W(c,x){let b=l(),g=b.length-1;if(c.key==="ArrowDown")c.preventDefault(),n.open=!0,n.active=Math.min(g,n.active+1);else if(c.key==="ArrowUp")c.preventDefault(),n.active=Math.max(0,n.active-1);else if(c.key==="Enter"){c.preventDefault();let y=b[n.active];y?d(y.value,x):e.allowCustom!==!1&&n.query.trim()?d(n.query.trim(),x):n.open&&(n.open=!1)}else if(c.key==="Escape")n.open=!1,e.multi||(n.query=s(o()[0]??""));else if(c.key==="Backspace"&&e.multi&&n.query===""){let y=o();y.length&&p(y[y.length-1])}}function le(){n.open=!1,e.multi?n.query="":e.allowCustom!==!1&&n.query.trim()?d(n.query.trim()):n.query=s(o()[0]??"")}}import q from"aberdeen";q.insertGlobalCss({".s-box":{"&":"display:flex flex-direction:column border: 1px solid $s-border; r: $s-radius-lg; overflow:hidden box-shadow: $s-shadow;","&:not(:first-child)":"margin-top: $3","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border-bottom: 1px solid $s-border; font-weight:600","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border-top: 1px solid $s-border;","> div":"p:$3 gap:$3"}});function ge(e={}){let t=typeof e=="string"||typeof e=="function"?{content:e}:e;q("section.s-box.s-s.panel",t.attrs,()=>{q(()=>{t.header!=null&&q("header.s-s.raised",t.headerAttrs,()=>a(t.header))}),q("div",t.contentAttrs,()=>{a(t.content)}),q(()=>{t.footer!=null&&q("footer.s-s.raised",t.footerAttrs,()=>a(t.footer))})})}import B from"aberdeen";B.insertGlobalCss({".s-btn":{"&":"display:inline-flex align-items:center justify-content:center gap:$2 font-weight:600 line-height:1.2 white-space:nowrap cursor:pointer text-decoration:none border: 1px solid $s-border; r: $s-radius; padding: 0.5em 1em; transition: background 0.15s, border-color 0.15s, color 0.15s, filter 0.15s, box-shadow 0.15s, transform 0.08s;","&:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus;","&:disabled, &[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none filter:saturate(0.6)","&:hover":"filter: brightness(1.08); transform: translateY(-1px)","&.tonal:hover, &.outlined:hover":"background: color-mix(in srgb, $s-b 26%, transparent);","&.gradient:not(.tonal):not(.outlined)":"border:0 box-shadow: inset 0 1px 0 color-mix(in srgb, white 25%, transparent), $s-glow;","&.gradient:not(.tonal):not(.outlined):hover":"filter: brightness(1.05); box-shadow: inset 0 1px 0 color-mix(in srgb, white 25%, transparent), 0 7px 18px color-mix(in srgb, $s-primary 34%, transparent); transform: translateY(-1px);","&:active:not(:disabled):not([aria-disabled=true])":"transform: translateY(1px)","&.small, .small > &":"padding: 0.32em 0.7em; font-size:0.85em","&.large, .large > &":"padding: 0.66em 1.3em; font-size:1.1em"}});var he=/\.(gradient|primary|secondary|neutral|danger|success|warning|base|panel|raised)(\.|\s|$)/;function A(e={}){let t=typeof e=="string"||typeof e=="function"?{content:e}:e,n=t.href!=null?"a":"button",i=t.attrs&&he.test(t.attrs)?"":".gradient";B(`${n}.s-btn.s-s${i}`,t.attrs,()=>{t.href!=null?(B(`href=${t.href} role=button`),t.disabled&&B("aria-disabled=true")):(B("type=",t.type??"button"),t.disabled&&B("disabled=true")),t.ariaLabel&&B("aria-label=",t.ariaLabel),t.click&&B("click=",t.click),a(t.icon),a(t.content)})}import _ from"aberdeen";import re from"aberdeen";re.insertGlobalCss({".s-bgroup":{"&":"display:inline-flex align-items:stretch","&.s-spaced":"gap:$2 flex-wrap:wrap","&.s-vertical":"flex-direction:column","&.s-attached":"gap:0","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child)":"margin-left:-1px","&.s-attached:not(.s-vertical) > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached:not(.s-vertical) > .s-btn:first-child:not(:last-child)":"border-top-right-radius:0 border-bottom-right-radius:0","&.s-attached:not(.s-vertical) > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-bottom-left-radius:0","&.s-attached.s-vertical > .s-btn:not(:first-child)":"margin-top:-1px","&.s-attached.s-vertical > .s-btn:not(:first-child):not(:last-child)":"r:0","&.s-attached.s-vertical > .s-btn:first-child:not(:last-child)":"border-bottom-left-radius:0 border-bottom-right-radius:0","&.s-attached.s-vertical > .s-btn:last-child:not(:first-child)":"border-top-left-radius:0 border-top-right-radius:0","&.s-attached > .s-btn:hover, &.s-attached > .s-btn:focus-visible":"z-index:1"}});function z(e={}){let n=`.s-${e.layout??"attached"}${e.vertical?".s-vertical":""}`;re(`div.s-bgroup${n} role=group`,e.attrs,()=>{if(e.buttons)for(let i of e.buttons)A(i);a(e.content)})}function xe(e){_(()=>{let t=e.bind.value;z({attrs:e.attrs,buttons:Object.entries(e.options).map(([n,i])=>({content:i,ariaLabel:typeof i=="function"?n:void 0,attrs:t===n?".primary":".neutral .outlined",click:()=>{e.bind.value=e.allowDeselect&&t===n?void 0:n}}))})}),e.name&&_(()=>_(`input type=hidden name=${e.name} value=`,e.bind.value??""))}import m from"aberdeen";m.insertGlobalCss({".s-check":{"&":"display:flex flex-direction:column gap:$1","> label":"display:flex align-items:center gap:$2 cursor:pointer user-select:none","> label:has(input:disabled)":"cursor:not-allowed opacity:0.6",input:"width:1.15em height:1.15em accent-color:$s-accent cursor:inherit m:0"}});function ve(e={}){let t=e.id??C("check");m("div.s-check",e.attrs,()=>{m(`label for=${t}`,()=>{m("input type=checkbox",e.inputAttrs,()=>{m(`id=${t}`),e.name&&m(`name=${e.name}`),e.checked&&!e.bind&&m("checked=true"),e.change&&m("change=",e.change),m(()=>{e.disabled&&m("disabled=true")}),m(()=>{e.required&&m("aria-required=true")}),e.bind&&m("bind=",e.bind)}),m(()=>{e.label!=null&&a(e.label),e.required&&m("span.s-req aria-hidden=true #*")})}),m(()=>{e.help!=null&&!e.error&&m("div.s-help",()=>a(e.help))}),m(()=>{e.error&&m("div.s-error role=alert #",e.error)})})}import F from"aberdeen";F.insertGlobalCss({".s-form":{"&":"display:flex flex-direction:column gap:$3","&.grid":"display:grid grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap:$3","&.grid > .s-wide, &.grid > footer":"grid-column: 1 / -1;","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 flex-wrap:wrap margin-top:$1"}});function ye(e={}){let t=typeof e=="string"||typeof e=="function"?{content:e}:e;F("form.s-form",t.attrs,()=>{F(()=>{F(".grid=",t.layout==="grid")}),F("submit=",n=>{if(n.preventDefault(),t.submit){let i=new FormData(n.target),o={};for(let s of new Set(i.keys())){let l=i.getAll(s);o[s]=l.length===1?l[0]:l}t.submit(o,n)}}),a(t.content),F(()=>{t.actions&&F("footer",t.actionsAttrs,()=>a(t.actions))})})}import u from"aberdeen";import v from"aberdeen";import{matchCurrent as $e}from"aberdeen/route";v.insertGlobalCss({".s-menu-list":"position:fixed z-index:350 min-width:10rem display:flex flex-direction:column p:$1 border: 1px solid $s-border; r:$s-radius-lg box-shadow:$s-shadow overflow-y:auto max-height:min(80vh,28rem) transition: opacity 0.15s, transform 0.15s;",".s-menu-list.hidden":"opacity:0 pointer-events:none transform:translateY(-6px)",".s-menu-item, .s-menu-item-link":"display:flex align-items:center gap:$2 w:100% padding: 0.5em 0.65em; r:$s-radius cursor:pointer text-align:left font-size:0.9em border:0 background:transparent fg:$s-fg text-decoration:none transition: background 0.12s, color 0.12s, transform 0.12s, box-shadow 0.12s;",".s-menu-item:hover:not([aria-disabled=true]):not([aria-current=page]), .s-menu-item-link:hover:not([aria-current=page])":"background: color-mix(in srgb, $s-fg 10%, transparent);",".s-menu-item[aria-current=page], .s-menu-item-link[aria-current=page]":"color:$s-on-accent font-weight:600 background: $s-gradient; box-shadow: 0 3px 10px color-mix(in srgb, $s-primary 38%, transparent);",".s-menu-item[aria-current=page] .s-menu-icon, .s-menu-item-link[aria-current=page] .s-menu-icon":"color:$s-on-accent",".s-menu-item[aria-current=page]:hover, .s-menu-item-link[aria-current=page]:hover":"filter:brightness(1.06)",".s-menu-item:focus-visible, .s-menu-item-link:focus-visible":"outline:none background: color-mix(in srgb, $s-fg 10%, transparent); box-shadow: 0 0 0 2px inset $s-focus;",".s-menu-item[aria-disabled=true], .s-menu-item-link[aria-disabled=true]":"opacity:0.45 cursor:not-allowed pointer-events:none",".s-menu-icon":"fg:$s-fg-muted flex-shrink:0","hr.s-menu-sep":"border:0 height:1px margin: $1 0.6rem; background: linear-gradient(to right, transparent, $s-border-strong 18%, $s-border-strong 82%, transparent);"});function N(e,t){v("keydown=",n=>{if(n.key!=="ArrowDown"&&n.key!=="ArrowUp"&&n.key!=="Home"&&n.key!=="End")return;n.preventDefault();let o=[...n.currentTarget.querySelectorAll(".s-menu-item, .s-menu-item-link")].filter(p=>p.getAttribute("aria-disabled")!=="true");if(!o.length)return;let s=o.indexOf(document.activeElement),l=n.key==="ArrowUp"?-1:1,d=n.key==="Home"?0:n.key==="End"?o.length-1:s<0?l>0?0:o.length-1:(s+l+o.length)%o.length;o[d].focus()});for(let n of e){if(typeof n=="string"||typeof n=="function"){a(n);continue}if("separator"in n){v("hr.s-menu-sep");continue}v(n.href?"a.s-menu-item-link":"button.s-menu-item type=button",n.attrs,()=>{n.href&&(v("href=",n.href),n.target&&v("target=",n.target),v(()=>{$e(n.href)&&v("aria-current=page")})),n.disabled&&v("aria-disabled=true"),v("click=",i=>{if(n.disabled){i.preventDefault();return}t?.(),n.click?.(i)}),n.icon&&v("span.s-menu-icon",()=>a(n.icon)),a(n.label)})}}var R=v.proxy({opts:null});function P(){let e=R.opts?.anchor;R.opts=null,e?.focus()}function we(e,t){let n=e.offsetWidth,i=e.offsetHeight,o=window.innerWidth,s=window.innerHeight,l=4,d=t.left;d+n>o-8&&(d=Math.max(8,t.right-n));let p=t.bottom+l;p+i>s-8&&t.top-i-l>=8&&(p=t.top-i-l),e.style.left=Math.max(8,d)+"px",e.style.top=Math.max(8,p)+"px"}M(()=>{let e=R.opts;if(!e)return;let t=v("div.s-menu-list.s-s.panel create=hidden destroy=hidden",e.dropdownAttrs,()=>{N(e.items,P)}),n=o=>{let s=o.target;!t.contains(s)&&!e.anchor.contains(s)&&P()},i=o=>{(o.key==="Escape"||o.key==="Tab")&&(o.preventDefault(),P())};document.addEventListener("click",n,!0),document.addEventListener("keydown",i,!0),v.clean(()=>{document.removeEventListener("click",n,!0),document.removeEventListener("keydown",i,!0)}),requestAnimationFrame(()=>{document.body.contains(t)&&(we(t,e.anchor.getBoundingClientRect()),t.querySelector(".s-menu-item:not([aria-disabled=true]), .s-menu-item-link:not([aria-disabled=true])")?.focus())})});function se(e){return R.opts=e,P}function V(e){let t=null;v.clean(()=>{R.opts?.anchor===t&&P()}),A({icon:()=>v("span aria-hidden=true #\u2630"),...e.button?.content==null?{ariaLabel:"Open menu"}:null,attrs:".neutral .outlined",...e.button,click:n=>{if(t=n.currentTarget,R.opts?.anchor===t){P();return}se({items:e.items,anchor:t,dropdownAttrs:e.dropdownAttrs})}})}u.insertGlobalCss({".s-main":{"&":"display:flex flex-direction:column min-height:100vh max-height:100vh container-type:inline-size","> header":"border-bottom: 1px solid $s-border; position:sticky top:0 z-index:10","> footer":"border-top: 1px solid $s-border; fg:$s-fg-muted","> header > .s-bar, > footer > .s-bar":"display:flex align-items:center width:100% margin-inline:auto gap:$3 padding: $2 $3;","> header .s-header-icon":"display:flex align-items:center font-size:1.4em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent;","> header .s-titles":"display:flex flex-direction:column min-width:0 flex:1","> header .s-title":"font-weight:800 font-size:1.1em line-height:1.2 overflow:hidden text-overflow:ellipsis white-space:nowrap letter-spacing:-0.01em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent; width:fit-content max-width:100%","> header .s-subtitle":"fg:$s-fg-muted font-size:0.85em overflow:hidden text-overflow:ellipsis white-space:nowrap","> header .s-menu":"display:flex align-items:center gap:$2",".s-body":"flex:1 overflow:hidden display:flex flex-direction:row min-height:0 justify-content:center",".s-body-inner":"flex:1 display:flex flex-direction:row min-height:0","&.s-nav-right .s-body-inner":"flex-direction:row-reverse",".s-nav-sep":"width:1px flex-shrink:0 align-self:stretch margin: 0.6rem 0; border:0 background: linear-gradient(to bottom, transparent, $s-border-strong 18%, $s-border-strong 82%, transparent);",".s-body main":"flex:1 min-height:0 overflow-y:auto display:flex flex-direction:column",".s-body main > .s-content":"width:100% flex:1 p:$3",".s-body main.s-scroll-y":"margin-right:$3"},".s-nav-panel":{"&":"display:flex flex-direction:column overflow-y:auto flex-shrink:0 max-width:228px padding:$3 gap:$1 background:transparent"},".s-main.s-nav-left .s-nav-trigger, .s-main.s-nav-right .s-nav-trigger":"display:none",".s-main.s-nav-btn-only .s-nav-panel":"display:none",".s-main.s-nav-btn-only .s-nav-trigger":"display:flex","@container (max-width: 640px)":{".s-main.s-nav-left .s-nav-panel, .s-main.s-nav-right .s-nav-panel, .s-main .s-nav-sep":"display:none",".s-main.s-nav-left .s-nav-trigger, .s-main.s-nav-right .s-nav-trigger":"display:flex",".s-content > .s-box":"margin-inline: calc(-1 * $3); r:0 border-inline:0",".s-main .s-body main.s-scroll-y":"margin-right:0"}});function ke(e={}){let t=e.nav,n=e.navPosition??"left",i=t!=null&&t.items.length>0,o=i?n==="button"?".s-nav-btn-only":`.s-nav-${n}`:"";u(`div.s-main.s-s.base${o}`,e.attrs,()=>{u(()=>{(e.title!=null||e.subtitle!=null||e.icon!=null||e.menu!=null||i)&&u("header.s-s.raised",e.topbarAttrs,()=>{u("div.s-bar",()=>{u(()=>{e.maxWidth!=null&&u("max-width:",e.maxWidth)}),u(()=>{i&&u("div.s-nav-trigger",()=>{V({...t,button:{icon:()=>u("span aria-hidden=true #\u2630"),ariaLabel:"Open navigation",attrs:".neutral .outlined .small",...t.button}})})}),u(()=>{e.icon!=null&&u("div.s-header-icon",()=>a(e.icon))}),u("div.s-titles",()=>{u(()=>{e.title!=null&&u("div.s-title",()=>a(e.title))}),u(()=>{e.subtitle!=null&&u("div.s-subtitle",()=>a(e.subtitle))})}),u(()=>{e.menu&&u("div.s-menu",()=>a(e.menu))})})})}),u("div.s-body",()=>{u("div.s-body-inner",()=>{u(()=>{e.maxWidth!=null&&u("max-width:",e.maxWidth)}),i&&n!=="button"&&(u(`nav.s-nav-panel.s-s.raised.s-nav-${n}`,e.navAttrs,()=>{N(t.items)}),u("div.s-nav-sep aria-hidden=true")),Ae(e)})}),u(()=>{e.footer!=null&&u("footer",()=>{u("div.s-bar",()=>{u(()=>{e.maxWidth!=null&&u("max-width:",e.maxWidth)}),a(e.footer)})})})})}function Ae(e){let t=u("main",()=>{u("div.s-content",e.contentAttrs,()=>{a(e.content)})});Oe(t)}function Oe(e){if(typeof ResizeObserver>"u")return;let t=()=>e.classList.toggle("s-scroll-y",e.offsetWidth>e.clientWidth),n=new ResizeObserver(t);n.observe(e),e.firstElementChild&&n.observe(e.firstElementChild),t(),u.clean(()=>n.disconnect())}import f from"aberdeen";import G from"aberdeen";function J(e={}){L(e,(t,n)=>{G("input.s-input",e.inputAttrs,()=>{G("type=",e.type??"text"),e.placeholder!=null&&G("placeholder=",e.placeholder),e.autocomplete!=null&&G("autocomplete=",e.autocomplete),e.value!=null&&!e.bind&&G("value=",e.value),e.input&&G("input=",e.input),e.change&&G("change=",e.change),H(e,t,n,e.bind)})})}f.insertGlobalCss({".s-backdrop":{"&":"position:fixed inset:0 z-index:200 display:block background: rgba(0,0,0,0.55); transition: opacity 0.4s ease-in-out;","&.hidden":"opacity:0 pointer-events:none"},".s-dialog":{"&":"position:fixed z-index:200 top:50% left:50% display:flex flex-direction:column transform:translate(-50%,-50%) min-width:20rem max-width:min(90vw,44rem) max-height:min(88vh,800px) border: 1px solid $s-border; r: $s-radius-lg; box-shadow: $s-shadow; overflow:hidden transition: opacity 0.2s ease-out, transform 0.2s ease-out;","> header":"display:flex align-items:center gap:$2 padding: $2 $3; border-bottom: 1px solid $s-border; font-weight:600 flex-shrink:0","> footer":"display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border-top: 1px solid $s-border; flex-shrink:0","> div":"p:$3 gap:$3 display:flex flex-direction:column overflow-y:auto flex:1 min-height:0","&.hidden":"opacity:0 pointer-events:none transform: translate(-50%, calc(-50% + 20px)); pointer-events:none"}});var D=f.proxy({}),Q=0,Se=f.derive(()=>{let e=Object.keys(D);if(e.length)return e[e.length-1]});M(()=>{f.onEach(D,({resolve:e,opts:t},n)=>{let i=()=>{delete D[n]};f.clean(()=>{t.onClose?.(),e()});let o=f.derive(()=>Se.value!=n);f("div.s-backdrop create=hidden destroy=hidden .hidden=",o,"click=",()=>{t.allowCancel!==!1&&i()}),f("div.s-dialog.s-s.panel create=hidden destroy=hidden",t.attrs,()=>{f(()=>{t.header!=null&&f("header.s-s.raised",t.headerAttrs,()=>a(t.header))}),f("div",t.contentAttrs,()=>{a(t.content,i)}),f(()=>{t.footer!=null&&f("footer.s-s.raised",t.footerAttrs,()=>a(t.footer))})})})});function j(e){Q||document.addEventListener("keydown",n=>{if(n.key==="Escape"&&e.allowCancel!==!1){let i=f.unproxy(D);for(let o=Q;o>0;o--)if(i[o]){i[o].opts.allowCancel!==!1&&delete D[o];break}}});let t=++Q;return e.cancelWithScope!==!1&&f.clean(()=>{delete D[t]}),new Promise(n=>{D[t]={resolve:n,opts:e}})}function Ee(e,t={}){return j({header:"Alert",allowCancel:!0,content:n=>{f("p",()=>{f("#",e)}),z({layout:"spaced",attrs:"align-self:flex-end",content:()=>{A({content:"OK",click:n})}})},...t})}function Te(e,t={}){return new Promise(n=>{let i=!1;j({header:"Confirm",allowCancel:!0,content:o=>{f("p",()=>{f("#",e)}),z({layout:"spaced",attrs:"align-self:flex-end",content:()=>{A({content:"Cancel",attrs:".neutral .outlined",click:o}),A({content:"OK",click:()=>{i=!0,o()}})}})},...t,onClose:()=>{n(i),t.onClose?.()}})})}function Ce(e,t="",n={}){return new Promise(i=>{let o=null;j({header:"Input",allowCancel:!0,content:s=>{f("p",()=>{f("#",e)});let l=f.proxy({value:t});f("form display:contents",()=>{f("submit=",d=>{d.preventDefault(),o=l.value,s()}),J({bind:f.ref(l,"value")}),z({layout:"spaced",attrs:"align-self:flex-end",content:()=>{A({content:"Cancel",attrs:".neutral .outlined",type:"button",click:s}),A({content:"OK",type:"submit"})}})})},...n,onClose:()=>{i(o),n.onClose?.()}})})}import w from"aberdeen";w.insertGlobalCss({".s-select_wrap":{"&":"position:relative display:block",select:"w:100% cursor:pointer padding-right:2.2em; appearance:none","&::after":"content: '\u25BE'; position:absolute right:0.7em top:50%; transform: translateY(-50%); pointer-events:none fg:$s-fg-muted font-size:0.85em"}});function Me(e){L(e,(t,n)=>{w("div.s-select_wrap",e.inputAttrs,()=>{w("select.s-input",()=>{H(e,t,n),w("change=",i=>{e.bind&&(e.bind.value=i.target.value)}),w(()=>{let i=typeof e.options=="function"?e.options():e.options,o=e.bind?.value??"";e.placeholder!=null&&w("option",()=>{w("value= disabled=true hidden=true"),o||w("selected=true"),w("#",e.placeholder)});for(let s of i){let l=typeof s=="string"?{value:s,label:s}:{value:s.value,label:s.label??s.value};w("option",()=>{w("value=",l.value),l.value===o&&w("selected=true"),w("#",l.label)})}})})})})}import $ from"aberdeen";$.insertGlobalCss({".s-tabs":{"&":"display:flex flex-direction:column gap:$3",".s-tablist":"display:flex gap:$1 align-items:stretch overflow-x:auto scrollbar-width:none border-bottom: 1px solid $s-border;",".s-tablist::-webkit-scrollbar":"display:none",".s-tab":"display:inline-flex align-items:center gap:$2 cursor:pointer background:transparent border:0 color: $s-fg-muted; font-weight:600 padding: 0.6em 0.9em; border-bottom: 3px solid transparent; margin-bottom:-1px transition: color 0.15s, background 0.15s, border-color 0.15s;",".s-tab:hover:not(:disabled), .s-tab[aria-selected=true]":"color: $s-fg;",".s-tab:disabled":"opacity:0.5 cursor:not-allowed",".s-tab:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; r: $s-radius;",".s-tab[aria-selected=true]":"border-image: $s-gradient 1;",".s-tabpanel":"display:block"}});function Le(e){let t=C("tabs"),n=(s,l)=>s.id??String(l),i=e.bind??$.proxy(n(e.tabs[0]??{label:""},0)),o=(s,l)=>{s.disabled||(i.value=n(s,l))};$("div.s-tabs",e.attrs,()=>{$("div.s-tablist role=tablist",()=>{e.tabs.forEach((s,l)=>{let d=n(s,l);$("button.s-tab type=button role=tab",()=>{$(`id=${t}-tab-${d} aria-controls=${t}-panel-${d}`),$(()=>{let p=i.value===d;$("aria-selected=",p?"true":"false"),$("tabindex=",p?"0":"-1")}),s.disabled&&$("disabled=true"),$("click=",()=>o(s,l)),$("keydown=",p=>Be(p,e.tabs,l,o)),a(s.icon),a(s.label)})})}),$("div.s-tabpanel role=tabpanel",e.contentAttrs,()=>{$(()=>{let s=i.value,l=e.tabs.findIndex((p,W)=>n(p,W)===s),d=e.tabs[l]??e.tabs[0];d&&($(`id=${t}-panel-${n(d,l)} aria-labelledby=${t}-tab-${n(d,l)}`),a(d.content))})})})}function Be(e,t,n,i){let o=n;if(e.key==="ArrowRight"||e.key==="ArrowDown")o=(n+1)%t.length;else if(e.key==="ArrowLeft"||e.key==="ArrowUp")o=(n-1+t.length)%t.length;else if(e.key==="Home")o=0;else if(e.key==="End")o=t.length-1;else return;e.preventDefault();let s=o>=n?1:-1;for(let l=0;l<t.length;l++){let d=t[o];if(d&&!d.disabled){i(d,o),e.currentTarget?.parentElement?.children[o]?.focus();return}o=(o+s+t.length)%t.length}}import S from"aberdeen";S.insertGlobalCss({"textarea.s-input":"resize:vertical min-height:3em line-height:1.45","textarea.s-input.s-autoGrow":"resize:none min-height:2.5em overflow-y:hidden"});function qe(e={}){let t=e.autoGrow!==!1;L(e,(n,i)=>{let o=S("textarea.s-input",e.inputAttrs,()=>{t?(S(".s-autoGrow"),S("input=",s=>{ae(s.currentTarget),e.input&&e.input(s)})):(S("rows=",e.rows??4),S("resize:",e.resize??"vertical"),e.input&&S("input=",e.input)),e.placeholder!=null&&S("placeholder=",e.placeholder),e.value!=null&&!e.bind&&S("value=",e.value),e.change&&S("change=",e.change),H(e,n,i,e.bind)});t&&requestAnimationFrame(()=>ae(o))})}function ae(e){e.style.height="auto",e.style.height=`${e.scrollHeight}px`}import k from"aberdeen";import{grow as ze,shrink as Fe}from"aberdeen/transitions";k.insertGlobalCss({".s-toasts":"position:fixed bottom:$3 right:$3 z-index:400 display:flex flex-direction:column gap:$2 pointer-events:none max-width:min(90vw,24rem) w:24rem",".s-toast":{"&":"display:flex align-items:flex-start gap:$2 padding: $3; border: 1px solid $s-border; r:$s-radius box-shadow:$s-shadow pointer-events:auto",".s-toast-body":"display:flex flex-direction:column gap:$1 flex:1 min-width:0",".s-toast-title":"font-weight:700 line-height:1.3",".s-toast-msg":"font-size:0.9em fg:$s-fg-muted line-height:1.4",".s-toast-close":"cursor:pointer border:0 background:transparent fg:$s-fg-muted font-size:1.1em line-height:1 padding: 0 0.15em; r:4px flex-shrink:0 align-self:flex-start",".s-toast-close:hover":"fg:$s-fg",".s-toast-close:focus-visible":"outline:none box-shadow: 0 0 0 3px $s-focus; fg:$s-fg"}});var Ge=0,Z=k.proxy({});M(()=>{k("div.s-toasts aria-live=polite aria-atomic=false",()=>{k.onEach(Z,e=>{let{opts:t}=e,n=t.type==="danger"||t.type==="warning"?"alert":"status",i=t.type??"neutral";k(`div.s-toast.s-s.${i} role=${n}`,"create=",ze,"destroy=",Fe,t.attrs,()=>{k("div.s-toast-body",()=>{k(()=>{t.title!=null&&k("div.s-toast-title",()=>a(t.title))}),k("div.s-toast-msg",()=>a(t.message))}),k(()=>{t.dismissible!==!1&&k("button.s-toast-close type=button aria-label=Dismiss",()=>{k("#\xD7"),k("click=",()=>X(e.id))})})})})})});function X(e){delete Z[e]}function De(e){let t=++Ge;Z[t]={id:t,opts:e};let n=e.duration??4e3,i;return n>0&&(i=setTimeout(()=>X(t),n)),()=>{i!=null&&clearTimeout(i),X(t)}}import E from"aberdeen";E.insertGlobalCss({".s-tt-tip":{"&":"position:fixed z-index:500 max-width:20rem w:max-content bg:$s-raised fg:$s-fg border: 1px solid $s-border-strong; r:$s-radius box-shadow:$s-shadow padding: 0.3em 0.65em; font-size:0.85em line-height:1.4 pointer-events:none"}});var K=E.proxy(void 0),T=null;typeof window<"u"&&window.addEventListener("scroll",()=>{K.value=void 0},{capture:!0,passive:!0});function Ie(e,t,n,i){let s=window.innerWidth,l=window.innerHeight,d=0,p=0;return i==="bottom"?(d=e.left+(e.width-t)/2,p=e.bottom+7,p+n>l-8&&(p=e.top-n-7)):i==="left"?(d=e.left-t-7,p=e.top+(e.height-n)/2,d<8&&(d=e.right+7)):i==="right"?(d=e.right+7,p=e.top+(e.height-n)/2,d+t>s-8&&(d=e.left-t-7)):(d=e.left+(e.width-t)/2,p=e.top-n-7,p<8&&(p=e.bottom+7)),{x:Math.max(8,Math.min(d,s-t-8)),y:Math.max(8,Math.min(p,l-n-8))}}function ee(){T&&clearTimeout(T),T=setTimeout(()=>{K.value=void 0,T=null},100)}M(()=>{let e=K.value;if(!e)return;let{opts:t,anchor:n}=e,i=t.placement??"top",o=E("div.s-tt-tip role=tooltip visibility:hidden",t.attrs,()=>{E("mouseenter=",()=>{T&&(clearTimeout(T),T=null)}),E("mouseleave=",ee),a(t.tip)});requestAnimationFrame(()=>{if(!document.body.contains(o))return;let{x:s,y:l}=Ie(n.getBoundingClientRect(),o.offsetWidth,o.offsetHeight,i);o.style.left=s+"px",o.style.top=l+"px",o.style.visibility=""})});function He(e){let t=n=>{T&&(clearTimeout(T),T=null),K.value={opts:e,anchor:n.currentTarget}};E("mouseenter=",t),E("mouseleave=",ee),E("focusin=",t),E("focusout=",ee),E.clean(()=>{K.value?.opts===e&&(K.value=void 0)})}export{He as addTooltip,Ee as alert,be as autocomplete,ge as box,A as button,xe as buttonChooser,z as buttonGroup,ve as checkbox,Te as confirm,j as dialog,ye as form,oe as getDarkMode,ke as main,V as menuButton,Ce as prompt,Me as select,ue as setDarkMode,se as showFloatingMenu,Le as tabs,qe as textarea,J as textline,De as toast};
package/dist/theme.d.ts CHANGED
@@ -1,10 +1,3 @@
1
- /**
2
- * The named accent roles for interactive elements (buttons, tabs, badges, …).
3
- * Each maps to a `.s-s.<role>` class that sets `--s-a` (ink) and `--s-b` (fill).
4
- */
5
- export type SurfaceRole = "primary" | "secondary" | "gradient" | "neutral" | "danger" | "success" | "warning";
6
- /** How a surface's two colours are rendered. `filled` is the default. */
7
- export type Variant = "filled" | "tonal" | "outlined";
8
1
  /**
9
2
  * Force dark mode (`true`), light mode (`false`), or follow the OS preference
10
3
  * (`undefined`). Takes effect immediately and is persisted to localStorage.
package/dist/theme.js CHANGED
@@ -38,7 +38,9 @@ import A from "aberdeen";
38
38
  * | `--s-fg-faint` | placeholders, disabled |
39
39
  * | `--s-border` / `--s-border-strong` | borders |
40
40
  * | `--s-accent` | brand "pop" colour (active indicators, etc.) |
41
- * | `--s-gradient` | primary→secondary brand sweep (mark, primary buttons, active nav) |
41
+ * | `--s-gradient` | full primary→secondary brand sweep (mark, active nav) |
42
+ * | `--s-gradient-surface` | compressed sweep for filled gradient surfaces (buttons) |
43
+ * | `--s-tint` | brand mid colour; the hue the neutral greys lean toward |
42
44
  * | `--s-glow` | soft coloured shadow for lit brand elements |
43
45
  * | `--s-link` / `--s-focus` | link & focus-ring colours |
44
46
  * | `--s-radius` / `--s-radius-lg` / `--s-shadow` | shape tokens |
@@ -134,12 +136,22 @@ export function getDarkMode(allowAuto = false) {
134
136
  // names (--s-primary/-danger/-success/-warning) double as semantic *ink*
135
137
  // colours, legible as text/borders on neutral surfaces.
136
138
  // ---------------------------------------------------------------------------
139
+ // The neutral fills/inks aren't hard-coded greys: each one mixes a small dose
140
+ // of `--s-tint` (the brand's mid colour, defined in the static block below)
141
+ // into a true-grey base. Re-skin the brand and every "grey" — page, panels,
142
+ // ink, the neutral fill — drifts subtly toward the new brand hue, light and
143
+ // dark alike. The percentages are deliberately small: a tint you'd only spot
144
+ // in a side-by-side, never a colour cast.
137
145
  A(() => {
138
146
  if (getDarkMode()) {
139
147
  A.insertGlobalCss({
140
148
  ":root": "--s-primary:#8b7bff --s-secondary:#ef7fd0 --s-danger:#ff6b6b --s-success:#46d39a --s-warning:#fbbf24 " +
141
- "--s-neutral:#3c4352 --s-page:#0e1015 --s-panel:#181b22 --s-raised:#222632 " +
142
- "--s-ink:#e8eaf0 --s-on-accent:#0c0a14 --s-focus:rgba(139,123,255,0.45) " +
149
+ "--s-neutral: color-mix(in oklab, #3d4047, $s-tint 14%); " +
150
+ "--s-page: color-mix(in oklab, #0e0f12, $s-tint 5%); " +
151
+ "--s-panel: color-mix(in oklab, #17181c, $s-tint 6%); " +
152
+ "--s-raised: color-mix(in oklab, #212327, $s-tint 8%); " +
153
+ "--s-ink: color-mix(in oklab, #e9eaec, $s-tint 8%); " +
154
+ "--s-on-accent:#0c0a14 --s-focus: color-mix(in srgb, $s-primary 45%, transparent); " +
143
155
  "--s-radius:12px --s-radius-lg:18px --s-shadow: 0 10px 34px rgba(0,0,0,0.5);",
144
156
  // Contextual link, restored across the neutral group (see static block).
145
157
  ":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral": "--s-link:#6db3ff",
@@ -148,8 +160,12 @@ A(() => {
148
160
  else {
149
161
  A.insertGlobalCss({
150
162
  ":root": "--s-primary:#6c5ce7 --s-secondary:#d6459e --s-danger:#e23b3b --s-success:#1f9d6b --s-warning:#d97706 " +
151
- "--s-neutral:#c7ccda --s-page:#f3f4f8 --s-panel:#ffffff --s-raised:#eceef4 " +
152
- "--s-ink:#1b1e27 --s-on-accent:#0c0a14 --s-focus:rgba(108,92,231,0.35) " +
163
+ "--s-neutral: color-mix(in oklab, #c9cbd0, $s-tint 14%); " +
164
+ "--s-page: color-mix(in oklab, #f3f4f6, $s-tint 5%); " +
165
+ "--s-panel: color-mix(in oklab, #ffffff, $s-tint 2%); " +
166
+ "--s-raised: color-mix(in oklab, #edeef0, $s-tint 7%); " +
167
+ "--s-ink: color-mix(in oklab, #1d1f24, $s-tint 7%); " +
168
+ "--s-on-accent:#0c0a14 --s-focus: color-mix(in srgb, $s-primary 35%, transparent); " +
153
169
  "--s-radius:12px --s-radius-lg:18px --s-shadow: 0 10px 30px rgba(20,24,40,0.13);",
154
170
  ":root, .s-s.base, .s-s.panel, .s-s.raised, .s-s.neutral": "--s-link:#2563eb",
155
171
  });
@@ -174,12 +190,18 @@ A.setSpacingCssVars();
174
190
  A.insertGlobalCss({
175
191
  // Derived brand tokens. These only reference the per-mode palette colours, so
176
192
  // they're defined once here and track the active mode (and any re-skin):
177
- // `--s-gradient` is the primary→secondary brand sweep used for the headline
178
- // mark, primary buttons and the active nav pill; `--s-glow` is a soft coloured
179
- // shadow that makes those same elements feel lit; `--s-page-bg` is a faint
193
+ // `--s-tint` is the brand's mid colour, the hue the neutral greys above lean
194
+ // toward; `--s-gradient` is the full primary→secondary sweep used where the
195
+ // brand should *show* (the headline mark, the active nav pill, tab edges);
196
+ // `--s-gradient-surface` is a compressed, near-vertical cut of that same sweep
197
+ // for *filled* gradient surfaces (buttons): it reads as one rich colour with
198
+ // depth rather than a two-colour banner; `--s-glow` is a soft coloured shadow
199
+ // that makes lit brand elements feel raised; `--s-page-bg` is a faint
180
200
  // twin-corner aurora wash painted on the page surface.
181
- ":root": "--s-gradient: linear-gradient(135deg, $s-primary, $s-secondary); " +
182
- "--s-glow: 0 8px 24px color-mix(in srgb, $s-primary 32%, transparent); " +
201
+ ":root": "--s-tint: color-mix(in oklab, $s-primary, $s-secondary); " +
202
+ "--s-gradient: linear-gradient(135deg, $s-primary, $s-secondary); " +
203
+ "--s-gradient-surface: linear-gradient(170deg, color-mix(in oklab, $s-primary 85%, $s-secondary), color-mix(in oklab, $s-primary 30%, $s-secondary)); " +
204
+ "--s-glow: 0 5px 16px color-mix(in srgb, $s-primary 26%, transparent); " +
183
205
  "--s-page-bg: radial-gradient(120% 80% at 100% 0%, color-mix(in oklab, $s-secondary, transparent 86%), transparent 56%), radial-gradient(120% 80% at 0% 0%, color-mix(in oklab, $s-primary, transparent 87%), transparent 56%), $s-page;",
184
206
  // Level/role modifier → anchors. Levels (neutral elevations) use the shared
185
207
  // ink; accent roles use the on-accent ink over their named fill. The page
@@ -231,10 +253,11 @@ A.insertGlobalCss({
231
253
  // overrides a component's default `.tonal`/`.outlined` (resetting both the
232
254
  // anchors and the painted background).
233
255
  ".s-s.filled": "--s-fg:$s-a --s-bg:$s-b background:$s-bg;",
234
- // Paint the brand sweep for a filled `.gradient` surface. Sits after the
235
- // variant rules and is keyed on `:not(.tonal):not(.outlined)`, so those
236
- // variants keep their solid-primary tint/edge.
237
- ".s-s.gradient:not(.tonal):not(.outlined)": "background: $s-gradient;",
256
+ // Paint the brand sweep for a filled `.gradient` surface the compressed
257
+ // surface cut, not the full banner sweep. Sits after the variant rules and is
258
+ // keyed on `:not(.tonal):not(.outlined)`, so those variants keep their
259
+ // solid-primary tint/edge.
260
+ ".s-s.gradient:not(.tonal):not(.outlined)": "background: $s-gradient-surface;",
238
261
  // Contextual accent: the brand pop colour on neutral surfaces. Declared on the
239
262
  // whole neutral group so re-entering a neutral surface under a coloured one
240
263
  // restores it. (--s-link gets the same treatment in the reactive block, where
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "staffa",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "An opinionated component library for the Aberdeen reactive UI library.",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -25,9 +25,11 @@
25
25
  "scripts": {
26
26
  "build:icons": "node scripts/generate-icons.mjs",
27
27
  "build": "npm run build:icons && tsc && tsc -p demo && esbuild src/index.ts --bundle --external:aberdeen --minify --format=esm --outfile=dist/staffa.esm.js",
28
+ "build:skill": "rm -rf skill ; mkdir skill && readme-tsdoc --create src/index.ts --file skill/REFERENCE.md --split && awk '/^@@include /{while((getline line < $2)>0) print line; close($2); next} 1' skill-template.md > skill/SKILL.md && rm skill/REFERENCE.md",
28
29
  "typecheck": "tsc --noEmit && tsc -p demo --noEmit",
29
30
  "smoke": "tsc && node smoke.mjs",
30
- "prepublish": "npm run build"
31
+ "prepublish": "npm run build && shotest test && npm run build:skill",
32
+ "test": "shotest test"
31
33
  },
32
34
  "peerDependencies": {
33
35
  "aberdeen": "^1.17.1"
@@ -35,8 +37,13 @@
35
37
  "devDependencies": {
36
38
  "aberdeen": "^1.17.1",
37
39
  "esbuild": "^0.28.0",
40
+ "http-server": "^14.1.1",
38
41
  "jsdom": "^29.1.1",
39
42
  "lucide-static": "^1.17.0",
43
+ "readme-tsdoc": "^1.2.1",
40
44
  "typescript": "^5.9.3"
45
+ },
46
+ "dependencies": {
47
+ "shotest": "^1.6.1"
41
48
  }
42
49
  }
@@ -1,5 +1,5 @@
1
1
  import A from "aberdeen";
2
- import { type Content, type ContentOptions, type Slot, type Attributes, drawSlot } from "../core.js";
2
+ import { type ContentOptions, type Slot, type Attributes, drawSlot } from "../core.js";
3
3
 
4
4
  /** Options for {@link box}. */
5
5
  export interface BoxOptions extends ContentOptions {
@@ -24,7 +24,7 @@ A.insertGlobalCss({
24
24
  "&": "display:flex flex-direction:column border: 1px solid $s-border; r: $s-radius-lg; overflow:hidden box-shadow: $s-shadow;",
25
25
  "&:not(:first-child)": "margin-top: $3",
26
26
  "> header": "display:flex align-items:center gap:$2 padding: $2 $3; border-bottom: 1px solid $s-border; font-weight:600",
27
- "> footer": "display:flex align-items:center gap:$2 padding: $2 $3; border-top: 1px solid $s-border;",
27
+ "> footer": "display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; border-top: 1px solid $s-border;",
28
28
  "> div": "p:$3 gap:$3",
29
29
  },
30
30
  });
@@ -47,8 +47,8 @@ A.insertGlobalCss({
47
47
  * S.box(() => A("p#Just some content")); // shorthand
48
48
  * ```
49
49
  */
50
- export function box(opts: BoxOptions | Content = {}): void {
51
- const o: BoxOptions = typeof opts === "function" ? { content: opts } : opts;
50
+ export function box(opts: BoxOptions | Slot = {}): void {
51
+ const o: BoxOptions = typeof opts === "string" || typeof opts === "function" ? { content: opts } : opts;
52
52
 
53
53
  A("section.s-box.s-s.panel", o.attrs, () => {
54
54
  // Header and footer get their own scopes so toggling them doesn't recreate
@@ -58,7 +58,7 @@ export function box(opts: BoxOptions | Content = {}): void {
58
58
  });
59
59
 
60
60
  A("div", o.contentAttrs, () => {
61
- if (o.content) o.content();
61
+ drawSlot(o.content);
62
62
  });
63
63
 
64
64
  A(() => {
@@ -1,12 +1,10 @@
1
1
  import A from "aberdeen";
2
- import { type Content, type Slot, type Attributes, drawSlot } from "../core.js";
2
+ import { type Slot, type Attributes, drawSlot } from "../core.js";
3
3
 
4
4
  /** Options for {@link button}. */
5
5
  export interface ButtonOptions {
6
- /** Button label text. */
7
- text?: string;
8
- /** Custom content (overrides {@link ButtonOptions.text | text}). */
9
- content?: Content;
6
+ /** Button content: a string for plain text, or a function for custom markup. */
7
+ content?: Slot;
10
8
  /** Leading icon/adornment, drawn before the label. */
11
9
  icon?: Slot;
12
10
  /** Click handler. */
@@ -49,15 +47,17 @@ A.insertGlobalCss({
49
47
  "&:hover": "filter: brightness(1.08); transform: translateY(-1px)",
50
48
  "&.tonal:hover, &.outlined:hover": "background: color-mix(in srgb, $s-b 26%, transparent);",
51
49
  // A filled `.gradient` button (the default) is the app's signature call to
52
- // action: a borderless gradient with a soft glow that lifts on hover. The
53
- // gradient fill itself comes from the `.s-s.gradient` surface rule in theme.ts.
54
- // No border: a filled gradient reads as one solid shape. Dropping the border
55
- // (rather than making it transparent) also sidesteps a Chromium artifact where
56
- // a gradient clipped to a transparent rounded border fringes the edge with the
57
- // gradient's far colour.
58
- "&.gradient:not(.tonal):not(.outlined)": "border:0 box-shadow: $s-glow;",
50
+ // action: a borderless gradient with a hairline top highlight (a hint of
51
+ // top-lighting that sells the fill as a lit, rounded shape) over a soft glow.
52
+ // The gradient fill itself comes from the `.s-s.gradient` surface rule in
53
+ // theme.ts. No border: a filled gradient reads as one solid shape. Dropping
54
+ // the border (rather than making it transparent) also sidesteps a Chromium
55
+ // artifact where a gradient clipped to a transparent rounded border fringes
56
+ // the edge with the gradient's far colour.
57
+ "&.gradient:not(.tonal):not(.outlined)":
58
+ "border:0 box-shadow: inset 0 1px 0 color-mix(in srgb, white 25%, transparent), $s-glow;",
59
59
  "&.gradient:not(.tonal):not(.outlined):hover":
60
- "filter: brightness(1.06); box-shadow: 0 10px 28px color-mix(in srgb, $s-primary 42%, transparent); transform: translateY(-1px);",
60
+ "filter: brightness(1.05); box-shadow: inset 0 1px 0 color-mix(in srgb, white 25%, transparent), 0 7px 18px color-mix(in srgb, $s-primary 34%, transparent); transform: translateY(-1px);",
61
61
  // Subtle press feedback.
62
62
  "&:active:not(:disabled):not([aria-disabled=true])": "transform: translateY(1px)",
63
63
  // Size: set on the button itself, or inherited from a `.small`/`.large`
@@ -82,19 +82,19 @@ const ROLE_CLASS = /\.(gradient|primary|secondary|neutral|danger|success|warning
82
82
  * startup) for SPA-style navigation without manual click handlers:
83
83
  * ```ts
84
84
  * interceptLinks(); // once at root
85
- * S.button({ href: "/dashboard", text: "Dashboard" }); // navigates via router
85
+ * S.button({ href: "/dashboard", content: "Dashboard" }); // navigates via router
86
86
  * ```
87
87
  *
88
88
  * @example
89
89
  * ```ts
90
- * S.button({ text: "Save", click: save });
91
- * S.button({ text: "Delete", attrs: ".danger .outlined", click: del });
92
- * S.button("Cancel"); // shorthand for { text: "Cancel" }
93
- * S.button({ href: "/docs", text: "Docs" }); // renders an <a role=button>
90
+ * S.button({ content: "Save", click: save });
91
+ * S.button({ content: "Delete", attrs: ".danger .outlined", click: del });
92
+ * S.button("Cancel"); // shorthand for { content: "Cancel" }
93
+ * S.button({ href: "/docs", content: "Docs" }); // renders an <a role=button>
94
94
  * ```
95
95
  */
96
- export function button(opts: ButtonOptions | string | Content = {}): void {
97
- const o: ButtonOptions = typeof opts === "string" ? { text: opts } : typeof opts === "function" ? { content: opts } : opts;
96
+ export function button(opts: ButtonOptions | Slot = {}): void {
97
+ const o: ButtonOptions = typeof opts === "string" || typeof opts === "function" ? { content: opts } : opts;
98
98
 
99
99
  const tag = o.href != null ? "a" : "button";
100
100
 
@@ -115,7 +115,6 @@ export function button(opts: ButtonOptions | string | Content = {}): void {
115
115
  if (o.click) A("click=", o.click);
116
116
 
117
117
  drawSlot(o.icon);
118
- if (o.content) o.content();
119
- else if (o.text != null) A("#", o.text);
118
+ drawSlot(o.content);
120
119
  });
121
120
  }
@@ -13,13 +13,13 @@ export interface ButtonChooserOptions {
13
13
  */
14
14
  options: Record<string, Slot>;
15
15
  /**
16
- * Two-way binding for the selected id, or `null` when nothing is selected.
16
+ * Two-way binding for the selected id, or `undefined` when nothing is selected.
17
17
  * Use an `A.proxy` or `A.ref`.
18
18
  */
19
- bind: Bindable<string | null>;
19
+ bind: Bindable<string | undefined>;
20
20
  /**
21
21
  * When `true`, clicking the already-selected button deselects it, setting
22
- * `bind.value` to `null`. Useful for "none / auto" states.
22
+ * `bind.value` to `undefined`. Useful for "none / auto" states.
23
23
  */
24
24
  allowDeselect?: boolean;
25
25
  /** Name attribute for the hidden `<input>`, enabling form submission. */
@@ -28,14 +28,14 @@ export interface ButtonChooserOptions {
28
28
 
29
29
  /**
30
30
  * A single-selection segmented control: an attached button group where exactly
31
- * one button is active at a time. Optionally allows deselecting back to `null`.
31
+ * one button is active at a time. Optionally allows deselecting back to `undefined`.
32
32
  *
33
33
  * Renders a hidden `<input>` alongside (when `name` is set) so the selected
34
34
  * value is included in native form submission.
35
35
  *
36
36
  * @example
37
37
  * ```ts
38
- * const $view = A.proxy({ value: "day" as string | null });
38
+ * const $view = A.proxy({ value: "day" as string | undefined });
39
39
  * S.buttonChooser({
40
40
  * options: { day: "Day", week: "Week", month: "Month" },
41
41
  * bind: $view,
@@ -48,11 +48,13 @@ export function buttonChooser(opts: ButtonChooserOptions): void {
48
48
  buttonGroup({
49
49
  attrs: opts.attrs,
50
50
  buttons: Object.entries(opts.options).map(([id, label]) => ({
51
- text: typeof label === "string" ? label : undefined,
52
- content: typeof label === "function" ? label : undefined,
51
+ content: label,
52
+ // Icon-only options (draw-function labels) get the id as their
53
+ // accessible name; plain-text labels speak for themselves.
54
+ ariaLabel: typeof label === "function" ? id : undefined,
53
55
  attrs: selected === id ? ".primary" : ".neutral .outlined",
54
56
  click: () => {
55
- opts.bind.value = (opts.allowDeselect && selected === id) ? null : id;
57
+ opts.bind.value = (opts.allowDeselect && selected === id) ? undefined : id;
56
58
  },
57
59
  })),
58
60
  });
@@ -1,5 +1,6 @@
1
1
  import A from "aberdeen";
2
2
  import type { ContentOptions } from "../core.js";
3
+ import { drawSlot } from "../core.js";
3
4
  import { type ButtonOptions, button } from "./button.js";
4
5
 
5
6
  /** Options for {@link buttonGroup}. */
@@ -43,9 +44,9 @@ A.insertGlobalCss({
43
44
  * @example
44
45
  * ```ts
45
46
  * S.buttonGroup({ buttons: [
46
- * { text: "Day", attrs: ".neutral .outlined" },
47
- * { text: "Week", attrs: ".neutral .outlined" },
48
- * { text: "Month", attrs: ".neutral .outlined" },
47
+ * { content: "Day", attrs: ".neutral .outlined" },
48
+ * { content: "Week", attrs: ".neutral .outlined" },
49
+ * { content: "Month", attrs: ".neutral .outlined" },
49
50
  * ]});
50
51
  * ```
51
52
  */
@@ -55,6 +56,6 @@ export function buttonGroup(opts: ButtonGroupOptions = {}): void {
55
56
 
56
57
  A(`div.s-bgroup${cls} role=group`, opts.attrs, () => {
57
58
  if (opts.buttons) for (const b of opts.buttons) button(b);
58
- if (opts.content) opts.content();
59
+ drawSlot(opts.content);
59
60
  });
60
61
  }
@@ -1,5 +1,5 @@
1
1
  import A from "aberdeen";
2
- import { type Slot, type Attributes, drawSlot } from "../core.js";
2
+ import { type Slot, type Attributes, drawSlot, mountPortal } from "../core.js";
3
3
  import { button } from "./button.js";
4
4
  import { buttonGroup } from "./buttonGroup.js";
5
5
  import { textline } from "./textline.js";
@@ -60,7 +60,7 @@ A.insertGlobalCss({
60
60
  "display:flex align-items:center gap:$2 padding: $2 $3; " +
61
61
  "border-bottom: 1px solid $s-border; font-weight:600 flex-shrink:0",
62
62
  "> footer":
63
- "display:flex align-items:center gap:$2 padding: $2 $3; " +
63
+ "display:flex align-items:center justify-content:flex-end gap:$2 padding: $2 $3; " +
64
64
  "border-top: 1px solid $s-border; flex-shrink:0",
65
65
  "> div": "p:$3 gap:$3 display:flex flex-direction:column overflow-y:auto flex:1 min-height:0",
66
66
  "&.hidden": "opacity:0 pointer-events:none transform: translate(-50%, calc(-50% + 20px)); pointer-events:none",
@@ -75,7 +75,7 @@ const topDialogId = A.derive(() => {
75
75
  if (keys.length) return keys[keys.length-1];
76
76
  });
77
77
 
78
- A.mount(document.body, () => {
78
+ mountPortal(() => {
79
79
  A.onEach(dialogs, ({resolve, opts}, dialogId) => {
80
80
  const close = () => { delete dialogs[dialogId]; };
81
81
 
@@ -128,8 +128,8 @@ A.mount(document.body, () => {
128
128
  * header: "Confirm",
129
129
  * content: (close) => {
130
130
  * A("p #Are you sure?");
131
- * S.button({ text: "Yes", click: () => { doIt(); close(); } });
132
- * S.button({ text: "Cancel", attrs: ".neutral .outlined", click: close });
131
+ * S.button({ content: "Yes", click: () => { doIt(); close(); } });
132
+ * S.button({ content: "Cancel", attrs: ".neutral .outlined", click: close });
133
133
  * },
134
134
  * });
135
135
  * ```
@@ -176,7 +176,7 @@ export function alert(message: string, opts: Partial<DialogOptions> = {}): Promi
176
176
  content: (close) => {
177
177
  A("p", () => { A("#", message); });
178
178
  buttonGroup({ layout: "spaced", attrs: "align-self:flex-end", content: () => {
179
- button({ text: "OK", click: close });
179
+ button({ content: "OK", click: close });
180
180
  }});
181
181
  },
182
182
  ...opts,
@@ -201,8 +201,8 @@ export function confirm(message: string, opts: Partial<DialogOptions> = {}): Pro
201
201
  content: (close) => {
202
202
  A("p", () => { A("#", message); });
203
203
  buttonGroup({ layout: "spaced", attrs: "align-self:flex-end", content: () => {
204
- button({ text: "Cancel", attrs: ".neutral .outlined", click: close });
205
- button({ text: "OK", click: () => { confirmed = true; close(); } });
204
+ button({ content: "Cancel", attrs: ".neutral .outlined", click: close });
205
+ button({ content: "OK", click: () => { confirmed = true; close(); } });
206
206
  }});
207
207
  },
208
208
  ...opts,
@@ -241,8 +241,8 @@ export function prompt(message: string, defaultValue = "", opts: Partial<DialogO
241
241
  });
242
242
  textline({ bind: A.ref($v, "value") });
243
243
  buttonGroup({ layout: "spaced", attrs: "align-self:flex-end", content: () => {
244
- button({ text: "Cancel", attrs: ".neutral .outlined", type: "button", click: close });
245
- button({ text: "OK", type: "submit" });
244
+ button({ content: "Cancel", attrs: ".neutral .outlined", type: "button", click: close });
245
+ button({ content: "OK", type: "submit" });
246
246
  }});
247
247
  });
248
248
  },