/* ds.css v1.0.0 (BB 261104). The app family design system for every in-house app John uses.
   Source of truth: WORK/JP/WEB/LANES/LN_WEB_PLATFORM/DESIGN/ds.css. Served pinned and immutable from
   https://ds.moabmerc.com/v1.0.0/ds.css. Spec: DESIGN/RESEARCH.md DECISIONS 1 to 29; provenance: DESIGN/KEPT.md.
   Opt in: put class="ds" on <html>. Tokens load either way; base element styles apply only under .ds,
   so linking this file into an older app changes nothing until that app opts in.
   Per-app theme, exactly three inputs (decision 1): --ds-base, --ds-accent, --ds-contrast.
   Every other color is derived with color-mix(in oklab) and light-dark(). The contrast gate is
   DESIGN/ds_contrast.py, which repeats these recipes; change one, change both. */

@font-face{font-family:"Fraunces";font-style:normal;font-weight:300 700;font-display:swap;
  src:url(fonts/fraunces-normal-latin.woff2) format("woff2")}
@font-face{font-family:"Fraunces Fallback";src:local("Georgia");size-adjust:116.9%;ascent-override:83.7%;descent-override:21.8%;line-gap-override:0%}

:root{
  /* the three per-app inputs */
  --ds-base:#fbf7f0;--ds-accent:#2f5d50;--ds-contrast:0;
  /* reference values, private (decision 2) */
  --ds-ref-ink:#22201c;--ds-ref-muted:#6b6555;--ds-ref-ink-d:#f1ebdf;--ds-ref-muted-d:#b0a896;
  --ds-ref-night:#14120e;--ds-ref-surface-d:#1c1914;--ds-ref-raised-d:#24201a;
  --ds-ref-success:#2f6b4f;--ds-ref-warning:#8a5a06;--ds-ref-critical:#b3261e;
  --ds-ref-success-d:#6fc29f;--ds-ref-warning-d:#e6b65a;--ds-ref-critical-d:#f2867a;
  --ds-ref-shadow:light-dark(rgb(60 40 10 / .07),rgb(0 0 0 / .32));
  color-scheme:light dark;
  /* system color roles, public (decision 3): role, then variant, then state */
  --ds-color-bg:light-dark(var(--ds-base),color-mix(in oklab,var(--ds-base) 5%,var(--ds-ref-night)));
  --ds-color-surface:light-dark(color-mix(in oklab,var(--ds-base) 35%,#fff),color-mix(in oklab,var(--ds-base) 6%,var(--ds-ref-surface-d)));
  --ds-color-surface-raised:light-dark(#fff,color-mix(in oklab,var(--ds-base) 6%,var(--ds-ref-raised-d)));
  --ds-color-text:light-dark(var(--ds-ref-ink),var(--ds-ref-ink-d));
  --ds-color-text-muted:light-dark(color-mix(in oklab,var(--ds-ref-muted),var(--ds-ref-ink) calc(var(--ds-contrast) * 100%)),color-mix(in oklab,var(--ds-ref-muted-d),var(--ds-ref-ink-d) calc(var(--ds-contrast) * 100%)));
  --ds-color-border:light-dark(color-mix(in oklab,var(--ds-color-bg),var(--ds-color-text) 16%),color-mix(in oklab,var(--ds-color-bg),var(--ds-color-text) 20%));
  --ds-color-border-strong:light-dark(color-mix(in oklab,var(--ds-color-bg),var(--ds-color-text) calc(48% + var(--ds-contrast) * 30%)),color-mix(in oklab,var(--ds-color-bg),var(--ds-color-text) calc(50% + var(--ds-contrast) * 30%)));
  --ds-color-accent:light-dark(var(--ds-accent),color-mix(in oklab,var(--ds-accent) 55%,#fff));
  --ds-color-accent-soft:color-mix(in oklab,var(--ds-color-accent) 14%,var(--ds-color-surface));
  --ds-color-on-accent:light-dark(#fff,#16140f);
  --ds-color-success:light-dark(var(--ds-ref-success),var(--ds-ref-success-d));
  --ds-color-warning:light-dark(var(--ds-ref-warning),var(--ds-ref-warning-d));
  --ds-color-critical:light-dark(var(--ds-ref-critical),var(--ds-ref-critical-d));
  --ds-color-focus:var(--ds-color-accent);
  /* space on a 4px base (decision 4) */
  --ds-space-1:4px;--ds-space-2:8px;--ds-space-3:12px;--ds-space-4:16px;--ds-space-5:20px;--ds-space-6:24px;--ds-space-7:32px;--ds-space-8:48px;
  /* radius (5), shadow (6) */
  --ds-radius-sm:6px;--ds-radius-md:12px;--ds-radius-lg:20px;--ds-radius-pill:999px;
  --ds-shadow-1:0 1px 2px var(--ds-ref-shadow),0 4px 14px var(--ds-ref-shadow);
  --ds-shadow-2:0 2px 6px var(--ds-ref-shadow),0 14px 36px var(--ds-ref-shadow);
  /* type (7): rem so text size settings and 200 percent zoom work; 13px floor */
  --ds-font-body:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --ds-font-head:"Fraunces","Fraunces Fallback",Georgia,serif;
  --ds-text-xs:.8125rem;--ds-text-sm:.9375rem;--ds-text-base:1.0625rem;--ds-text-lg:1.25rem;--ds-text-xl:1.5rem;--ds-text-2xl:1.875rem;
  /* targets (8), safe areas (9), motion (10), focus (11), bar heights */
  --ds-tap:48px;--ds-tap-min:44px;
  --ds-safe-top:env(safe-area-inset-top,0px);--ds-safe-bottom:env(safe-area-inset-bottom,0px);
  --ds-motion-fast:120ms;--ds-motion-base:200ms;--ds-ease:cubic-bezier(.2,0,0,1);
  --ds-focus-ring:2px solid var(--ds-color-focus);
  --ds-header-h:56px;--ds-tabbar-h:64px;--ds-actionbar-h:76px;--ds-measure:46rem;
}
/* forced scheme for one subtree, used by the demo page and by an app's own theme switch */
[data-ds-theme=light]{color-scheme:light}
[data-ds-theme=dark]{color-scheme:dark}
[data-ds-theme]{background:var(--ds-color-bg);color:var(--ds-color-text)}
/* decision 12: Increase Contrast raises the third input */
@media (prefers-contrast:more){:root{--ds-contrast:.6}}
/* browsers without light-dark() (before Safari 17.5) get the light theme, never a blank page */
@supports not (color:light-dark(#000,#fff)){:root{color-scheme:light;
  --ds-ref-shadow:rgb(60 40 10 / .07);--ds-color-bg:var(--ds-base);--ds-color-surface:color-mix(in oklab,var(--ds-base) 35%,#fff);
  --ds-color-surface-raised:#fff;--ds-color-text:var(--ds-ref-ink);
  --ds-color-text-muted:color-mix(in oklab,var(--ds-ref-muted),var(--ds-ref-ink) calc(var(--ds-contrast) * 100%));
  --ds-color-border:color-mix(in oklab,var(--ds-base),var(--ds-ref-ink) 16%);
  --ds-color-border-strong:color-mix(in oklab,var(--ds-base),var(--ds-ref-ink) calc(48% + var(--ds-contrast) * 30%));
  --ds-color-accent:var(--ds-accent);--ds-color-on-accent:#fff;--ds-color-success:var(--ds-ref-success);
  --ds-color-warning:var(--ds-ref-warning);--ds-color-critical:var(--ds-ref-critical)}}

/* base, only under html.ds */
:where(.ds) *,:where(.ds) *::before,:where(.ds) *::after{box-sizing:border-box}
:where(.ds) [hidden]{display:none!important}
html.ds{-webkit-text-size-adjust:100%;text-size-adjust:100%;background:var(--ds-color-bg);color:var(--ds-color-text);
  scroll-padding-top:calc(var(--ds-header-h) + var(--ds-safe-top));scroll-padding-bottom:calc(var(--ds-tabbar-h) + var(--ds-safe-bottom))}
:where(.ds) body{margin:0;font:var(--ds-text-base)/1.5 var(--ds-font-body);font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;background:var(--ds-color-bg);color:var(--ds-color-text)}
:where(.ds) h1,:where(.ds) h2,:where(.ds) h3,.ds-head{font-family:var(--ds-font-head);font-weight:500;letter-spacing:-.01em;line-height:1.2;margin:0}
:where(.ds) h1{font-size:var(--ds-text-xl)}:where(.ds) h2{font-size:var(--ds-text-lg)}:where(.ds) h3{font-size:var(--ds-text-base)}
:where(.ds) p{margin:0}
:where(.ds) a{color:var(--ds-color-accent);text-decoration:underline;text-underline-offset:.15em}
:where(.ds) button,:where(.ds) input,:where(.ds) select,:where(.ds) textarea{font:inherit;color:inherit}
:where(.ds) button{cursor:pointer}
:where(.ds) :focus-visible{outline:var(--ds-focus-ring);outline-offset:2px}
:where(.ds) :focus:not(:focus-visible){outline:none}
.ds-sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.ds-muted{color:var(--ds-color-text-muted)}
.ds-stack{display:flex;flex-direction:column;gap:var(--ds-space-4)}
.ds-main{max-width:var(--ds-measure);margin:0 auto;padding:var(--ds-space-4) var(--ds-space-4) var(--ds-space-8);display:flex;flex-direction:column;gap:var(--ds-space-6)}
body:has(> .ds-tabbar) .ds-main,.ds-main.ds-has-tabbar{padding-bottom:calc(var(--ds-tabbar-h) + var(--ds-safe-bottom) + var(--ds-space-8))}
body:has(.ds-actionbar) .ds-main{padding-bottom:calc(var(--ds-tabbar-h) + var(--ds-actionbar-h) + var(--ds-safe-bottom) + var(--ds-space-8))}

/* buttons: one primary per screen (the primary sits in ds-actionbar or ds-empty) */
.ds-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--ds-space-2);min-height:var(--ds-tap);padding:0 var(--ds-space-5);
  border:1.5px solid var(--ds-color-border-strong);border-radius:var(--ds-radius-md);background:var(--ds-color-surface-raised);
  color:var(--ds-color-text);font-size:var(--ds-text-base);font-weight:600;text-decoration:none;white-space:nowrap;
  transition:background var(--ds-motion-fast) var(--ds-ease),transform var(--ds-motion-fast) var(--ds-ease)}
.ds-btn:active{transform:scale(.98)}
.ds-btn--primary{background:var(--ds-color-accent);border-color:var(--ds-color-accent);color:var(--ds-color-on-accent)}
.ds-btn--quiet{background:transparent;border-color:transparent;color:var(--ds-color-accent);text-decoration:underline;text-underline-offset:.15em}
.ds-btn--danger{color:var(--ds-color-critical);border-color:var(--ds-color-critical)}
.ds-btn--block{width:100%}
.ds-btn:disabled,.ds-btn[aria-disabled=true]{opacity:.5;cursor:default;transform:none}
.ds-iconbtn{display:inline-grid;place-items:center;width:var(--ds-tap-min);height:var(--ds-tap-min);border-radius:var(--ds-radius-pill);
  border:1px solid var(--ds-color-border);background:var(--ds-color-surface);color:var(--ds-color-text);position:relative;font-size:1.15rem;padding:0}

/* ds-header (28): sticky, clears the notch; title left, at most two icon buttons right */
.ds-header{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:var(--ds-space-3);
  min-height:calc(var(--ds-header-h) + var(--ds-safe-top));padding:var(--ds-safe-top) var(--ds-space-4) 0;
  background:color-mix(in oklab,var(--ds-color-bg) 92%,transparent);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  border-bottom:1px solid var(--ds-color-border)}
.ds-header__title{flex:1;min-width:0;font-family:var(--ds-font-head);font-size:var(--ds-text-xl);font-weight:500;line-height:1.1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0}
.ds-header__sub{display:block;font-family:var(--ds-font-body);font-size:var(--ds-text-xs);color:var(--ds-color-text-muted);font-weight:400}
.ds-header__actions{display:flex;gap:var(--ds-space-2);align-items:center}

/* ds-tabbar (13): 3 to 5 places, icon plus one word, always visible, no More tab */
.ds-tabbar{position:fixed;left:0;right:0;bottom:0;z-index:30;display:grid;grid-auto-flow:column;grid-auto-columns:1fr;
  min-height:calc(var(--ds-tabbar-h) + var(--ds-safe-bottom));padding:var(--ds-space-1) var(--ds-space-2) var(--ds-safe-bottom);
  background:var(--ds-color-surface);border-top:1px solid var(--ds-color-border);box-shadow:0 -2px 12px var(--ds-ref-shadow)}
.ds-tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-height:var(--ds-tap);position:relative;
  background:none;border:0;padding:var(--ds-space-1) 0;color:var(--ds-color-text-muted);font-size:var(--ds-text-xs);font-weight:500;text-decoration:none}
.ds .ds-tab{color:var(--ds-color-text-muted);text-decoration:none}
.ds-tab__icon{display:grid;place-items:center;width:3.25rem;height:1.875rem;border-radius:var(--ds-radius-pill);font-size:1.25rem;line-height:1;
  transition:background var(--ds-motion-fast) var(--ds-ease)}
.ds .ds-tab[aria-current=page],.ds .ds-tab[aria-selected=true]{color:var(--ds-color-accent);font-weight:700}
.ds-tab[aria-current=page] .ds-tab__icon,.ds-tab[aria-selected=true] .ds-tab__icon{background:var(--ds-color-accent-soft)}
@media (min-width:900px){.ds-tabbar{left:50%;right:auto;transform:translateX(-50%);width:min(40rem,100vw - 2rem);bottom:var(--ds-space-4);
  border:1px solid var(--ds-color-border);border-radius:var(--ds-radius-lg);padding-bottom:var(--ds-space-1);min-height:var(--ds-tabbar-h)}}

/* ds-badge: a count that needs the person (filled by ds.badge) */
.ds-badge{position:absolute;top:2px;left:calc(50% + .5rem);min-width:1.375rem;height:1.375rem;padding:0 .375rem;border-radius:var(--ds-radius-pill);
  background:var(--ds-color-critical);color:light-dark(#fff,#16140f);font-size:var(--ds-text-xs);font-weight:700;line-height:1.375rem;text-align:center}
.ds-iconbtn .ds-badge{top:-4px;left:auto;right:-4px}

/* ds-segment (14): 2 to 4 views of the same content; current view is bold, underlined and accent */
.ds-segment{display:flex;gap:var(--ds-space-5);border-bottom:1px solid var(--ds-color-border);overflow-x:auto;scrollbar-width:none}
.ds-segment button,.ds-segment a{min-height:var(--ds-tap-min);padding:0 var(--ds-space-1);margin-bottom:-1px;background:none;border:0;
  border-bottom:3px solid transparent;color:var(--ds-color-text-muted);font-size:var(--ds-text-sm);font-weight:500;white-space:nowrap;text-decoration:none}
.ds .ds-segment [aria-selected=true],.ds .ds-segment [aria-pressed=true],.ds .ds-segment [aria-current]{color:var(--ds-color-accent);
  border-bottom-color:var(--ds-color-accent);font-weight:700}

/* ds-row and ds-list (23): the base list pattern */
.ds-list{background:var(--ds-color-surface);border:1px solid var(--ds-color-border);border-radius:var(--ds-radius-md);overflow:hidden;
  box-shadow:var(--ds-shadow-1);margin:0;padding:0;list-style:none}
.ds-row{display:flex;align-items:center;gap:var(--ds-space-3);width:100%;min-height:calc(var(--ds-tap) + 8px);padding:var(--ds-space-3) var(--ds-space-4);
  background:var(--ds-color-surface);border:0;border-bottom:1px solid var(--ds-color-border);color:var(--ds-color-text);text-align:left;text-decoration:none}
.ds .ds-row{color:var(--ds-color-text);text-decoration:none}
.ds-row:last-child{border-bottom:0}
a.ds-row:hover,button.ds-row:hover{background:color-mix(in oklab,var(--ds-color-surface),var(--ds-color-text) 4%)}
.ds-row__lead{flex:none;display:grid;place-items:center;width:2.5rem;height:2.5rem;border-radius:var(--ds-radius-md);
  background:var(--ds-color-accent-soft);font-size:1.15rem}
.ds-row__main{flex:1;min-width:0}
.ds-row__title{display:block;font-weight:600;line-height:1.3}
.ds-row__sub{display:block;font-size:var(--ds-text-sm);color:var(--ds-color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ds-row__end{flex:none;text-align:right;font-size:var(--ds-text-sm);color:var(--ds-color-text-muted)}
.ds-row__end b{display:block;color:var(--ds-color-text);font-size:var(--ds-text-base)}
a.ds-row::after,button.ds-row.ds-row--go::after{content:"";flex:none;width:.5rem;height:.5rem;border:solid var(--ds-color-text-muted);
  border-width:2px 2px 0 0;transform:rotate(45deg);margin-left:var(--ds-space-1)}

/* ds-group (23): a list section with a sticky small heading; --ds-group-color paints the dot, the name always shows */
.ds-group{display:flex;flex-direction:column;gap:var(--ds-space-2)}
.ds-group__head{position:sticky;top:calc(var(--ds-header-h) + var(--ds-safe-top));z-index:5;display:flex;align-items:center;gap:var(--ds-space-2);
  padding:var(--ds-space-2) var(--ds-space-1);background:var(--ds-color-bg);font-size:var(--ds-text-sm);font-weight:700;color:var(--ds-color-text-muted);margin:0}
.ds-group__head::before{content:"";width:.75rem;height:.75rem;border-radius:3px;background:var(--ds-group-color,var(--ds-color-border-strong))}
.ds-group__head span{margin-left:auto;font-weight:500}

/* ds-checkrow (24): the whole row toggles; checked shows a strike line AND a check mark, never color alone */
.ds-checkrow{cursor:pointer}
.ds-check{flex:none;width:1.75rem;height:1.75rem;border:2px solid var(--ds-color-border-strong);border-radius:50%;position:relative;
  background:var(--ds-color-surface-raised);transition:background var(--ds-motion-fast) var(--ds-ease)}
.ds-checkrow[aria-checked=true] .ds-check{background:var(--ds-color-accent);border-color:var(--ds-color-accent)}
.ds-checkrow[aria-checked=true] .ds-check::after{content:"";position:absolute;left:.5rem;top:.25rem;width:.4rem;height:.75rem;
  border:solid var(--ds-color-on-accent);border-width:0 3px 3px 0;transform:rotate(45deg)}
.ds-checkrow[aria-checked=true] .ds-row__title{text-decoration:line-through;text-decoration-thickness:2px;color:var(--ds-color-text-muted)}

/* ds-sheet (15): native dialog, half or full height, grabber button, visible Close; one at a time (ds.js) */
dialog.ds-sheet{position:fixed;inset:auto 0 0 0;margin:0 auto;width:100%;max-width:40rem;max-height:92dvh;padding:0;border:0;
  border-radius:var(--ds-radius-lg) var(--ds-radius-lg) 0 0;background:var(--ds-color-surface-raised);color:var(--ds-color-text);
  box-shadow:var(--ds-shadow-2);overflow:auto;overscroll-behavior:contain}
dialog.ds-sheet[open]{display:flex;flex-direction:column;animation:ds-up var(--ds-motion-base) var(--ds-ease)}
dialog.ds-sheet.ds-sheet--half{max-height:55dvh}
dialog.ds-sheet::backdrop{background:rgb(20 15 5 / .4)}
.ds-sheet__grab{display:block;width:100%;height:var(--ds-tap-min);background:none;border:0;padding:0;position:relative;flex:none}
.ds-sheet__grab::before{content:"";position:absolute;left:50%;top:50%;width:2.75rem;height:.3rem;border-radius:9px;
  transform:translate(-50%,-50%);background:var(--ds-color-border-strong)}
.ds-sheet__head{display:flex;align-items:center;gap:var(--ds-space-3);padding:0 var(--ds-space-4) var(--ds-space-2)}
.ds-sheet__head h2{flex:1}
.ds-sheet__body{padding:var(--ds-space-2) var(--ds-space-4) calc(var(--ds-space-6) + var(--ds-safe-bottom));display:flex;flex-direction:column;gap:var(--ds-space-4)}
@media (min-width:760px){dialog.ds-sheet{inset:0;margin:auto;border-radius:var(--ds-radius-lg);height:fit-content}}
@keyframes ds-up{from{transform:translateY(24px);opacity:.4}to{transform:none;opacity:1}}
@keyframes ds-fade{from{opacity:0}to{opacity:1}}

/* ds-toast (16): one at a time, bottom, above the tab bar, one action, 6 s, role=status (ds.js) */
.ds-toast{position:fixed;left:50%;bottom:calc(var(--ds-space-4) + var(--ds-safe-bottom));transform:translateX(-50%);z-index:60;
  display:flex;align-items:center;gap:var(--ds-space-4);width:max-content;max-width:calc(100vw - 2rem);min-height:var(--ds-tap);
  padding:var(--ds-space-2) var(--ds-space-2) var(--ds-space-2) var(--ds-space-4);border-radius:var(--ds-radius-md);
  background:var(--ds-color-text);color:var(--ds-color-bg);box-shadow:var(--ds-shadow-2);font-size:var(--ds-text-sm);
  animation:ds-up var(--ds-motion-base) var(--ds-ease)}
body:has(> .ds-tabbar) .ds-toast{bottom:calc(var(--ds-tabbar-h) + var(--ds-safe-bottom) + var(--ds-space-3))}
body:has(.ds-actionbar) .ds-toast{bottom:calc(var(--ds-tabbar-h) + var(--ds-actionbar-h) + var(--ds-safe-bottom) + var(--ds-space-3))}
.ds-toast__msg{flex:1}
.ds-toast__action{min-height:var(--ds-tap-min);padding:0 var(--ds-space-3);border:0;border-radius:var(--ds-radius-sm);background:none;
  color:inherit;font-weight:700;text-decoration:underline;text-underline-offset:.2em}
.ds-toast--bad{box-shadow:inset 6px 0 0 var(--ds-color-critical),var(--ds-shadow-2)}
.ds-toast--bad .ds-toast__msg::before{content:"!";display:inline-grid;place-items:center;width:1.25rem;height:1.25rem;margin-right:var(--ds-space-2);
  border-radius:50%;border:2px solid currentColor;font-weight:800;font-size:.75rem}

/* ds-confirm (17): only for actions that leave the building; named outcome buttons, never Yes and No */
dialog.ds-confirm{max-width:24rem;width:calc(100% - 2rem);padding:var(--ds-space-6);border:0;border-radius:var(--ds-radius-lg);
  background:var(--ds-color-surface-raised);color:var(--ds-color-text);box-shadow:var(--ds-shadow-2)}
dialog.ds-confirm[open]{display:flex;flex-direction:column;gap:var(--ds-space-4);animation:ds-fade var(--ds-motion-base) var(--ds-ease)}
dialog.ds-confirm::backdrop{background:rgb(20 15 5 / .45)}
.ds-confirm__actions{display:flex;flex-direction:column-reverse;gap:var(--ds-space-2)}

/* ds-chip (28): one-tap filters and adds; pressed shows a check mark as well as the fill */
.ds-chips{display:flex;flex-wrap:wrap;gap:var(--ds-space-2)}
.ds-chip{display:inline-flex;align-items:center;gap:var(--ds-space-1);min-height:var(--ds-tap-min);padding:0 var(--ds-space-4);
  border:1.5px solid var(--ds-color-border-strong);border-radius:var(--ds-radius-pill);background:var(--ds-color-surface);
  color:var(--ds-color-text);font-size:var(--ds-text-sm);font-weight:500;text-decoration:none}
.ds-chip[aria-pressed=true]{background:var(--ds-color-accent);border-color:var(--ds-color-accent);color:var(--ds-color-on-accent);font-weight:700}
.ds-chip[aria-pressed=true]::before{content:"\2713 ";font-weight:800}

/* ds-status (25): a word plus an icon plus color; color is the third cue, never the only one */
.ds-status{display:inline-flex;align-items:center;gap:var(--ds-space-1);padding:2px var(--ds-space-2);border:1.5px solid currentColor;
  border-radius:var(--ds-radius-pill);font-size:var(--ds-text-xs);font-weight:700;line-height:1.4;white-space:nowrap;color:var(--ds-color-text-muted)}
.ds-status::before{font-weight:800}
.ds-status--ok{color:var(--ds-color-success)}.ds-status--ok::before{content:"\2713 "}
.ds-status--warn{color:var(--ds-color-warning)}.ds-status--warn::before{content:"! "}
.ds-status--bad{color:var(--ds-color-critical)}.ds-status--bad::before{content:"\2715 "}
.ds-status--info::before{content:"i "}

/* ds-empty (18): what goes here, how to start, one button that is the screen's primary action */
.ds-empty{display:flex;flex-direction:column;align-items:center;gap:var(--ds-space-3);padding:var(--ds-space-8) var(--ds-space-5);text-align:center;
  background:var(--ds-color-surface);border:1.5px dashed var(--ds-color-border-strong);border-radius:var(--ds-radius-md)}
.ds-empty__icon{font-size:2.25rem;line-height:1}
.ds-empty h2{font-size:var(--ds-text-lg)}
.ds-empty p{color:var(--ds-color-text-muted);max-width:30ch}

/* ds-actionbar (28): the one primary action, bottom third, inside thumb reach */
.ds-actionbar{position:fixed;left:0;right:0;bottom:0;z-index:29;display:flex;gap:var(--ds-space-2);align-items:center;
  padding:var(--ds-space-3) var(--ds-space-4) calc(var(--ds-space-3) + var(--ds-safe-bottom));
  background:color-mix(in oklab,var(--ds-color-bg) 94%,transparent);border-top:1px solid var(--ds-color-border)}
body:has(> .ds-tabbar) .ds-actionbar{bottom:calc(var(--ds-tabbar-h) + var(--ds-safe-bottom));padding-bottom:var(--ds-space-3)}
.ds-actionbar > *{flex:1}
.ds-actionbar__note{flex:2;font-size:var(--ds-text-sm);color:var(--ds-color-text-muted)}
.ds-actionbar__note b{display:block;color:var(--ds-color-text);font-size:var(--ds-text-base)}
@media (min-width:900px){.ds-actionbar{left:50%;right:auto;transform:translateX(-50%);width:min(40rem,100vw - 2rem);
  border:1px solid var(--ds-color-border);border-radius:var(--ds-radius-lg);bottom:calc(var(--ds-tabbar-h) + var(--ds-space-6))}}

/* ds-field (21): label, hint, input, error under the label with an icon and a hidden "Error:" prefix; 16px floor on inputs */
.ds-field{display:flex;flex-direction:column;gap:var(--ds-space-1)}
.ds-field > label,.ds-field__label{font-weight:600;font-size:var(--ds-text-sm)}
.ds-field__hint{font-size:var(--ds-text-sm);color:var(--ds-color-text-muted)}
.ds-field__error{display:none;align-items:center;gap:var(--ds-space-2);font-size:var(--ds-text-sm);font-weight:600;color:var(--ds-color-critical)}
.ds-field__error::before{content:"!";display:inline-grid;place-items:center;flex:none;width:1.25rem;height:1.25rem;border-radius:50%;
  background:var(--ds-color-critical);color:light-dark(#fff,#16140f);font-weight:800;font-size:.75rem}
.ds-field--error .ds-field__error{display:flex}
.ds-input,.ds-field input:not([type=checkbox]):not([type=radio]),.ds-field select,.ds-field textarea{width:100%;min-height:var(--ds-tap);
  padding:var(--ds-space-2) var(--ds-space-3);font-size:max(16px,var(--ds-text-base));border:1.5px solid var(--ds-color-border-strong);
  border-radius:var(--ds-radius-md);background:var(--ds-color-surface-raised);color:var(--ds-color-text)}
.ds-field textarea{min-height:6rem;resize:vertical}
.ds-field [aria-invalid=true],.ds-field--error input,.ds-field--error select,.ds-field--error textarea{border-color:var(--ds-color-critical);border-width:2px}
.ds-field input[type=checkbox],.ds-field input[type=radio]{width:1.375rem;height:1.375rem;accent-color:var(--ds-color-accent)}
.ds-field--inline{flex-direction:row;align-items:center;gap:var(--ds-space-3);min-height:var(--ds-tap)}

/* ds-more (22): one <details> row labeled More options, one level only */
details.ds-more{border-top:1px solid var(--ds-color-border)}
details.ds-more > summary{display:flex;align-items:center;justify-content:space-between;min-height:var(--ds-tap);cursor:pointer;list-style:none;
  font-weight:600;color:var(--ds-color-accent)}
details.ds-more > summary::-webkit-details-marker{display:none}
details.ds-more > summary::after{content:"";width:.5rem;height:.5rem;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg);
  transition:transform var(--ds-motion-fast) var(--ds-ease)}
details.ds-more[open] > summary::after{transform:rotate(225deg)}
details.ds-more > :not(summary){margin-bottom:var(--ds-space-4)}
details.ds-more details.ds-more{display:none}

/* ds-card, ds-section, ds-figure (27): homes and dashboards */
.ds-card{background:var(--ds-color-surface);border:1px solid var(--ds-color-border);border-radius:var(--ds-radius-md);padding:var(--ds-space-4);
  box-shadow:var(--ds-shadow-1);display:flex;flex-direction:column;gap:var(--ds-space-3)}
.ds-section{display:flex;flex-direction:column;gap:var(--ds-space-3)}
.ds-section__head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--ds-space-3)}
.ds-section__head a{font-size:var(--ds-text-sm);font-weight:600;min-height:var(--ds-tap-min);display:inline-flex;align-items:center}
.ds-figure{display:flex;align-items:center;gap:var(--ds-space-4);flex-wrap:wrap}
.ds-figure__num{font-family:var(--ds-font-head);font-size:clamp(var(--ds-text-2xl),9vw,2.75rem);font-weight:500;line-height:1;
  font-variant-numeric:lining-nums tabular-nums}
.ds-figure__label{display:block;font-size:var(--ds-text-sm);color:var(--ds-color-text-muted);margin-top:var(--ds-space-1)}
.ds-figure__body{flex:1;min-width:10rem}

/* ds-tiles (26): 2 columns at 390px, 96px tall at least, a tile opens a filtered list */
.ds-tiles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--ds-space-3);margin:0;padding:0;list-style:none}
@media (min-width:700px){.ds-tiles{grid-template-columns:repeat(auto-fill,minmax(10rem,1fr))}}
.ds-tile{display:flex;flex-direction:column;justify-content:space-between;gap:var(--ds-space-2);min-height:96px;padding:var(--ds-space-3) var(--ds-space-4);
  background:var(--ds-color-surface);border:1px solid var(--ds-color-border);border-left:6px solid var(--ds-tile-color,var(--ds-color-accent));
  border-radius:var(--ds-radius-md);box-shadow:var(--ds-shadow-1);color:var(--ds-color-text);text-align:left;text-decoration:none;width:100%}
.ds .ds-tile{color:var(--ds-color-text);text-decoration:none}
.ds-tile__icon{font-size:1.5rem;line-height:1}
.ds-tile__label{font-weight:700;line-height:1.25}
.ds-tile__count{font-size:var(--ds-text-sm);color:var(--ds-color-text-muted)}

/* ds-skeleton (19): shown only after 300ms of waiting (ds.skeleton); no full-page spinners */
.ds-skeleton{display:flex;flex-direction:column;gap:var(--ds-space-2)}
.ds-skeleton__row{height:calc(var(--ds-tap) + 8px);border-radius:var(--ds-radius-md);
  background:color-mix(in oklab,var(--ds-color-surface),var(--ds-color-text) 7%);animation:ds-pulse 1.4s ease-in-out infinite}
@keyframes ds-pulse{50%{opacity:.55}}

/* ds-offline (20): a thin banner on the offline event, gone on online (ds.js) */
.ds-offline{position:fixed;left:0;right:0;top:0;z-index:70;padding:calc(var(--ds-space-2) + var(--ds-safe-top)) var(--ds-space-4) var(--ds-space-2);
  background:var(--ds-color-warning);color:light-dark(#fff,#16140f);font-size:var(--ds-text-sm);font-weight:600;text-align:center}

/* motion (10): reduced motion collapses slides to fades and stops the skeleton pulse */
@media (prefers-reduced-motion:reduce){
  :root{--ds-motion-fast:.01ms;--ds-motion-base:.01ms}
  dialog.ds-sheet[open],.ds-toast{animation:ds-fade 160ms linear}
  .ds-skeleton__row{animation:none}
  .ds-btn:active{transform:none}
  .ds *{scroll-behavior:auto!important}
}
/* Windows high contrast and other forced color modes: keep every boundary visible */
@media (forced-colors:active){
  .ds-tab[aria-current=page],.ds-tab[aria-selected=true],.ds-chip[aria-pressed=true]{outline:2px solid CanvasText}
  .ds-check,.ds-status,.ds-btn,.ds-tile{border-color:CanvasText}
}
