@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Literata:opsz,wght@7..72,400;7..72,500;7..72,600&display=swap');

/* ---- sesebonui/styles.css ---- */
/* ============================================================
   SesebonUI — global entry point.
   Consumers link THIS file. Import list only; no rules here.
   ============================================================ */


/* ---- tokens/fonts.css ---- */
/* ============================================================
   SesebonUI · FONTS
   NOTE: webfonts are loaded from Google Fonts here as a
   convenience. For production / offline, vendor the .woff2
   binaries into assets/fonts/ and replace these @imports with
   local @font-face rules. (Flagged to the user.)
   ============================================================ */



/* ------------------------------------------------------------
   THE THIRD FAMILY — Literata, editorial only.

   The two-family rule (Space Grotesk for UI, JetBrains Mono for
   data) governs the PRODUCT surface and is unchanged. Literata
   is a third ROLE, not a third UI font: it is permitted only
   inside `.sb-prose` — essays, articles, documentation pages.
   It must never appear in a panel, a control, a label or a
   metric.

   Why a text face at all: Space Grotesk is a geometric display
   sans. It carries the 13.5px conversation prose well, and it
   gets tiring across 2,000 words at 17px. Literata is drawn for
   continuous reading, and its sturdy low-contrast strokes hold
   up on a near-black ground where a high-contrast serif blooms.

   It ships with an optical-size axis (7..72), so headings and
   body text in the same family are optically corrected rather
   than merely scaled.
   ------------------------------------------------------------ */


/* ---- tokens/colors.css ---- */
/* ============================================================
   SesebonUI · COLOR SYSTEM
   ------------------------------------------------------------
   Three layers:
   1. PRIMITIVES  — raw palette. Never referenced by components.
   2. SEMANTIC    — role-based aliases. THE CONTRACT. Components
                    read ONLY these (var(--surface-raised), etc).
   3. THEMES/MOTIFS — re-bind semantic tokens under a scope.
                    A reskin = override the semantic layer only.

   SKINNING RULE: a motif may move surfaces / text / accent /
   textures. It may NEVER move --status-alert (safety red stays
   red at Christmas). Keep that invariant and skins can't break
   the brand's meaning.
   ============================================================ */

:root {
  /* ---------- 1. PRIMITIVES (raw — do not consume directly) ---------- */
  --sb-black:      #000000;
  --sb-obsidian:   #0A0A0A;
  --sb-pit:        #070707;
  --sb-chrome:     #050505;
  --sb-line:       #1f1f1f;
  --sb-hair:       #141414;
  --sb-track:      #171717;

  --sb-white:      #fafafa;
  --sb-fog:        #f2f2f2;
  --sb-gray-1:     #8a8a8a;
  --sb-gray-2:     #5a5a5a;
  --sb-gray-3:     #3d3d3d;
  --sb-gray-4:     #2a2a2a;

  --sb-amber:      #FFB000;
  --sb-amber-ink:  #1a1200;
  --sb-red:        #FF3B30;

  --sb-jade:       #5BC8A0;
  --sb-iris:       #9D8DF1;
  --sb-sky:        #7CC4FF;

  /* ---------- 2. SEMANTIC (the contract — components read these) ---------- */

  /* Surfaces — back-to-front depth */
  --surface-base:    var(--sb-black);     /* page / canvas background        */
  --surface-raised:  var(--sb-obsidian);  /* cards, panels                   */
  --surface-sunken:  var(--sb-pit);       /* insets, rows, wells             */
  --surface-chrome:  var(--sb-chrome);    /* top bar, terminal, manifest     */
  --surface-track:   var(--sb-track);     /* progress / bar backgrounds      */

  /* Borders */
  --border-default:  var(--sb-line);      /* standard 1px hairline           */
  --border-subtle:   var(--sb-hair);      /* inner dividers, quieter          */

  /* Text — descending emphasis */
  --text-primary:    var(--sb-white);     /* headings, hero values            */
  --text-body:       var(--sb-fog);       /* default copy                     */
  --text-secondary:  var(--sb-gray-1);    /* supporting / values              */
  --text-tertiary:   var(--sb-gray-2);    /* micro-labels, captions           */
  --text-ghost:      var(--sb-gray-3);    /* deprioritized / placeholder      */

  /* Accent — the single brand interactive color */
  --accent:          var(--sb-amber);
  --accent-ink:      var(--sb-amber-ink); /* text/icon on an accent fill      */
  --accent-wash:     rgba(255,176,0,.08); /* faint accent fill                */
  --accent-line:     rgba(255,176,0,.18); /* accent at hairline strength      */
  --accent-dim:      #6b5300;             /* accent at ~40% luma — journal step index (SPEC §6) */

  /* Status — INVARIANT across motifs. Do not re-theme. */
  --status-alert:    var(--sb-red);       /* threats, overages, errors        */
  --status-active:   var(--sb-amber);     /* on / live / armed-ok             */
  --status-idle:     var(--sb-gray-2);    /* off / clear / passive            */
  --alert-wash:      rgba(255,59,48,.08); /* faint alert fill — mirror of --accent-wash (CodeBlock diff removed-row, Toast alert) */

  /* Data / category encodings (charts, tags) */
  --data-pos:        var(--sb-amber);
  --data-warn:       var(--sb-red);
  --data-neutral:    var(--sb-fog);
  --cat-health:      var(--sb-jade);
  --cat-financial:   var(--sb-amber);
  --cat-preference:  var(--sb-iris);
  --cat-biographical:var(--sb-sky);
  --cat-general:     var(--sb-gray-1);

  /* Longform / code / mermaid (conversation surface — SPEC §3/§6) */
  --code-string:         #e8c15a;                /* code literals / string amber   */
  --mermaid-node-fill:   var(--surface-raised);
  --mermaid-node-stroke: var(--border-default);
  --mermaid-text:        var(--text-secondary);
  --mermaid-decision:    var(--accent);          /* decision nodes                 */
  --mermaid-alert:       var(--status-alert);    /* alert paths                    */
  --mermaid-edge:        var(--text-tertiary);

  /* Decoration (motif texture/ambient hooks — empty by default) */
  --motif-texture:   none;
  --motif-ambient:   transparent;
}

/* ============================================================
   THEME: graphite — a cool-neutral alternate base.
   Bind with <html data-theme="graphite"> or [data-theme].
   ============================================================ */
[data-theme="graphite"] {
  --surface-base:    #0c0d10;
  --surface-raised:  #15171c;
  --surface-sunken:  #101116;
  --surface-chrome:  #0f1014;
  --border-default:  #2a2d35;
  --border-subtle:   #20232a;
  --text-primary:    #ffffff;
  --text-body:       #eef1f5;
  --text-secondary:  #9aa0ab;
  --text-tertiary:   #646b76;
  --text-ghost:      #454b55;
  --status-alert:    #FF5247;  /* still red — invariant role honored */
}


/* ---- tokens/typography.css ---- */
/* ============================================================
   SesebonUI · TYPOGRAPHY
   Two families, strict division of labor:
   - UI / display  → Space Grotesk
   - ALL numbers, metrics, logs, micro-labels, code → JetBrains Mono
   Monospace for data is a load-bearing brand rule, not a vibe.
   ============================================================ */

:root {
  /* Families */
  --font-ui:   'Space Grotesk', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  /* Weights */
  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semibold:600;
  --fw-bold:    700;

  /* Fluid type scale (clamp: min, vw, max) */
  --fs-micro:  10px;                          /* mono micro-labels          */
  --fs-label:  clamp(10px, .7vw, 11px);       /* field / section labels      */
  --fs-caption:clamp(9px, .65vw, 10px);
  --fs-body:   clamp(12px, .9vw, 13px);
  --fs-value:  clamp(18px, 1.5vw, 21px);      /* standard metric             */
  --fs-value-lg: clamp(22px, 2.2vw, 28px);
  --fs-title:  clamp(14px, 1.2vw, 17px);      /* panel titles                */
  --fs-hero:   clamp(28px, 3vw, 40px);        /* hero metric                 */
  --fs-display:clamp(15px, 1.4vw, 18px);      /* wordmark                    */

  /* Line heights */
  --lh-tight:  1;
  --lh-snug:   1.2;
  --lh-body:   1.5;

  /* Letter-spacing — mono labels run wide; this is signature */
  --ls-label:  .14em;
  --ls-micro:  .16em;
  --ls-wide:   .1em;
  --ls-normal: .01em;

  /* Longform / conversation surface (added for the ConversationLog — SPEC §6) */
  /* Was 13.5px, "sized to sit next to UI chrome". That held while the
     conversation was one panel among widgets. It is now the primary reading
     surface of the app, and 13.5px is below what anyone sustains comfortably —
     mainstream assistants sit at 15-16px. The widget tier is untouched: this
     token is conversation-only, which is the whole reason it exists separately
     from --fs-body. */
  --fs-prose:  15px;     /* assistant prose body                              */
  --lh-prose:  1.65;     /* prose line-height                                 */
  --fw-light:  300;      /* display numerals ONLY (the Zen clock) — nowhere else */
}

/* ============================================================
   EDITORIAL TIER — long-form pages (essays, articles, docs).

   DISTINCT FROM --fs-prose. There are two long-form contexts on
   this system and conflating them breaks one of them:

     CONVERSATION prose  --fs-prose 15px, Space Grotesk.
                         Assistant replies. Raised from 13.5px
                         once the conversation became the primary
                         reading surface rather than one panel.

     EDITORIAL prose     the tokens below, Literata. A full page
                         whose only job is to be read. Sized for
                         continuous reading, not for density.

   The brand's density rule is deliberately suspended here and
   nowhere else. A dashboard earns its tightness because the
   reader is scanning; an essay is the opposite task.
   ============================================================ */

:root {
  /* The editorial family. Swap this one token to re-cast every
     long-form page on the system. */
  --font-read:      'Literata', Georgia, 'Times New Roman', serif;

  /* Reading scale. Fixed, not fluid — a text column should not
     resize with the viewport once it has reached its measure. */
  --fs-read:        17px;
  --fs-read-sm:     14.5px;   /* captions, table cells, figure labels */
  --fs-read-lead:   19.5px;   /* standfirst / summary                 */
  --lh-read:        1.72;

  /* Editorial headings. These are Space Grotesk, not Literata:
     the heading register stays with the UI family so a page
     still reads as this system's page. Only BODY changes face. */
  --fs-read-h1:     clamp(2rem, 5vw, 3.1rem);
  --fs-read-h2:     clamp(1.35rem, 2.8vw, 1.7rem);
  --fs-read-h3:     1.12rem;

  /* Measure — the most load-bearing number on a text page. */
  --measure-read:   66ch;
  --measure-page:   860px;
}


/* ---- tokens/spacing.css ---- */
/* ============================================================
   SesebonUI · SPACING & LAYOUT
   4px base grid. Brutalist density — tight, deliberate.
   These are brand-permanent: motifs never change spacing.
   ============================================================ */

:root {
  --space-0:  0px;
  --space-1:  4px;
  --space-2:  6px;
  --space-3:  8px;
  --space-4:  10px;
  --space-5:  12px;
  --space-6:  14px;
  --space-7:  16px;
  --space-8:  18px;
  --space-9:  20px;
  --space-10: 24px;

  /* Component rhythm */
  --pad-card:      18px 20px;   /* panel padding              */
  --pad-cell:      12px 13px;   /* sub-cell padding           */
  --pad-row:       10px 12px;   /* list row padding           */
  --gap-board:     14px;        /* between panels             */
  --gap-tight:     10px;        /* within a panel             */

  /* Canvas */
  --canvas-max:    1560px;
  --canvas-pad:    16px;

  /* Chrome heights */
  --h-topbar:      46px;
  --h-manifest:    30px;
  --h-input:       42px;

  /* Overlays */
  --drawer-w:      420px;       /* right-edge Drawer fixed width          */
  --toast-max:     3;           /* max toasts visible; older collapse +n  */
}

/* ------------------------------------------------------------
   EDITORIAL RHYTHM — vertical spacing for long-form pages.
   Built from the same 4px grid; the grid is brand-permanent and
   this does not change it. These are larger steps than the
   component rhythm above because a reading column needs air
   that a dashboard panel does not.
   ------------------------------------------------------------ */
:root {
  --stack-para:    24px;   /* paragraph to paragraph            */
  --stack-block:   36px;   /* body to a heading / figure / rule  */
  --stack-section: 72px;   /* major section break                */
  --pad-read:      28px 32px;  /* figure / callout padding       */
}


/* ---- tokens/effects.css ---- */
/* ============================================================
   SesebonUI · EFFECTS — borders, radius, shadows, motion
   Defining trait: ZERO radius, hairline borders, (almost) no
   shadow. Depth comes from surface tints + 1px lines, not blur.
   ============================================================ */

:root {
  /* Border width + radius (radius is 0 everywhere — on purpose) */
  --bw:        1px;
  --radius:    0px;

  /* The one sanctioned shadow — floating overlays only (payload
     inspector, dialogs). Flat surfaces get NO shadow. */
  --shadow-overlay: 0 8px 40px rgba(0,0,0,.6);

  /* Emphasis ring — replaces shadow for "this panel is focused" */
  --ring-accent: inset 0 0 0 1px var(--accent);
  --ring-alert:  inset 0 0 0 1px var(--status-alert);

  /* Motion — fast, mechanical, cubic. No bounce, no spring. */
  --ease:        cubic-bezier(.4, 0, .1, 1);
  --dur-fast:    .18s;
  --dur-med:     .35s;
  --dur-layout:  .55s;   /* column re-composition               */

  /* Scanline / striped placeholder fills (camera + media tiles) */
  --fill-stripe: repeating-linear-gradient(135deg, #0d0d0d 0, #0d0d0d 7px, #070707 7px, #070707 14px);
  --fill-scan:   repeating-linear-gradient(0deg, rgba(255,255,255,.02) 0, rgba(255,255,255,.02) 1px, transparent 1px, transparent 3px);
}

/* Keyframes shipped with the system */
@keyframes sb-blink { 0%,49%{opacity:1} 50%,100%{opacity:0} }
@keyframes sb-pulse { 0%,100%{opacity:1} 50%{opacity:.25} }
@keyframes sb-snow  { 0%{transform:translateY(-10%)} 100%{transform:translateY(110%)} }
@keyframes sb-fade  { from{opacity:0} to{opacity:1} }
@keyframes sb-modal { from{opacity:0; transform:translateY(6px) scale(.99)} to{opacity:1; transform:none} }
@keyframes sb-spin  { to{transform:rotate(360deg)} }
@keyframes sb-tick-sweep { 0%,100%{opacity:.12} 8%{opacity:1} 32%{opacity:.12} }  /* retired with the ringed Mark; kept for any consumer still on it */
/* Mark thinking: the square aperture breathes. Opacity only — animating the
   rect geometry would resample the hairline every frame and shimmer at 15px. */
@keyframes sb-mark-aperture { 0%,100%{opacity:1} 50%{opacity:.35} }
@keyframes sb-mark-core     { 0%,100%{opacity:.35} 50%{opacity:1} }
@keyframes sb-tts-bar    { 0%,100%{transform:scaleY(.25)} 50%{transform:scaleY(1)} }  /* TTS level meter */
@keyframes sb-deplete    { from{transform:scaleX(1)} to{transform:scaleX(0)} }  /* Toast auto-dismiss countdown line */
@keyframes sb-drawer     { from{opacity:0; transform:translateX(14px)} to{opacity:1; transform:none} }  /* Drawer slide-in */


/* Patterns that ship as CSS rather than as a React component,
   because their consumers are documents, not applications. */

/* ---- patterns/prose.css ---- */
/* ============================================================
   SesebonUI · PROSE — the editorial long-form surface.

   Scope: everything inside `.sb-prose`. This is the ONLY place
   --font-read is permitted. Panels, controls, labels and metrics
   keep the two-family rule (Space Grotesk + JetBrains Mono).

   Relationship to the `Markdown` component (Conversation-Surface
   SPEC §3): same rule set, different context. `Markdown` renders
   assistant replies INSIDE a panel at --fs-prose. This renders a
   PAGE at --fs-read. The rules below are inherited from that spec
   deliberately, so a reader moving between a chat reply and an
   article sees one system, not two:

     - h1–h3 are Space Grotesk. h4–h6 collapse to the mono label
       register: past h3 the register shifts from heading to label.
     - Blockquote is a 2px left rule and italic, with NO accent.
       Accent is interaction, not decoration.
     - Lists use en-dash and zero-padded ordinals, not bullets.
     - Tables get the full hairline grid, mono uppercase headers,
       and right-aligned numeric columns.

   KNOWN DIVERGENCE from SPEC §3, stated rather than hidden:
   the spec swaps every numeral to mono at −1px. That is a
   per-character substitution, which the React `Markdown`
   component does by wrapping spans. CSS cannot do it per
   character without a unicode-range @font-face pinned to a
   font binary, and the Google Fonts URLs are not stable enough
   to pin. So mono is applied here wherever numerals are DATA —
   tables, figures, dates, metrics, code — and prose numerals
   stay in the reading face with tabular-nums. If the numerals
   are ever vendored locally, the unicode-range trick closes
   this gap and this note comes out.
   ============================================================ */

.sb-prose {
  font-family: var(--font-read);
  font-size: var(--fs-read);
  line-height: var(--lh-read);
  color: var(--text-body);
  max-width: var(--measure-read);
}

.sb-prose > * { max-width: var(--measure-read); }

.sb-prose p { margin: 0 0 var(--stack-para); }

.sb-prose > :first-child { margin-top: 0; }
.sb-prose > :last-child  { margin-bottom: 0; }

/* ---------- headings: h1–h3 stay in the UI family ---------- */

.sb-prose h1,
.sb-prose h2,
.sb-prose h3 {
  font-family: var(--font-ui);
  color: var(--text-primary);
  text-wrap: balance;
}

.sb-prose h1 {
  font-size: var(--fs-read-h1);
  font-weight: var(--fw-bold);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 var(--stack-block);
}

.sb-prose h2 {
  font-size: var(--fs-read-h2);
  font-weight: var(--fw-semibold);
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: var(--stack-section) 0 var(--stack-block);
}

.sb-prose h3 {
  font-size: var(--fs-read-h3);
  font-weight: var(--fw-semibold);
  line-height: 1.3;
  margin: var(--stack-block) 0 var(--space-7);
}

/* Past h3 the register shifts from heading to label (SPEC §3). */
.sb-prose h4,
.sb-prose h5,
.sb-prose h6 {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: var(--stack-block) 0 var(--space-5);
}

/* ---------- inline ---------- */

.sb-prose strong { color: var(--text-primary); font-weight: var(--fw-semibold); }
.sb-prose em     { font-style: italic; }

.sb-prose a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.sb-prose a:hover { background: var(--accent-wash); }

/* Data is mono. Load-bearing brand rule, not a vibe. */
.sb-prose code,
.sb-prose time,
.sb-prose .sb-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.sb-prose code {
  font-size: 0.85em;
  color: var(--code-string);
  background: var(--surface-sunken);
  border: var(--bw) solid var(--border-subtle);
  border-radius: var(--radius);
  padding: 1px 5px;
}

/* Prose numerals do not change face, but they do align. */
.sb-prose p, .sb-prose li { font-variant-numeric: tabular-nums; }

/* ---------- lists: en-dash and zero-padded ordinals ---------- */

.sb-prose ul,
.sb-prose ol {
  margin: 0 0 var(--stack-para);
  padding-left: var(--space-9);
}
.sb-prose li { margin-bottom: var(--space-5); }
.sb-prose li::marker {
  color: var(--text-tertiary);
  font-family: var(--font-mono);
  font-size: 0.85em;
}
.sb-prose ul { list-style: none; padding-left: var(--space-10); }
.sb-prose ul > li { position: relative; }
.sb-prose ul > li::before {
  content: "–";
  position: absolute;
  left: calc(var(--space-10) * -1);
  color: var(--text-tertiary);
  font-family: var(--font-mono);
}
.sb-prose ol { list-style: decimal-leading-zero; }

.sb-prose li > ul,
.sb-prose li > ol { margin-top: var(--space-5); margin-bottom: 0; }

/* ---------- blockquote: 2px rule, italic, NO accent ---------- */

.sb-prose blockquote {
  margin: var(--stack-block) 0;
  padding: var(--space-5) 0 var(--space-5) var(--space-9);
  border-left: 2px solid var(--border-default);
  font-style: italic;
  font-size: var(--fs-read-lead);
  line-height: 1.45;
  color: var(--text-primary);
}
.sb-prose blockquote p:last-child { margin-bottom: 0; }

/* ---------- rules ---------- */

.sb-prose hr {
  border: 0;
  border-top: var(--bw) solid var(--border-subtle);
  margin: var(--stack-section) 0;
  max-width: var(--measure-read);
}

/* ---------- code blocks ---------- */

.sb-prose pre {
  font-family: var(--font-mono);
  font-size: var(--fs-read-sm);
  line-height: 1.6;
  color: var(--text-body);
  background: var(--surface-sunken);
  border: var(--bw) solid var(--border-default);
  border-radius: var(--radius);
  padding: var(--space-9) var(--space-10);
  overflow-x: auto;
  margin: 0 0 var(--stack-para);
  max-width: 100%;
}
.sb-prose pre code {
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font-size: inherit;
}

/* ---------- tables: hairline grid, mono uppercase heads ---------- */

.sb-prose .sb-tablewrap {
  overflow-x: auto;
  margin: 0 0 var(--stack-para);
  max-width: 100%;
  border: var(--bw) solid var(--border-default);
}
.sb-prose table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-ui);
  font-size: var(--fs-read-sm);
}
.sb-prose thead th {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  text-align: left;
  background: var(--surface-sunken);
  border-bottom: var(--bw) solid var(--border-default);
  padding: var(--pad-row);
  white-space: nowrap;
}
.sb-prose tbody td {
  padding: var(--pad-row);
  border-bottom: var(--bw) solid var(--border-subtle);
  border-right: var(--bw) solid var(--border-subtle);
  color: var(--text-secondary);
  vertical-align: top;
}
.sb-prose tbody td:last-child,
.sb-prose thead th:last-child { border-right: 0; }
.sb-prose tbody tr:last-child td { border-bottom: 0; }

/* Numeric columns are mono and right-aligned. Mark with
   <td class="sb-num"> — or let a generator detect it. */
.sb-prose td.sb-num,
.sb-prose th.sb-num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--text-body);
  white-space: nowrap;
}

/* ---------- media ---------- */

.sb-prose img {
  max-width: 100%;
  height: auto;
  border: var(--bw) solid var(--border-default);
}
.sb-prose figure { margin: 0 0 var(--stack-para); max-width: 100%; }
.sb-prose figcaption {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: var(--ls-wide);
  color: var(--text-ghost);
  margin-top: var(--space-3);
}

/* ---------- lead paragraph ---------- */

.sb-prose .sb-lead {
  font-size: var(--fs-read-lead);
  line-height: 1.5;
  color: var(--text-secondary);
}

@media (max-width: 640px) {
  .sb-prose { font-size: 16px; }
  .sb-prose h2 { margin-top: var(--stack-block); }
}

/* ============================================================
   ICONS — see components/core/icons.svg for the symbol set and
   the reasoning behind geometric glyphs over brand logos.
   Stroke inherits currentColor, so an icon takes the colour of
   whatever text register it sits in, and every semantic token
   applies to it without a per-icon rule.
   ============================================================ */

.sb-icon {
  width: 20px;
  height: 20px;
  flex: none;
  display: inline-block;
  vertical-align: middle;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}
.sb-icon-sm { width: 16px; height: 16px; }

/* The inlined symbol sprite. Hidden by class, never by an inline style —
   a CSP without 'unsafe-inline' blocks style attributes outright. */
.sb-icon-sprite { display: none; }

/* ---------- editorial note: corrections, updates, asides ----------
   A published piece is never silently revised, so it needs somewhere
   to carry a correction where the error is. Hairline and neutral, NOT
   accent: a correction is not an interaction, and accent is reserved.
   ------------------------------------------------------------------ */

.sb-prose .sb-note {
  background: var(--surface-sunken);
  border: var(--bw) solid var(--border-default);
  border-left: 2px solid var(--text-tertiary);
  border-radius: var(--radius);
  padding: var(--space-9) var(--space-10);
  margin: 0 0 var(--stack-para);
  font-size: var(--fs-read-sm);
  line-height: 1.6;
  max-width: 100%;
}
.sb-prose .sb-note p { margin-bottom: var(--space-5); }
.sb-prose .sb-note > :last-child { margin-bottom: 0; }

.sb-prose .sb-note-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: var(--space-5);
}


/* The pixel owl. Base rule only — the per-animation rules need a
   URL, which differs per consumer, so each generates them from
   assets/sprite/sprites.json. See the file header for the
   contract a generator must honour. */

/* ---- patterns/sprite.css ---- */
/* ============================================================
   SesebonUI · SPRITE — the pixel owl.

   The owl is the system's one figurative asset. It signifies
   wisdom, which is why it is allowed to exist at all in a
   language that otherwise bans decorative illustration: it
   carries a meaning the geometry cannot.

   BRAND USE — what the licence actually says. CraftPix's terms
   contain NO clause about logos or trademarks. An earlier
   version of this header claimed they forbade both; that was
   wrong, taken from a third-party licence summary rather than
   from CraftPix. What the terms DO say, on every tier:

     "You can NOT resell the source files (PNG, JPG, EPS, Adobe
      Illustrator, etc.) or slightly modified version of the art."

   So the constraint on brand use is not a prohibition, it is
   non-exclusivity plus that resale clause. The same owl is
   licensed to everyone who buys the pack, and a recoloured
   silhouette of it is plausibly a "slightly modified version".
   Using it as a character inside this product is squarely
   permitted. Registering it as a mark, or putting it on goods
   that are themselves sold, is not something this licence can
   support — and a mark over non-exclusive stock art is weak on
   its own terms regardless of what CraftPix permits.

   Mark therefore stays the registered-identity slot — wordmark,
   favicon — because it is ours outright, not because CraftPix
   forbids the alternative. Get advice before filing anything.

   The licence DOES prohibit AI/ML training use, universally and
   explicitly — keep these masks out of any model pipeline,
   including a visual-memory capture of a UI that renders them.

   ------------------------------------------------------------
   WHY MASKS, NOT PICTURES

   Every file in assets/sprite/ is a 1-bit ALPHA mask. It holds
   no palette. The element supplies the colour, so a sprite is
   amber under the default theme and frost under motifs/winter
   from ONE asset — it re-skins exactly the way Mark does. A
   coloured PNG would have been the single visual in the system
   that a motif swap could not reach.

   ------------------------------------------------------------
   WHAT LIVES HERE vs WHAT A CONSUMER GENERATES

   This file holds only what needs no URL. The per-animation
   rules do need one, and the right URL differs per consumer —
   a content-hashed path from a static build, a bundler import
   in the app — so each consumer generates them from
   assets/sprite/sprites.json. See site/build.mjs for a
   reference implementation.

   A generator MUST honour three things:

   1. Emit the natural size as `:where(.sprite.<name>)`.
      :where() contributes ZERO specificity, so a placement rule
      like `.herofig .sprite` can override it. Declared normally
      it ties with `.sprite.<name>` at (0,2,0) and wins on source
      order, silently killing every size override downstream.

   2. Derive width, height, mask-size and the keyframe travel
      from --sprite-cell, never from fixed pixels. One override
      then resizes a sprite correctly. Halving the 64px cell
      lands back on the art's native 32px, so scaled-down
      sprites stay pixel-exact.

      --sprite-cell is the cell HEIGHT. Width is
      `calc(var(--sprite-cell) * var(--sprite-aspect))`, because
      CELLS ARE NOT ALWAYS SQUARE: pull-up is 32x64 while every
      other sheet is 32x32. Emit the aspect calc unconditionally
      rather than special-casing squares — assuming square is
      what first mis-read pull-up as 3 frames of 64 instead of 6
      of 32, at half speed with two owls on screen. A hover swap
      must carry its TARGET's aspect too, or the new mask
      renders stretched to the old one's ratio.

   3. Emit `.once` AFTER every per-animation rule. Those rules
      set the `animation` SHORTHAND, which resets
      iteration-count and fill-mode — so `.sprite.once` declared
      earlier ties at (0,2,0) and loses, and a one-shot death
      animation loops forever.

   Frames advance on mask-position in PIXELS, never percentages.
   At mask-size 400% a 4-frame sheet under steps(4) lands on
   0/25/50/75%, which is BETWEEN cells and renders as two half
   characters.

   ------------------------------------------------------------
   MOTION

   Consumers are responsible for honouring
   prefers-reduced-motion. Freezing the animation leaves a sprite
   at mask-position 0 — frame one, a complete pose rather than a
   broken cell — so `animation: none` is a safe reduction.
   ============================================================ */

.sprite {
  display: block;
  flex: none;
  background-color: var(--accent);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  /* Belt and braces. The masks are pre-scaled 2x with nearest
     neighbour at generation time precisely because engines
     disagree about honouring image-rendering for MASK images,
     and a smoothed pixel sprite reads as a bug, not a style. */
  image-rendering: pixelated;
}


/* Elegant theme collection (47 palettes — generated). */

/* ---- sesebonui/themes.css ---- */
/* ============================================================
   SesebonUI · THEMES — 47 palettes.
   Generated by scripts/generate-themes.js — do not edit by hand.
   Regenerate:  npm run themes     Verify:  npm run themes:check

   Each palette supplies five HUES. Every lightness here is
   computed against the theme's own surface so the five-step
   text ladder, the accent, the alert and the data colours all
   clear their contrast floors on that ground.

   Activate: <html data-theme="<slug>">

   Rule: --status-alert keeps the ALERT HUE in every theme. Its
   lightness is fitted to the surface so the signal survives on
   a light ground — the invariant is "red stays red", and a red
   nobody can see is not honouring it. (graphite set the
   precedent with #FF5247.)
   ============================================================ */

/* Modern Contrast */
[data-theme="modern-contrast"] {
  /* Surfaces */
  --surface-base:      #FFFFFF;
  --surface-raised:    #F7F7F7;
  --surface-sunken:    #F0F0F0;
  --surface-chrome:    #FAFAFA;
  --surface-track:     #E9E9E9;
  /* Borders */
  --border-default:    #D9D9D9;
  --border-subtle:     #EBEBEB;
  /* Text */
  --text-primary:      #202020;
  --text-body:         #23314E;
  --text-secondary:    #526282;
  --text-tertiary:     #8A8A8A;
  --text-ghost:        #B4B4B4;
  /* Accent */
  --accent:            #9F6400;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(159,100,0,0.08);
  --accent-line:       rgba(159,100,0,0.18);
  --accent-dim:        #FFB73E;
  /* Status */
  --status-alert:      #E31011;
  --status-active:     #9F6400;
  --status-idle:       #8F8F8F;
  --alert-wash:        rgba(227,16,17,0.08);
  /* Data */
  --data-pos:          #9F6400;
  --data-warn:         #E31011;
  --data-neutral:      #23314E;
  --cat-health:        #00815F;
  --cat-financial:     #9F6400;
  --cat-preference:    #7462C2;
  --cat-biographical:  #2C76AC;
  --cat-general:       #717171;
  --code-string:       #8C6D00;
}

/* Moody Lavender */
[data-theme="moody-lavender"] {
  /* Surfaces */
  --surface-base:      #DBC9C5;
  --surface-raised:    #D5C0BB;
  --surface-sunken:    #CFB8B2;
  --surface-chrome:    #D7C3BF;
  --surface-track:     #CAB0AA;
  /* Borders */
  --border-default:    #BE9D96;
  --border-subtle:     #CCB2AC;
  /* Text */
  --text-primary:      #1A1A32;
  --text-body:         #2C2F48;
  --text-secondary:    #3E415C;
  --text-tertiary:     #71646F;
  --text-ghost:        #978995;
  /* Accent */
  --accent:            #574F4B;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(87,79,75,0.08);
  --accent-line:       rgba(87,79,75,0.18);
  --accent-dim:        #938781;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #574F4B;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #574F4B;
  --data-warn:         #A80004;
  --data-neutral:      #2C2F48;
  --cat-health:        #005D44;
  --cat-financial:     #574F4B;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Deep Maritime */
[data-theme="deep-maritime"] {
  /* Surfaces */
  --surface-base:      #1B263B;
  --surface-raised:    #202D47;
  --surface-sunken:    #172032;
  --surface-chrome:    #192336;
  --surface-track:     #24324E;
  /* Borders */
  --border-default:    #39517D;
  --border-subtle:     #293959;
  /* Text */
  --text-primary:      #E6E7E3;
  --text-body:         #B7CEED;
  --text-secondary:    #93AAC7;
  --text-tertiary:     #627D9B;
  --text-ghost:        #405976;
  /* Accent */
  --accent:            #8496A9;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(132,150,169,0.08);
  --accent-line:       rgba(132,150,169,0.18);
  --accent-dim:        #546678;
  /* Status */
  --status-alert:      #FF5C4D;
  --status-active:     #8496A9;
  --status-idle:       #767676;
  --alert-wash:        rgba(255,92,77,0.08);
  /* Data */
  --data-pos:          #8496A9;
  --data-warn:         #FF5C4D;
  --data-neutral:      #B7CEED;
  --cat-health:        #33A67F;
  --cat-financial:     #8496A9;
  --cat-preference:    #9787EA;
  --cat-biographical:  #539AD3;
  --cat-general:       #949494;
  --code-string:       #B6901E;
}

/* Spring Blossom */
[data-theme="spring-blossom"] {
  /* Surfaces */
  --surface-base:      #FEEAFA;
  --surface-raised:    #FDDBF6;
  --surface-sunken:    #FDCDF3;
  --surface-chrome:    #FEE0F8;
  --surface-track:     #FCC1F0;
  /* Borders */
  --border-default:    #FBA1E9;
  --border-subtle:     #FCC4F1;
  /* Text */
  --text-primary:      #141D2D;
  --text-body:         #362E3C;
  --text-secondary:    #5D5464;
  --text-tertiary:     #90777B;
  --text-ghost:        #BAA0A4;
  /* Accent */
  --accent:            #62657E;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(98,101,126,0.08);
  --accent-line:       rgba(98,101,126,0.18);
  --accent-dim:        #A1A3B6;
  /* Status */
  --status-alert:      #CE0006;
  --status-active:     #62657E;
  --status-idle:       #838383;
  --alert-wash:        rgba(206,0,6,0.08);
  /* Data */
  --data-pos:          #62657E;
  --data-warn:         #CE0006;
  --data-neutral:      #362E3C;
  --cat-health:        #007556;
  --cat-financial:     #62657E;
  --cat-preference:    #6A58B7;
  --cat-biographical:  #206BA1;
  --cat-general:       #666666;
  --code-string:       #7E6200;
}

/* Corporate Slate */
[data-theme="corporate-slate"] {
  /* Surfaces */
  --surface-base:      #FFFFFF;
  --surface-raised:    #F7F7F7;
  --surface-sunken:    #F0F0F0;
  --surface-chrome:    #FAFAFA;
  --surface-track:     #E9E9E9;
  /* Borders */
  --border-default:    #D9D9D9;
  --border-subtle:     #EBEBEB;
  /* Text */
  --text-primary:      #202020;
  --text-body:         #00383B;
  --text-secondary:    #36686B;
  --text-tertiary:     #8A8A8A;
  --text-ghost:        #B4B4B4;
  /* Accent */
  --accent:            #527690;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(82,118,144,0.08);
  --accent-line:       rgba(82,118,144,0.18);
  --accent-dim:        #9BB4C6;
  /* Status */
  --status-alert:      #E31011;
  --status-active:     #527690;
  --status-idle:       #8F8F8F;
  --alert-wash:        rgba(227,16,17,0.08);
  /* Data */
  --data-pos:          #527690;
  --data-warn:         #E31011;
  --data-neutral:      #00383B;
  --cat-health:        #00815F;
  --cat-financial:     #527690;
  --cat-preference:    #7462C2;
  --cat-biographical:  #2C76AC;
  --cat-general:       #717171;
  --code-string:       #8C6D00;
}

/* Soft Frost */
[data-theme="soft-frost"] {
  /* Surfaces */
  --surface-base:      #F0EFEB;
  --surface-raised:    #E9E8E2;
  --surface-sunken:    #E3E1DA;
  --surface-chrome:    #ECEAE5;
  --surface-track:     #DDDBD2;
  /* Borders */
  --border-default:    #CFCCBF;
  --border-subtle:     #DFDDD4;
  /* Text */
  --text-primary:      #141C36;
  --text-body:         #153439;
  --text-secondary:    #3F5E63;
  --text-tertiary:     #798093;
  --text-ghost:        #A1A9BE;
  /* Accent */
  --accent:            #72665D;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(114,102,93,0.08);
  --accent-line:       rgba(114,102,93,0.18);
  --accent-dim:        #ADA29B;
  /* Status */
  --status-alert:      #D30007;
  --status-active:     #72665D;
  --status-idle:       #848484;
  --alert-wash:        rgba(211,0,7,0.08);
  /* Data */
  --data-pos:          #72665D;
  --data-warn:         #D30007;
  --data-neutral:      #153439;
  --cat-health:        #007757;
  --cat-financial:     #72665D;
  --cat-preference:    #6C59B8;
  --cat-biographical:  #226DA2;
  --cat-general:       #676767;
  --code-string:       #806300;
}

/* Midnight Depths */
[data-theme="midnight-depths"] {
  /* Surfaces */
  --surface-base:      #312244;
  --surface-raised:    #39284F;
  --surface-sunken:    #2B1E3B;
  --surface-chrome:    #2E203F;
  --surface-track:     #3E2B57;
  /* Borders */
  --border-default:    #604285;
  --border-subtle:     #463061;
  /* Text */
  --text-primary:      #ACF3F9;
  --text-body:         #98D7E1;
  --text-secondary:    #77B5BF;
  --text-tertiary:     #94719F;
  --text-ghost:        #704F7A;
  /* Accent */
  --accent:            #55A4A6;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(85,164,166,0.08);
  --accent-line:       rgba(85,164,166,0.18);
  --accent-dim:        #3E787A;
  /* Status */
  --status-alert:      #FF6454;
  --status-active:     #55A4A6;
  --status-idle:       #797979;
  --alert-wash:        rgba(255,100,84,0.08);
  /* Data */
  --data-pos:          #55A4A6;
  --data-warn:         #FF6454;
  --data-neutral:      #98D7E1;
  --cat-health:        #37A982;
  --cat-financial:     #55A4A6;
  --cat-preference:    #9A8AEE;
  --cat-biographical:  #569ED6;
  --cat-general:       #979797;
  --code-string:       #B99323;
}

/* Earthy Minimalist */
[data-theme="earthy-minimalist"] {
  /* Surfaces */
  --surface-base:      #ECF8F8;
  --surface-raised:    #E0F4F4;
  --surface-sunken:    #D6F0F0;
  --surface-chrome:    #E5F5F5;
  --surface-track:     #CCECEC;
  /* Borders */
  --border-default:    #B4E3E3;
  --border-subtle:     #CFEDED;
  /* Text */
  --text-primary:      #2E1803;
  --text-body:         #392E22;
  --text-secondary:    #685B4E;
  --text-tertiary:     #8D8481;
  --text-ghost:        #B7ADAA;
  /* Accent */
  --accent:            #896557;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(137,101,87,0.08);
  --accent-line:       rgba(137,101,87,0.18);
  --accent-dim:        #BDA298;
  /* Status */
  --status-alert:      #DB0007;
  --status-active:     #896557;
  --status-idle:       #8A8A8A;
  --alert-wash:        rgba(219,0,7,0.08);
  /* Data */
  --data-pos:          #896557;
  --data-warn:         #DB0007;
  --data-neutral:      #392E22;
  --cat-health:        #007C5B;
  --cat-financial:     #896557;
  --cat-preference:    #715FBF;
  --cat-biographical:  #2771A7;
  --cat-general:       #6D6D6D;
  --code-string:       #876900;
}

/* Urban Sun */
[data-theme="urban-sun"] {
  /* Surfaces */
  --surface-base:      #E8EDDF;
  --surface-raised:    #E1E7D5;
  --surface-sunken:    #DAE2CC;
  --surface-chrome:    #E3E9D8;
  --surface-track:     #D4DDC3;
  /* Borders */
  --border-default:    #C5D1AE;
  --border-subtle:     #D6DFC6;
  /* Text */
  --text-primary:      #1D1D1C;
  --text-body:         #2F312F;
  --text-secondary:    #555755;
  --text-tertiary:     #75807B;
  --text-ghost:        #9EA9A4;
  /* Accent */
  --accent:            #7F6200;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(127,98,0,0.08);
  --accent-line:       rgba(127,98,0,0.18);
  --accent-dim:        #FFCA16;
  /* Status */
  --status-alert:      #CE0006;
  --status-active:     #7F6200;
  --status-idle:       #828282;
  --alert-wash:        rgba(206,0,6,0.08);
  /* Data */
  --data-pos:          #7F6200;
  --data-warn:         #CE0006;
  --data-neutral:      #2F312F;
  --cat-health:        #007556;
  --cat-financial:     #7F6200;
  --cat-preference:    #6956B5;
  --cat-biographical:  #206BA1;
  --cat-general:       #666666;
  --code-string:       #7E6200;
}

/* Berry Blush */
[data-theme="berry-blush"] {
  /* Surfaces */
  --surface-base:      #F9DBBD;
  --surface-raised:    #F8D3AF;
  --surface-sunken:    #F6CCA1;
  --surface-chrome:    #F8D6B4;
  --surface-track:     #F5C595;
  /* Borders */
  --border-default:    #F3B577;
  --border-subtle:     #F6C799;
  /* Text */
  --text-primary:      #3F031B;
  --text-body:         #660031;
  --text-secondary:    #922550;
  --text-tertiary:     #C34E6A;
  --text-ghost:        #F17690;
  /* Accent */
  --accent:            #96474F;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(150,71,79,0.08);
  --accent-line:       rgba(150,71,79,0.18);
  --accent-dim:        #C27D84;
  /* Status */
  --status-alert:      #C10005;
  --status-active:     #96474F;
  --status-idle:       #7A7A7A;
  --alert-wash:        rgba(193,0,5,0.08);
  /* Data */
  --data-pos:          #96474F;
  --data-warn:         #C10005;
  --data-neutral:      #660031;
  --cat-health:        #006D50;
  --cat-financial:     #96474F;
  --cat-preference:    #6450AE;
  --cat-biographical:  #166499;
  --cat-general:       #5F5F5F;
  --code-string:       #765B00;
}

/* Dusty Lilac */
[data-theme="dusty-lilac"] {
  /* Surfaces */
  --surface-base:      #E9C6CD;
  --surface-raised:    #E5BBC3;
  --surface-sunken:    #E1B0BA;
  --surface-chrome:    #E6BFC7;
  --surface-track:     #DDA7B2;
  /* Borders */
  --border-default:    #D48F9D;
  --border-subtle:     #DEA9B4;
  /* Text */
  --text-primary:      #28162D;
  --text-body:         #43283E;
  --text-secondary:    #563A51;
  --text-tertiary:     #7C6171;
  --text-ghost:        #A28696;
  /* Accent */
  --accent:            #6A4B48;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(106,75,72,0.08);
  --accent-line:       rgba(106,75,72,0.18);
  --accent-dim:        #A7817D;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #6A4B48;
  --status-idle:       #6D6D6D;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #6A4B48;
  --data-warn:         #A80004;
  --data-neutral:      #43283E;
  --cat-health:        #005D44;
  --cat-financial:     #6A4B48;
  --cat-preference:    #5743A0;
  --cat-biographical:  #005588;
  --cat-general:       #525252;
  --code-string:       #674F00;
}

/* Twilight Indigo */
[data-theme="twilight-indigo"] {
  /* Surfaces */
  --surface-base:      #0D1321;
  --surface-raised:    #121A2D;
  --surface-sunken:    #090E17;
  --surface-chrome:    #0B101C;
  --surface-track:     #151F35;
  /* Borders */
  --border-default:    #283B67;
  --border-subtle:     #192540;
  /* Text */
  --text-primary:      #D6E8FF;
  --text-body:         #AFD1EF;
  --text-secondary:    #7898B4;
  --text-tertiary:     #596C86;
  --text-ghost:        #394A63;
  /* Accent */
  --accent:            #888372;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(136,131,114,0.08);
  --accent-line:       rgba(136,131,114,0.18);
  --accent-dim:        #565348;
  /* Status */
  --status-alert:      #F83229;
  --status-active:     #888372;
  --status-idle:       #666666;
  --alert-wash:        rgba(248,50,41,0.08);
  /* Data */
  --data-pos:          #888372;
  --data-warn:         #F83229;
  --data-neutral:      #AFD1EF;
  --cat-health:        #18946F;
  --cat-financial:     #888372;
  --cat-preference:    #8575D6;
  --cat-biographical:  #4088BF;
  --cat-general:       #828282;
  --code-string:       #A27E00;
}

/* Powder Clouds */
[data-theme="powder-clouds"] {
  /* Surfaces */
  --surface-base:      #F0EFEB;
  --surface-raised:    #E9E8E2;
  --surface-sunken:    #E3E1DA;
  --surface-chrome:    #ECEAE5;
  --surface-track:     #DDDBD2;
  /* Borders */
  --border-default:    #CFCCBF;
  --border-subtle:     #DFDDD4;
  /* Text */
  --text-primary:      #001F33;
  --text-body:         #1F3341;
  --text-secondary:    #465B6A;
  --text-tertiary:     #8C7D74;
  --text-ghost:        #B6A69C;
  /* Accent */
  --accent:            #72665D;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(114,102,93,0.08);
  --accent-line:       rgba(114,102,93,0.18);
  --accent-dim:        #ADA29B;
  /* Status */
  --status-alert:      #D30007;
  --status-active:     #72665D;
  --status-idle:       #848484;
  --alert-wash:        rgba(211,0,7,0.08);
  /* Data */
  --data-pos:          #72665D;
  --data-warn:         #D30007;
  --data-neutral:      #1F3341;
  --cat-health:        #007757;
  --cat-financial:     #72665D;
  --cat-preference:    #6C59B8;
  --cat-biographical:  #226DA2;
  --cat-general:       #676767;
  --code-string:       #806300;
}

/* Muted Amethyst */
[data-theme="muted-amethyst"] {
  /* Surfaces */
  --surface-base:      #D6CFCB;
  --surface-raised:    #CFC7C2;
  --surface-sunken:    #C9BFBA;
  --surface-chrome:    #D2CAC5;
  --surface-track:     #C3B9B3;
  /* Borders */
  --border-default:    #B4A8A0;
  --border-subtle:     #C4BAB5;
  /* Text */
  --text-primary:      #1F1B2B;
  --text-body:         #362D3C;
  --text-secondary:    #4B4252;
  --text-tertiary:     #84606C;
  --text-ghost:        #AC8692;
  /* Accent */
  --accent:            #614F48;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(97,79,72,0.08);
  --accent-line:       rgba(97,79,72,0.18);
  --accent-dim:        #9D857B;
  /* Status */
  --status-alert:      #AD0004;
  --status-active:     #614F48;
  --status-idle:       #6F6F6F;
  --alert-wash:        rgba(173,0,4,0.08);
  /* Data */
  --data-pos:          #614F48;
  --data-warn:         #AD0004;
  --data-neutral:      #362D3C;
  --cat-health:        #006046;
  --cat-financial:     #614F48;
  --cat-preference:    #5945A1;
  --cat-biographical:  #00588C;
  --cat-general:       #545454;
  --code-string:       #685000;
}

/* Cherry Ash */
[data-theme="cherry-ash"] {
  /* Surfaces */
  --surface-base:      #FFFFFF;
  --surface-raised:    #F7F7F7;
  --surface-sunken:    #F0F0F0;
  --surface-chrome:    #FAFAFA;
  --surface-track:     #E9E9E9;
  /* Borders */
  --border-default:    #D9D9D9;
  --border-subtle:     #EBEBEB;
  /* Text */
  --text-primary:      #301A21;
  --text-body:         #571E2B;
  --text-secondary:    #8E4F5A;
  --text-tertiary:     #838C86;
  --text-ghost:        #ADB7B1;
  /* Accent */
  --accent:            #94656F;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(148,101,111,0.08);
  --accent-line:       rgba(148,101,111,0.18);
  --accent-dim:        #C5AAAF;
  /* Status */
  --status-alert:      #E31011;
  --status-active:     #94656F;
  --status-idle:       #8F8F8F;
  --alert-wash:        rgba(227,16,17,0.08);
  /* Data */
  --data-pos:          #94656F;
  --data-warn:         #E31011;
  --data-neutral:      #571E2B;
  --cat-health:        #00815F;
  --cat-financial:     #94656F;
  --cat-preference:    #7462C2;
  --cat-biographical:  #2C76AC;
  --cat-general:       #717171;
  --code-string:       #8C6D00;
}

/* Ocean Orchid */
[data-theme="ocean-orchid"] {
  /* Surfaces */
  --surface-base:      #DEC6DD;
  --surface-raised:    #D8BCD7;
  --surface-sunken:    #D3B3D2;
  --surface-chrome:    #DAC0D9;
  --surface-track:     #CEABCD;
  /* Borders */
  --border-default:    #C296C0;
  --border-subtle:     #CFADCE;
  /* Text */
  --text-primary:      #00202A;
  --text-body:         #1E3248;
  --text-secondary:    #2F445B;
  --text-tertiary:     #6A6483;
  --text-ghost:        #8E88A9;
  /* Accent */
  --accent:            #6A475B;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(106,71,91,0.08);
  --accent-line:       rgba(106,71,91,0.18);
  --accent-dim:        #A57992;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #6A475B;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #6A475B;
  --data-warn:         #A80004;
  --data-neutral:      #1E3248;
  --cat-health:        #005D44;
  --cat-financial:     #6A475B;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #525252;
  --code-string:       #654E00;
}

/* Coral Slate */
[data-theme="coral-slate"] {
  /* Surfaces */
  --surface-base:      #BDD5EA;
  --surface-raised:    #B1CDE6;
  --surface-sunken:    #A6C6E3;
  --surface-chrome:    #B5D0E8;
  --surface-track:     #9CC0E0;
  /* Borders */
  --border-default:    #83B0D8;
  --border-subtle:     #9FC2E0;
  /* Text */
  --text-primary:      #111E2B;
  --text-body:         #173152;
  --text-secondary:    #2D476A;
  --text-tertiary:     #CB2B2A;
  --text-ghost:        #FA5B51;
  /* Accent */
  --accent:            #55545B;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(85,84,91,0.08);
  --accent-line:       rgba(85,84,91,0.18);
  --accent-dim:        #8C8B94;
  /* Status */
  --status-alert:      #AD0004;
  --status-active:     #55545B;
  --status-idle:       #707070;
  --alert-wash:        rgba(173,0,4,0.08);
  /* Data */
  --data-pos:          #55545B;
  --data-warn:         #AD0004;
  --data-neutral:      #173152;
  --cat-health:        #006046;
  --cat-financial:     #55545B;
  --cat-preference:    #5945A1;
  --cat-biographical:  #00588C;
  --cat-general:       #555555;
  --code-string:       #6A5200;
}

/* Pure Porcelain */
[data-theme="pure-porcelain"] {
  /* Surfaces */
  --surface-base:      #FFFFFF;
  --surface-raised:    #F7F7F7;
  --surface-sunken:    #F0F0F0;
  --surface-chrome:    #FAFAFA;
  --surface-track:     #E9E9E9;
  /* Borders */
  --border-default:    #D9D9D9;
  --border-subtle:     #EBEBEB;
  /* Text */
  --text-primary:      #2E1D14;
  --text-body:         #383029;
  --text-secondary:    #696058;
  --text-tertiary:     #898B89;
  --text-ghost:        #B2B5B2;
  /* Accent */
  --accent:            #856D5E;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(133,109,94,0.08);
  --accent-line:       rgba(133,109,94,0.18);
  --accent-dim:        #BFAEA4;
  /* Status */
  --status-alert:      #E31011;
  --status-active:     #856D5E;
  --status-idle:       #8F8F8F;
  --alert-wash:        rgba(227,16,17,0.08);
  /* Data */
  --data-pos:          #856D5E;
  --data-warn:         #E31011;
  --data-neutral:      #383029;
  --cat-health:        #00815F;
  --cat-financial:     #856D5E;
  --cat-preference:    #7462C2;
  --cat-biographical:  #2C76AC;
  --cat-general:       #717171;
  --code-string:       #8C6D00;
}

/* Rich Burgundy */
[data-theme="rich-burgundy"] {
  /* Surfaces */
  --surface-base:      #5C1013;
  --surface-raised:    #6A1216;
  --surface-sunken:    #510E11;
  --surface-chrome:    #560F12;
  --surface-track:     #741418;
  /* Borders */
  --border-default:    #AF1E24;
  --border-subtle:     #81161B;
  /* Text */
  --text-primary:      #FFE1D0;
  --text-body:         #FFBCB3;
  --text-secondary:    #FF9385;
  --text-tertiary:     #DB5A4B;
  --text-ghost:        #AF3026;
  /* Accent */
  --accent:            #DD877A;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(221,135,122,0.08);
  --accent-line:       rgba(221,135,122,0.18);
  --accent-dim:        #BD4330;
  /* Status */
  --status-alert:      #FF7262;
  --status-active:     #DD877A;
  --status-idle:       #7F7F7F;
  --alert-wash:        rgba(255,114,98,0.08);
  /* Data */
  --data-pos:          #DD877A;
  --data-warn:         #FF7262;
  --data-neutral:      #FFBCB3;
  --cat-health:        #41B18A;
  --cat-financial:     #DD877A;
  --cat-preference:    #A090F5;
  --cat-biographical:  #5CA4DD;
  --cat-general:       #9D9D9D;
  --code-string:       #BE982A;
}

/* Vintage Steel */
[data-theme="vintage-steel"] {
  /* Surfaces */
  --surface-base:      #C1CFD4;
  --surface-raised:    #B8C8CE;
  --surface-sunken:    #AFC1C8;
  --surface-chrome:    #BBCAD0;
  --surface-track:     #A7BBC2;
  /* Borders */
  --border-default:    #94ACB5;
  --border-subtle:     #AABDC4;
  /* Text */
  --text-primary:      #2D1423;
  --text-body:         #392B44;
  --text-secondary:    #4B3D57;
  --text-tertiary:     #66667E;
  --text-ghost:        #8A8BA4;
  /* Accent */
  --accent:            #265A5D;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(38,90,93,0.08);
  --accent-line:       rgba(38,90,93,0.18);
  --accent-dim:        #4AAFB5;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #265A5D;
  --status-idle:       #6D6D6D;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #265A5D;
  --data-warn:         #A80004;
  --data-neutral:      #392B44;
  --cat-health:        #005D44;
  --cat-financial:     #265A5D;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #525252;
  --code-string:       #674F00;
}

/* Rustic Truffle */
[data-theme="rustic-truffle"] {
  /* Surfaces */
  --surface-base:      #D5CABF;
  --surface-raised:    #CFC2B5;
  --surface-sunken:    #C9BBAD;
  --surface-chrome:    #D1C5B9;
  --surface-track:     #C4B4A5;
  /* Borders */
  --border-default:    #B7A491;
  --border-subtle:     #C5B6A7;
  /* Text */
  --text-primary:      #2E1615;
  --text-body:         #3C2D23;
  --text-secondary:    #4E3F34;
  --text-tertiary:     #756454;
  --text-ghost:        #9C8A79;
  /* Accent */
  --accent:            #644D3B;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(100,77,59,0.08);
  --accent-line:       rgba(100,77,59,0.18);
  --accent-dim:        #A68368;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #644D3B;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #644D3B;
  --data-warn:         #A80004;
  --data-neutral:      #3C2D23;
  --cat-health:        #005D44;
  --cat-financial:     #644D3B;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Desert Rose */
[data-theme="desert-rose"] {
  /* Surfaces */
  --surface-base:      #D3CBC2;
  --surface-raised:    #CCC3B9;
  --surface-sunken:    #C6BCB1;
  --surface-chrome:    #CFC6BC;
  --surface-track:     #C1B6A9;
  /* Borders */
  --border-default:    #B3A596;
  --border-subtle:     #C2B7AB;
  /* Text */
  --text-primary:      #161E26;
  --text-body:         #462730;
  --text-secondary:    #593942;
  --text-tertiary:     #835E5C;
  --text-ghost:        #AB8481;
  /* Accent */
  --accent:            #654D34;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(101,77,52,0.08);
  --accent-line:       rgba(101,77,52,0.18);
  --accent-dim:        #AC865E;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #654D34;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #654D34;
  --data-warn:         #A80004;
  --data-neutral:      #462730;
  --cat-health:        #005D44;
  --cat-financial:     #654D34;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Industrial Dune */
[data-theme="industrial-dune"] {
  /* Surfaces */
  --surface-base:      #C3CED1;
  --surface-raised:    #BAC7CA;
  --surface-sunken:    #B2C0C4;
  --surface-chrome:    #BDC9CD;
  --surface-track:     #AABABE;
  /* Borders */
  --border-default:    #98ABB0;
  --border-subtle:     #ACBCC0;
  /* Text */
  --text-primary:      #151E26;
  --text-body:         #333029;
  --text-secondary:    #45423B;
  --text-tertiary:     #6E6756;
  --text-ghost:        #948D7C;
  /* Accent */
  --accent:            #595138;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(89,81,56,0.08);
  --accent-line:       rgba(89,81,56,0.18);
  --accent-dim:        #9F9167;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #595138;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #595138;
  --data-warn:         #A80004;
  --data-neutral:      #333029;
  --cat-health:        #005D44;
  --cat-financial:     #595138;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #525252;
  --code-string:       #654E00;
}

/* Shadowed Bone */
[data-theme="shadowed-bone"] {
  /* Surfaces */
  --surface-base:      #F1F0EA;
  --surface-raised:    #EBE9E1;
  --surface-sunken:    #E5E3D8;
  --surface-chrome:    #EDECE4;
  --surface-track:     #E0DDD0;
  /* Borders */
  --border-default:    #D2CFBC;
  --border-subtle:     #E1DFD2;
  /* Text */
  --text-primary:      #241A25;
  --text-body:         #322F33;
  --text-secondary:    #5B585C;
  --text-tertiary:     #877E86;
  --text-ghost:        #B1A7AF;
  /* Accent */
  --accent:            #6C695D;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(108,105,93,0.08);
  --accent-line:       rgba(108,105,93,0.18);
  --accent-dim:        #A9A69B;
  /* Status */
  --status-alert:      #D30007;
  --status-active:     #6C695D;
  --status-idle:       #848484;
  --alert-wash:        rgba(211,0,7,0.08);
  /* Data */
  --data-pos:          #6C695D;
  --data-warn:         #D30007;
  --data-neutral:      #322F33;
  --cat-health:        #007757;
  --cat-financial:     #6C695D;
  --cat-preference:    #6C59B8;
  --cat-biographical:  #226DA2;
  --cat-general:       #696969;
  --code-string:       #826500;
}

/* Blackberry Silk */
[data-theme="blackberry-silk"] {
  /* Surfaces */
  --surface-base:      #DEC8C3;
  --surface-raised:    #D8BFB9;
  --surface-sunken:    #D3B6B0;
  --surface-chrome:    #DAC2BC;
  --surface-track:     #CFAEA7;
  /* Borders */
  --border-default:    #C39B92;
  --border-subtle:     #D0B0A9;
  /* Text */
  --text-primary:      #350C2D;
  --text-body:         #532024;
  --text-secondary:    #683336;
  --text-tertiary:     #6E6560;
  --text-ghost:        #958B86;
  /* Accent */
  --accent:            #585041;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(88,80,65,0.08);
  --accent-line:       rgba(88,80,65,0.18);
  --accent-dim:        #9A8D76;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #585041;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #585041;
  --data-warn:         #A80004;
  --data-neutral:      #532024;
  --cat-health:        #005D44;
  --cat-financial:     #585041;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Camel & Graphite */
[data-theme="camel-graphite"] {
  /* Surfaces */
  --surface-base:      #D1CBC6;
  --surface-raised:    #CAC3BD;
  --surface-sunken:    #C4BCB5;
  --surface-chrome:    #CCC6C0;
  --surface-track:     #BEB5AE;
  /* Borders */
  --border-default:    #AFA49C;
  --border-subtle:     #BFB7B0;
  /* Text */
  --text-primary:      #201C1C;
  --text-body:         #373025;
  --text-secondary:    #494135;
  --text-tertiary:     #7F6046;
  --text-ghost:        #A7866B;
  /* Accent */
  --accent:            #6F4920;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(111,73,32,0.08);
  --accent-line:       rgba(111,73,32,0.18);
  --accent-dim:        #C7863E;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #6F4920;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #6F4920;
  --data-warn:         #A80004;
  --data-neutral:      #373025;
  --cat-health:        #005D44;
  --cat-financial:     #6F4920;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Lilac Haze */
[data-theme="lilac-haze"] {
  /* Surfaces */
  --surface-base:      #E1DEE9;
  --surface-raised:    #D8D5E3;
  --surface-sunken:    #D1CCDD;
  --surface-chrome:    #DBD8E5;
  --surface-track:     #C9C4D8;
  /* Borders */
  --border-default:    #B7B0CA;
  --border-subtle:     #CBC6D9;
  /* Text */
  --text-primary:      #1F1933;
  --text-body:         #3D2D2D;
  --text-secondary:    #5D4A4B;
  --text-tertiary:     #777181;
  --text-ghost:        #9E98A9;
  /* Accent */
  --accent:            #665778;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(102,87,120,0.08);
  --accent-line:       rgba(102,87,120,0.18);
  --accent-dim:        #9E90AF;
  /* Status */
  --status-alert:      #BF0005;
  --status-active:     #665778;
  --status-idle:       #797979;
  --alert-wash:        rgba(191,0,5,0.08);
  /* Data */
  --data-pos:          #665778;
  --data-warn:         #BF0005;
  --data-neutral:      #3D2D2D;
  --cat-health:        #006A4D;
  --cat-financial:     #665778;
  --cat-preference:    #614EAB;
  --cat-biographical:  #136297;
  --cat-general:       #5D5D5D;
  --code-string:       #745A00;
}

/* Olive Ash */
[data-theme="olive-ash"] {
  /* Surfaces */
  --surface-base:      #D5D0CD;
  --surface-raised:    #CEC8C4;
  --surface-sunken:    #C7C1BD;
  --surface-chrome:    #D0CBC7;
  --surface-track:     #C1BAB5;
  /* Borders */
  --border-default:    #B2A9A3;
  --border-subtle:     #C3BCB7;
  /* Text */
  --text-primary:      #1E1D13;
  --text-body:         #313123;
  --text-secondary:    #464637;
  --text-tertiary:     #706960;
  --text-ghost:        #969086;
  /* Accent */
  --accent:            #595547;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(89,85,71,0.08);
  --accent-line:       rgba(89,85,71,0.18);
  --accent-dim:        #97917D;
  /* Status */
  --status-alert:      #AD0004;
  --status-active:     #595547;
  --status-idle:       #6F6F6F;
  --alert-wash:        rgba(173,0,4,0.08);
  /* Data */
  --data-pos:          #595547;
  --data-warn:         #AD0004;
  --data-neutral:      #313123;
  --cat-health:        #006046;
  --cat-financial:     #595547;
  --cat-preference:    #5945A1;
  --cat-biographical:  #00588C;
  --cat-general:       #555555;
  --code-string:       #685000;
}

/* Sunlit Walnut */
[data-theme="sunlit-walnut"] {
  /* Surfaces */
  --surface-base:      #E7C598;
  --surface-raised:    #E4BE8B;
  --surface-sunken:    #E1B780;
  --surface-chrome:    #E5C090;
  --surface-track:     #DFB175;
  /* Borders */
  --border-default:    #D9A25A;
  --border-subtle:     #DFB378;
  /* Text */
  --text-primary:      #420010;
  --text-body:         #532308;
  --text-secondary:    #66341B;
  --text-tertiary:     #895F35;
  --text-ghost:        #B08359;
  /* Accent */
  --accent:            #575400;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(87,84,0,0.08);
  --accent-line:       rgba(87,84,0,0.18);
  --accent-dim:        #DCD500;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #575400;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #575400;
  --data-warn:         #A80004;
  --data-neutral:      #532308;
  --cat-health:        #005D44;
  --cat-financial:     #575400;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Stormy Rose */
[data-theme="stormy-rose"] {
  /* Surfaces */
  --surface-base:      #CFCBC1;
  --surface-raised:    #C8C4B8;
  --surface-sunken:    #C2BDB0;
  --surface-chrome:    #CBC6BB;
  --surface-track:     #BCB7A9;
  /* Borders */
  --border-default:    #AEA796;
  --border-subtle:     #BEB8AB;
  /* Text */
  --text-primary:      #002125;
  --text-body:         #15333F;
  --text-secondary:    #284651;
  --text-tertiary:     #546C62;
  --text-ghost:        #789187;
  /* Accent */
  --accent:            #6F4646;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(111,70,70,0.08);
  --accent-line:       rgba(111,70,70,0.18);
  --accent-dim:        #A67272;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #6F4646;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #6F4646;
  --data-warn:         #A80004;
  --data-neutral:      #15333F;
  --cat-health:        #005D44;
  --cat-financial:     #6F4646;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Pacific Lace */
[data-theme="pacific-lace"] {
  /* Surfaces */
  --surface-base:      #FFFFFF;
  --surface-raised:    #F7F7F7;
  --surface-sunken:    #F0F0F0;
  --surface-chrome:    #FAFAFA;
  --surface-track:     #E9E9E9;
  /* Borders */
  --border-default:    #D9D9D9;
  --border-subtle:     #EBEBEB;
  /* Text */
  --text-primary:      #202020;
  --text-body:         #343225;
  --text-secondary:    #646254;
  --text-tertiary:     #8D897C;
  --text-ghost:        #B8B4A7;
  /* Accent */
  --accent:            #007D8B;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(0,125,139,0.08);
  --accent-line:       rgba(0,125,139,0.18);
  --accent-dim:        #33EAFF;
  /* Status */
  --status-alert:      #E31011;
  --status-active:     #007D8B;
  --status-idle:       #8F8F8F;
  --alert-wash:        rgba(227,16,17,0.08);
  /* Data */
  --data-pos:          #007D8B;
  --data-warn:         #E31011;
  --data-neutral:      #343225;
  --cat-health:        #00815F;
  --cat-financial:     #007D8B;
  --cat-preference:    #7462C2;
  --cat-biographical:  #2C76AC;
  --cat-general:       #717171;
  --code-string:       #8C6D00;
}

/* Mocha Blush */
[data-theme="mocha-blush"] {
  /* Surfaces */
  --surface-base:      #D1CCDC;
  --surface-raised:    #C9C3D6;
  --surface-sunken:    #C1BAD0;
  --surface-chrome:    #CCC6D8;
  --surface-track:     #BAB2CA;
  /* Borders */
  --border-default:    #A89FBD;
  --border-subtle:     #BCB4CC;
  /* Text */
  --text-primary:      #29191B;
  --text-body:         #28323A;
  --text-secondary:    #3B454E;
  --text-tertiary:     #7B625C;
  --text-ghost:        #A28881;
  /* Accent */
  --accent:            #575053;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(87,80,83,0.08);
  --accent-line:       rgba(87,80,83,0.18);
  --accent-dim:        #92898D;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #575053;
  --status-idle:       #6D6D6D;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #575053;
  --data-warn:         #A80004;
  --data-neutral:      #28323A;
  --cat-health:        #005F45;
  --cat-financial:     #575053;
  --cat-preference:    #5743A0;
  --cat-biographical:  #005588;
  --cat-general:       #525252;
  --code-string:       #674F00;
}

/* Teal & Steel */
[data-theme="teal-steel"] {
  /* Surfaces */
  --surface-base:      #B7D5D4;
  --surface-raised:    #ADCFCE;
  --surface-sunken:    #A4CAC9;
  --surface-chrome:    #B1D1D0;
  --surface-track:     #9CC5C4;
  /* Borders */
  --border-default:    #87B9B7;
  --border-subtle:     #9EC6C5;
  /* Text */
  --text-primary:      #181E20;
  --text-body:         #133535;
  --text-secondary:    #284A4A;
  --text-tertiary:     #5D6C70;
  --text-ghost:        #829397;
  /* Accent */
  --accent:            #1F5B5F;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(31,91,95,0.08);
  --accent-line:       rgba(31,91,95,0.18);
  --accent-dim:        #3DB3BB;
  /* Status */
  --status-alert:      #AD0004;
  --status-active:     #1F5B5F;
  --status-idle:       #6F6F6F;
  --alert-wash:        rgba(173,0,4,0.08);
  /* Data */
  --data-pos:          #1F5B5F;
  --data-warn:         #AD0004;
  --data-neutral:      #133535;
  --cat-health:        #006046;
  --cat-financial:     #1F5B5F;
  --cat-preference:    #5945A1;
  --cat-biographical:  #00588C;
  --cat-general:       #545454;
  --code-string:       #685000;
}

/* Monolithic Grey */
[data-theme="monolithic-grey"] {
  /* Surfaces */
  --surface-base:      #2F2E2E;
  --surface-raised:    #383636;
  --surface-sunken:    #282727;
  --surface-chrome:    #2B2A2A;
  --surface-track:     #3D3C3C;
  /* Borders */
  --border-default:    #605E5E;
  --border-subtle:     #454343;
  /* Text */
  --text-primary:      #EDE6E6;
  --text-body:         #CFCBDD;
  --text-secondary:    #B5B1C3;
  --text-tertiary:     #868485;
  --text-ghost:        #626061;
  /* Accent */
  --accent:            #A4A096;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(164,160,150,0.08);
  --accent-line:       rgba(164,160,150,0.18);
  --accent-dim:        #736F64;
  /* Status */
  --status-alert:      #FF7565;
  --status-active:     #A4A096;
  --status-idle:       #808080;
  --alert-wash:        rgba(255,117,101,0.08);
  /* Data */
  --data-pos:          #A4A096;
  --data-warn:         #FF7565;
  --data-neutral:      #CFCBDD;
  --cat-health:        #41B18A;
  --cat-financial:     #A4A096;
  --cat-preference:    #A292F6;
  --cat-biographical:  #5EA5DF;
  --cat-general:       #A0A0A0;
  --code-string:       #C19B2E;
}

/* Wisteria Night */
[data-theme="wisteria-night"] {
  /* Surfaces */
  --surface-base:      #FFFFFF;
  --surface-raised:    #F7F7F7;
  --surface-sunken:    #F0F0F0;
  --surface-chrome:    #FAFAFA;
  --surface-track:     #E9E9E9;
  /* Borders */
  --border-default:    #D9D9D9;
  --border-subtle:     #EBEBEB;
  /* Text */
  --text-primary:      #361235;
  --text-body:         #3B294E;
  --text-secondary:    #6D5982;
  --text-tertiary:     #978686;
  --text-ghost:        #C3B1B1;
  /* Accent */
  --accent:            #8B667A;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(139,102,122,0.08);
  --accent-line:       rgba(139,102,122,0.18);
  --accent-dim:        #C0AAB6;
  /* Status */
  --status-alert:      #E31011;
  --status-active:     #8B667A;
  --status-idle:       #8F8F8F;
  --alert-wash:        rgba(227,16,17,0.08);
  /* Data */
  --data-pos:          #8B667A;
  --data-warn:         #E31011;
  --data-neutral:      #3B294E;
  --cat-health:        #00815F;
  --cat-financial:     #8B667A;
  --cat-preference:    #7462C2;
  --cat-biographical:  #2C76AC;
  --cat-general:       #717171;
  --code-string:       #8C6D00;
}

/* Vintage Grape */
[data-theme="vintage-grape"] {
  /* Surfaces */
  --surface-base:      #C9CECA;
  --surface-raised:    #C1C6C2;
  --surface-sunken:    #B9C0BB;
  --surface-chrome:    #C4C9C5;
  --surface-track:     #B2B9B4;
  /* Borders */
  --border-default:    #A1AAA3;
  --border-subtle:     #B4BBB6;
  /* Text */
  --text-primary:      #231830;
  --text-body:         #382C40;
  --text-secondary:    #4A3E53;
  --text-tertiary:     #616874;
  --text-ghost:        #878E9B;
  /* Accent */
  --accent:            #505437;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(80,84,55,0.08);
  --accent-line:       rgba(80,84,55,0.18);
  --accent-dim:        #959C68;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #505437;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #505437;
  --data-warn:         #A80004;
  --data-neutral:      #382C40;
  --cat-health:        #005D44;
  --cat-financial:     #505437;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #525252;
  --code-string:       #654E00;
}

/* Golden Olive */
[data-theme="golden-olive"] {
  /* Surfaces */
  --surface-base:      #D9CA82;
  --surface-raised:    #D5C576;
  --surface-sunken:    #D2C06B;
  --surface-chrome:    #D7C77A;
  --surface-track:     #CFBC61;
  /* Borders */
  --border-default:    #C7B147;
  --border-subtle:     #D0BD63;
  /* Text */
  --text-primary:      #181E17;
  --text-body:         #39300B;
  --text-secondary:    #4C421E;
  --text-tertiary:     #A35000;
  --text-ghost:        #D7711E;
  /* Accent */
  --accent:            #565237;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(86,82,55,0.08);
  --accent-line:       rgba(86,82,55,0.18);
  --accent-dim:        #8F885B;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #565237;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #565237;
  --data-warn:         #A80004;
  --data-neutral:      #39300B;
  --cat-health:        #005D44;
  --cat-financial:     #565237;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Muted Fern */
[data-theme="muted-fern"] {
  /* Surfaces */
  --surface-base:      #040303;
  --surface-raised:    #0E0A0A;
  --surface-sunken:    #000000;
  --surface-chrome:    #000000;
  --surface-track:     #140F0F;
  /* Borders */
  --border-default:    #3B2D2D;
  --border-subtle:     #1D1616;
  /* Text */
  --text-primary:      #D3E7CB;
  --text-body:         #BDCFCA;
  --text-secondary:    #7C8E88;
  --text-tertiary:     #51665F;
  --text-ghost:        #31453F;
  /* Accent */
  --accent:            #84776F;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(132,119,111,0.08);
  --accent-line:       rgba(132,119,111,0.18);
  --accent-dim:        #4A433E;
  /* Status */
  --status-alert:      #ED231D;
  --status-active:     #84776F;
  --status-idle:       #5F5F5F;
  --alert-wash:        rgba(237,35,29,0.08);
  /* Data */
  --data-pos:          #84776F;
  --data-warn:         #ED231D;
  --data-neutral:      #BDCFCA;
  --cat-health:        #008B67;
  --cat-financial:     #84776F;
  --cat-preference:    #7D6BCC;
  --cat-biographical:  #367FB6;
  --cat-general:       #797979;
  --code-string:       #977500;
}

/* Olive Cherry */
[data-theme="olive-cherry"] {
  /* Surfaces */
  --surface-base:      #31081F;
  --surface-raised:    #3F0A28;
  --surface-sunken:    #260618;
  --surface-chrome:    #2B071B;
  --surface-track:     #490C2E;
  /* Borders */
  --border-default:    #841654;
  --border-subtle:     #560E37;
  /* Text */
  --text-primary:      #E4E8E1;
  --text-body:         #C1D1C6;
  --text-secondary:    #8E9D93;
  --text-tertiary:     #6F6F6F;
  --text-ghost:        #4C4C4C;
  /* Accent */
  --accent:            #CD6B6A;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(205,107,106,0.08);
  --accent-line:       rgba(205,107,106,0.18);
  --accent-dim:        #933231;
  /* Status */
  --status-alert:      #FD392E;
  --status-active:     #CD6B6A;
  --status-idle:       #6A6A6A;
  --alert-wash:        rgba(253,57,46,0.08);
  /* Data */
  --data-pos:          #CD6B6A;
  --data-warn:         #FD392E;
  --data-neutral:      #C1D1C6;
  --cat-health:        #219974;
  --cat-financial:     #CD6B6A;
  --cat-preference:    #8A79DB;
  --cat-biographical:  #458CC4;
  --cat-general:       #878787;
  --code-string:       #A78200;
}

/* Frosted Lime */
[data-theme="frosted-lime"] {
  /* Surfaces */
  --surface-base:      #F1F7EE;
  --surface-raised:    #E8F2E3;
  --surface-sunken:    #E0EDDA;
  --surface-chrome:    #EBF4E7;
  --surface-track:     #D9E9D1;
  /* Borders */
  --border-default:    #C6DFBA;
  --border-subtle:     #DBEAD3;
  /* Text */
  --text-primary:      #0F2101;
  --text-body:         #293423;
  --text-secondary:    #54614E;
  --text-tertiary:     #7D8964;
  --text-ghost:        #A8B48E;
  /* Accent */
  --accent:            #677216;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(103,114,22,0.08);
  --accent-line:       rgba(103,114,22,0.18);
  --accent-dim:        #CADC49;
  /* Status */
  --status-alert:      #DB0007;
  --status-active:     #677216;
  --status-idle:       #898989;
  --alert-wash:        rgba(219,0,7,0.08);
  /* Data */
  --data-pos:          #677216;
  --data-warn:         #DB0007;
  --data-neutral:      #293423;
  --cat-health:        #007C5B;
  --cat-financial:     #677216;
  --cat-preference:    #705EBD;
  --cat-biographical:  #2771A7;
  --cat-general:       #6C6C6C;
  --code-string:       #876900;
}

/* Deep Onyx Teal */
[data-theme="deep-onyx-teal"] {
  /* Surfaces */
  --surface-base:      #1A1D1A;
  --surface-raised:    #222622;
  --surface-sunken:    #141614;
  --surface-chrome:    #171917;
  --surface-track:     #272C27;
  /* Borders */
  --border-default:    #485048;
  --border-subtle:     #2E342E;
  /* Text */
  --text-primary:      #C6EEE9;
  --text-body:         #BBD0DD;
  --text-secondary:    #8EA2AE;
  --text-tertiary:     #5C7873;
  --text-ghost:        #3B5651;
  /* Accent */
  --accent:            #7C908A;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(124,144,138,0.08);
  --accent-line:       rgba(124,144,138,0.18);
  --accent-dim:        #4F5D59;
  /* Status */
  --status-alert:      #FF4639;
  --status-active:     #7C908A;
  --status-idle:       #6F6F6F;
  --alert-wash:        rgba(255,70,57,0.08);
  /* Data */
  --data-pos:          #7C908A;
  --data-warn:         #FF4639;
  --data-neutral:      #BBD0DD;
  --cat-health:        #289E78;
  --cat-financial:     #7C908A;
  --cat-preference:    #8E7EE0;
  --cat-biographical:  #4A91C9;
  --cat-general:       #8C8C8C;
  --code-string:       #AC8709;
}

/* Grape Mint */
[data-theme="grape-mint"] {
  /* Surfaces */
  --surface-base:      #C1CFCF;
  --surface-raised:    #B8C8C8;
  --surface-sunken:    #B0C2C2;
  --surface-chrome:    #BBCBCB;
  --surface-track:     #A9BCBC;
  /* Borders */
  --border-default:    #96AEAE;
  --border-subtle:     #ABBEBE;
  /* Text */
  --text-primary:      #2F1420;
  --text-body:         #3E2841;
  --text-secondary:    #533B56;
  --text-tertiary:     #6A657C;
  --text-ghost:        #8F8AA2;
  /* Accent */
  --accent:            #41573B;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(65,87,59,0.08);
  --accent-line:       rgba(65,87,59,0.18);
  --accent-dim:        #749A6A;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #41573B;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #41573B;
  --data-warn:         #A80004;
  --data-neutral:      #3E2841;
  --cat-health:        #005D44;
  --cat-financial:     #41573B;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #525252;
  --code-string:       #674F00;
}

/* Shadowed Thistle */
[data-theme="shadowed-thistle"] {
  /* Surfaces */
  --surface-base:      #D6C9D0;
  --surface-raised:    #CFC0C8;
  --surface-sunken:    #C9B8C1;
  --surface-chrome:    #D2C3CB;
  --surface-track:     #C3B0BB;
  /* Borders */
  --border-default:    #B59EAA;
  --border-subtle:     #C5B2BC;
  /* Text */
  --text-primary:      #201B28;
  --text-body:         #412C1D;
  --text-secondary:    #543E2F;
  --text-tertiary:     #716558;
  --text-ghost:        #988B7D;
  /* Accent */
  --accent:            #514D66;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(81,77,102,0.08);
  --accent-line:       rgba(81,77,102,0.18);
  --accent-dim:        #847F9E;
  /* Status */
  --status-alert:      #A80004;
  --status-active:     #514D66;
  --status-idle:       #6C6C6C;
  --alert-wash:        rgba(168,0,4,0.08);
  /* Data */
  --data-pos:          #514D66;
  --data-warn:         #A80004;
  --data-neutral:      #412C1D;
  --cat-health:        #005D44;
  --cat-financial:     #514D66;
  --cat-preference:    #56429E;
  --cat-biographical:  #005588;
  --cat-general:       #515151;
  --code-string:       #654E00;
}

/* Pine & Lilac */
[data-theme="pine-lilac"] {
  /* Surfaces */
  --surface-base:      #DFD9E2;
  --surface-raised:    #D7D0DB;
  --surface-sunken:    #D1C8D5;
  --surface-chrome:    #DAD3DE;
  --surface-track:     #CAC0CF;
  /* Borders */
  --border-default:    #BAAEC1;
  --border-subtle:     #CCC2D1;
  /* Text */
  --text-primary:      #002123;
  --text-body:         #2B303D;
  --text-secondary:    #464C59;
  --text-tertiary:     #7F6A89;
  --text-ghost:        #A790B1;
  /* Accent */
  --accent:            #04684C;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(4,104,76,0.08);
  --accent-line:       rgba(4,104,76,0.18);
  --accent-dim:        #0DF6B5;
  /* Status */
  --status-alert:      #BA0005;
  --status-active:     #04684C;
  --status-idle:       #767676;
  --alert-wash:        rgba(186,0,5,0.08);
  /* Data */
  --data-pos:          #04684C;
  --data-warn:         #BA0005;
  --data-neutral:      #2B303D;
  --cat-health:        #00684C;
  --cat-financial:     #04684C;
  --cat-preference:    #5E4BA8;
  --cat-biographical:  #0E5F94;
  --cat-general:       #5B5B5B;
  --code-string:       #715700;
}

/* Almond Sky */
[data-theme="almond-sky"] {
  /* Surfaces */
  --surface-base:      #F9F9F7;
  --surface-raised:    #F2F2EE;
  --surface-sunken:    #ECECE6;
  --surface-chrome:    #F5F5F1;
  --surface-track:     #E6E6DE;
  /* Borders */
  --border-default:    #D8D8CB;
  --border-subtle:     #E8E8E0;
  /* Text */
  --text-primary:      #141F21;
  --text-body:         #442A20;
  --text-secondary:    #74574B;
  --text-tertiary:     #7E8987;
  --text-ghost:        #A8B4B2;
  /* Accent */
  --accent:            #866756;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(134,103,86,0.08);
  --accent-line:       rgba(134,103,86,0.18);
  --accent-dim:        #BEA79A;
  /* Status */
  --status-alert:      #DE0007;
  --status-active:     #866756;
  --status-idle:       #8A8A8A;
  --alert-wash:        rgba(222,0,7,0.08);
  /* Data */
  --data-pos:          #866756;
  --data-warn:         #DE0007;
  --data-neutral:      #442A20;
  --cat-health:        #007E5C;
  --cat-financial:     #866756;
  --cat-preference:    #715FBF;
  --cat-biographical:  #2973A9;
  --cat-general:       #6D6D6D;
  --code-string:       #896A00;
}

/* Prussian Dim */
[data-theme="prussian-dim"] {
  /* Surfaces */
  --surface-base:      #FFFFFF;
  --surface-raised:    #F7F7F7;
  --surface-sunken:    #F0F0F0;
  --surface-chrome:    #FAFAFA;
  --surface-track:     #E9E9E9;
  /* Borders */
  --border-default:    #D9D9D9;
  --border-subtle:     #EBEBEB;
  /* Text */
  --text-primary:      #16203C;
  --text-body:         #2A332E;
  --text-secondary:    #59635D;
  --text-tertiary:     #808C8C;
  --text-ghost:        #ABB7B7;
  /* Accent */
  --accent:            #57739C;
  --accent-ink:        #FFFFFF;
  --accent-wash:       rgba(87,115,156,0.08);
  --accent-line:       rgba(87,115,156,0.18);
  --accent-dim:        #A1B2CA;
  /* Status */
  --status-alert:      #E31011;
  --status-active:     #57739C;
  --status-idle:       #8F8F8F;
  --alert-wash:        rgba(227,16,17,0.08);
  /* Data */
  --data-pos:          #57739C;
  --data-warn:         #E31011;
  --data-neutral:      #2A332E;
  --cat-health:        #00815F;
  --cat-financial:     #57739C;
  --cat-preference:    #7462C2;
  --cat-biographical:  #2C76AC;
  --cat-general:       #717171;
  --code-string:       #8C6D00;
}

/* Candy Onyx */
[data-theme="candy-onyx"] {
  /* Surfaces */
  --surface-base:      #2E0219;
  --surface-raised:    #3E0322;
  --surface-sunken:    #210112;
  --surface-chrome:    #270215;
  --surface-track:     #490328;
  /* Borders */
  --border-default:    #8B064B;
  --border-subtle:     #580430;
  /* Text */
  --text-primary:      #FFDFE0;
  --text-body:         #BBD0DD;
  --text-secondary:    #8599A5;
  --text-tertiary:     #696D69;
  --text-ghost:        #484B48;
  /* Accent */
  --accent:            #868846;
  --accent-ink:        #0B0B0B;
  --accent-wash:       rgba(134,136,70,0.08);
  --accent-line:       rgba(134,136,70,0.18);
  --accent-dim:        #58592E;
  /* Status */
  --status-alert:      #FA352B;
  --status-active:     #868846;
  --status-idle:       #696969;
  --alert-wash:        rgba(250,53,43,0.08);
  /* Data */
  --data-pos:          #868846;
  --data-warn:         #FA352B;
  --data-neutral:      #BBD0DD;
  --cat-health:        #1B9671;
  --cat-financial:     #868846;
  --cat-preference:    #8776D8;
  --cat-biographical:  #438BC3;
  --cat-general:       #848484;
  --code-string:       #A47F00;
}


/* Motifs (opt-in skins). Activate with e.g. <html data-motif="winter">. */

/* ---- motifs/winter.css ---- */
/* ============================================================
   SesebonUI · MOTIF — Winter
   ------------------------------------------------------------
   Proof that a seasonal reskin is a ONE-FILE token drop.
   Activate: <html data-motif="winter">
   Rules honored:
   - Only surfaces / text / accent / decoration are re-bound.
   - --status-alert is NOT touched (safety red stays red).
   - Spacing, radius, type are untouched (structure is permanent).
   ============================================================ */

[data-motif="winter"] {
  /* Cool-shifted surfaces */
  --surface-base:    #04070b;
  --surface-raised:  #0a0f15;
  --surface-sunken:  #070b10;
  --surface-chrome:  #05080c;
  --border-default:  #16202b;
  --border-subtle:   #101822;

  /* Frost accent replaces amber */
  --accent:          #8FD3FF;
  --accent-ink:      #04141f;
  --accent-wash:     rgba(143,211,255,.08);
  --accent-line:     rgba(143,211,255,.20);

  /* Status roles that ALSO read accent shift with it… */
  --status-active:   #8FD3FF;
  /* …but the alert role stays its invariant red. (Intentionally absent.) */

  /* Decoration hooks — host reads these to mount ambient layers */
  --motif-ambient:   rgba(143,211,255,.06);
}


/* ---- site ---- */
/* ============================================================
   SESEBON SITE — layout only.

   Everything typographic now lives in the design system: the
   editorial tier in tokens/typography.css, the reading surface
   in components/patterns/prose.css. This file holds ONLY what
   is specific to this site's page furniture — chrome, hero,
   cards, listings, CV rows.

   If a rule here starts describing how text reads rather than
   where a box sits, it belongs upstream in SesebonUI instead.

   Rules inherited and kept:
   - Semantic tokens only. No --sb-* primitive is touched.
   - --status-alert is never re-bound.
   - Accent is interaction, not decoration. It appears on links,
     hover states and DATA encodings (--data-*), never as an
     ornamental rule or marker.
   - Radius is 0 and shadows are absent. Depth is surface tint
     plus a 1px line.
   ============================================================ */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--surface-base);
  color: var(--text-body);
  font-family: var(--font-ui);
  font-size: var(--fs-read-sm);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.skip { position: absolute; left: -9999px; top: 0; background: var(--accent); color: var(--accent-ink); padding: var(--space-3) var(--space-7); font-family: var(--font-mono); font-size: var(--fs-label); z-index: 10; }
.skip:focus { left: 0; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---------- shared atoms ---------- */

.mono-label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.mono-label.accent { color: var(--accent); }
.mono-label.muted  { color: var(--text-ghost); }

a { color: var(--accent); text-underline-offset: 3px; }

/* ---------- chrome ---------- */

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-7);
  padding: 0 var(--canvas-pad);
  min-height: var(--h-topbar);
  border-bottom: var(--bw) solid var(--border-default);
  background: var(--surface-chrome);
  position: sticky; top: 0; z-index: 5;
}

.wordmark {
  font-family: var(--font-mono);
  font-size: var(--fs-display);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-wide);
  color: var(--text-primary);
  text-decoration: none;
}
.wordmark::before {
  content: ""; display: inline-block;
  width: 9px; height: 9px;
  margin-right: var(--space-3);
  border: 2px solid var(--accent);
}

.topbar nav { display: flex; gap: var(--space-9); }
.topbar nav a {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-secondary);
  text-decoration: none;
}
.topbar nav a:hover, .topbar nav a[aria-current="page"] { color: var(--accent); }

main {
  max-width: var(--measure-page);
  margin: 0 auto;
  padding: 0 var(--canvas-pad) var(--stack-section);
}

.sitefoot {
  max-width: var(--measure-page);
  margin: 0 auto;
  padding: var(--space-9) var(--canvas-pad) var(--space-10);
  border-top: var(--bw) solid var(--border-subtle);
  display: flex; flex-wrap: wrap;
  gap: var(--space-5) var(--space-10);
  justify-content: space-between;
}

/* ---------- hero / page heads ---------- */

.hero, .pagehead {
  padding: var(--stack-section) 0 var(--stack-block);
  border-bottom: var(--bw) solid var(--border-subtle);
  margin-bottom: var(--stack-block);
}

.hero h1, .pagehead h1 {
  font-family: var(--font-ui);
  font-size: var(--fs-read-h1);
  font-weight: var(--fw-bold);
  line-height: 1.04;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: var(--space-7) 0 var(--space-9);
  max-width: 20ch;
  text-wrap: balance;
}

.hero-sub {
  font-family: var(--font-read);
  font-size: var(--fs-read-lead);
  line-height: 1.5;
  color: var(--text-secondary);
  max-width: 52ch;
  margin: 0;
}

.hero-meta { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-10); margin-top: var(--space-10); }

/* ---------- bands ---------- */

.band { padding: var(--stack-block) 0; }
.band > h2 { margin: 0 0 var(--space-9); }

.more { margin: var(--space-9) 0 0; }
.more a, .postnav a {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  text-decoration: none;
}
.more a:hover, .postnav a:hover { text-decoration: underline; }

/* ---------- work cards ---------- */

.workgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--gap-board); }

.workcard {
  background: var(--surface-raised);
  border: var(--bw) solid var(--border-default);
  padding: var(--pad-card);
  display: flex; flex-direction: column; gap: var(--space-5);
}
/* baseline, not center: a title that wraps to three lines would otherwise float
   the owl halfway down it. The sprite stands on the title's FIRST line. (This
   rule used to hold the status pill here too; the pill now lives in the tag row
   with the other chips, so only the sprite needs aligning.) */
.workcard header { display: flex; align-items: baseline; gap: var(--space-5); }
.workcard h3 { margin: 0; font-size: var(--fs-read-h3); font-weight: var(--fw-semibold); color: var(--text-primary); }
.workcard p { margin: 0; font-family: var(--font-read); font-size: var(--fs-read-sm); line-height: 1.55; color: var(--text-secondary); }

.pill {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  padding: 3px var(--space-3);
  border: var(--bw) solid var(--border-default);
  color: var(--text-tertiary);
  white-space: nowrap;
}
.pill.live    { color: var(--status-active); border-color: var(--accent-line); background: var(--accent-wash); }
.pill.build   { color: var(--cat-preference); }
.pill.shipped { color: var(--cat-health); }

.tags { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; padding: 0; }
/* :not(.pill) so the status chip keeps its own border and colour: the pill now
   shares this row, and a bare `.tags li` outranks `.pill` on specificity, which
   would have repainted every status the same neutral grey. */
.tags li:not(.pill) { border: var(--bw) solid var(--border-subtle); padding: 2px var(--space-3); }

/* ---------- post lists ---------- */

.postlist { list-style: none; margin: 0; padding: 0; }
.postlist li { border-top: var(--bw) solid var(--border-subtle); }
.postlist li:last-child { border-bottom: var(--bw) solid var(--border-subtle); }

.postlist a {
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr);
  gap: var(--space-3) var(--space-9);
  align-items: baseline;
  padding: var(--space-9) 0;
  text-decoration: none; color: inherit;
}
.postlist a:hover .postlink-t { color: var(--accent); }

.postlink-t { font-size: var(--fs-read-lead); font-weight: var(--fw-semibold); color: var(--text-primary); line-height: 1.3; }
.postlink-s { grid-column: 2; font-family: var(--font-read); font-size: var(--fs-read-sm); color: var(--text-tertiary); line-height: 1.5; max-width: 60ch; }

/* ---------- link list ---------- */

.linkgroups { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--gap-board); }
.linkgroup > h3 { margin: 0 0 var(--space-5); }
.linklist { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 2px; }
.extlink { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-7); background: var(--surface-sunken); border: var(--bw) solid var(--border-subtle); text-decoration: none; }
.extlink:hover { border-color: var(--accent-line); background: var(--accent-wash); }
.extlink-v { font-family: var(--font-mono); font-size: var(--fs-read-sm); color: var(--text-body); overflow-wrap: anywhere; }

/* ---------- post head ---------- */

.posthead {
  padding: var(--stack-section) 0 var(--stack-block);
  border-bottom: var(--bw) solid var(--border-subtle);
  margin-bottom: var(--stack-block);
}
.posthead h1 {
  font-family: var(--font-ui);
  font-size: var(--fs-read-h1);
  font-weight: var(--fw-bold);
  line-height: 1.06;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: var(--space-7) 0 var(--space-9);
  max-width: 22ch;
  text-wrap: balance;
}

.postnav { margin-top: var(--stack-block); padding-top: var(--space-9); border-top: var(--bw) solid var(--border-subtle); }

/* ---------- CV ---------- */

.cvsection { padding: var(--stack-block) 0; border-top: var(--bw) solid var(--border-subtle); }
.cvsection > h2 { margin: 0 0 var(--space-10); }

.role { display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); gap: var(--space-5) var(--space-10); padding-bottom: var(--stack-block); }
.role:last-child { padding-bottom: 0; }
.role .when { font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: var(--ls-wide); color: var(--text-tertiary); line-height: 1.5; }
.role h3 { margin: 0 0 var(--space-2); font-size: var(--fs-read-h3); font-weight: var(--fw-semibold); color: var(--text-primary); }
.role .where { font-family: var(--font-mono); font-size: var(--fs-caption); letter-spacing: var(--ls-wide); text-transform: uppercase; color: var(--accent); display: block; margin-bottom: var(--space-5); }
.role ul { margin: 0; padding-left: var(--space-9); font-family: var(--font-read); font-size: var(--fs-read-sm); line-height: 1.6; color: var(--text-secondary); }
.role li { margin-bottom: var(--space-3); }
.role li::marker { color: var(--text-ghost); }
.role > div > p { margin: 0 0 var(--space-5); font-family: var(--font-read); font-size: var(--fs-read-sm); color: var(--text-secondary); }

.skillgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 2px; }
.skillcard { background: var(--surface-sunken); border: var(--bw) solid var(--border-subtle); padding: var(--space-7); }
.skillcard h3 { margin: 0 0 var(--space-5); }
.skillcard ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.skillcard li { font-family: var(--font-mono); font-size: var(--fs-caption); letter-spacing: var(--ls-normal); color: var(--text-secondary); border: var(--bw) solid var(--border-subtle); padding: 3px var(--space-3); }

/* ---------- figures embedded in posts (data encodings) ---------- */

.sb-prose .figure { background: var(--surface-raised); border: var(--bw) solid var(--border-default); padding: var(--pad-read); margin: 0 0 var(--stack-para); max-width: 100%; }
.sb-prose .figure .fig-t,
.sb-prose .swatchlab .fig-t { font-family: var(--font-ui); font-size: var(--fs-read-sm); font-weight: var(--fw-semibold); color: var(--text-primary); margin: 0 0 var(--space-2); }
.sb-prose .figure .fig-s,
.sb-prose .swatchlab .fig-s { font-family: var(--font-ui); font-size: var(--fs-read-sm); color: var(--text-tertiary); margin: 0 0 var(--space-9); max-width: none; }
.sb-prose .figure .frow { display: grid; grid-template-columns: minmax(90px, 150px) 1fr 3rem; align-items: center; gap: var(--space-5); margin-bottom: var(--space-3); }
.sb-prose .figure .flbl { font-family: var(--font-ui); font-size: var(--fs-read-sm); line-height: 1.25; color: var(--text-secondary); }
.sb-prose .figure .flbl em { font-style: normal; display: block; font-family: var(--font-mono); font-size: var(--fs-caption); color: var(--text-ghost); letter-spacing: var(--ls-wide); }
.sb-prose .figure .ftrack { position: relative; height: 14px; background: var(--surface-track); }
.sb-prose .figure .fbar { position: absolute; inset: 0 auto 0 0; background: var(--data-neutral); opacity: .45; }
.sb-prose .figure .fbar.over { background: var(--data-warn); opacity: 1; }
.sb-prose .figure .fthresh { position: absolute; top: -4px; bottom: -4px; width: 2px; background: var(--data-pos); }
.sb-prose .figure .fval { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-read-sm); text-align: right; color: var(--text-body); }
.sb-prose .figure .fkey { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-9); margin-top: var(--space-7); padding-top: var(--space-5); border-top: var(--bw) solid var(--border-subtle); }
.sb-prose .figure .fkey span { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); font-size: var(--fs-caption); color: var(--text-ghost); letter-spacing: var(--ls-wide); }
.sb-prose .figure .fkey i { width: 12px; height: 7px; display: inline-block; }

/* ---------- narrow ---------- */

@media (max-width: 640px) {
  .postlist a { grid-template-columns: 1fr; gap: var(--space-3); }
  .postlist .postlink-s { grid-column: 1; }
  .role { grid-template-columns: 1fr; gap: var(--space-3); }
  .sb-prose .figure .frow { grid-template-columns: 1fr 3rem; }
  .sb-prose .figure .flbl { grid-column: 1 / -1; }
  .topbar { position: static; }
}

@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* Link cards: icon + label on one row, value beneath. */
.extlink-h { display: flex; align-items: center; gap: var(--space-3); color: var(--text-tertiary); }
.extlink:hover .extlink-h { color: var(--accent); }

/* "Load-bearing": not shipped, not merely live. Other people's work rests on
   it. Sky reads as structural next to amber (active) and jade (shipped),
   and stays clear of accent, which is reserved for interaction. */
.pill.bearing { color: var(--cat-biographical); border-color: var(--border-default); }


.hero > .sprite { margin-bottom: var(--space-5); }

/* ---------- sprite placements ----------
   Each placement has to justify itself: the sprite either does a job the page
   was already trying to do, or it does not go there.

   SIZING is a single --sprite-cell override; the generated rules derive the
   sheet width and the keyframe travel from it, so nothing here restates a frame
   count. Halving the 64px cell lands back on the art's native 32px, so the
   small ones stay pixel-exact.

   HOVER is carried by the parent (.sw-jump, .sw-run, .sw-hurt-death), never by
   the sprite: a 28px owl is a poor hover target, and the trigger belongs to the
   card or the hero it decorates, not to the decoration.

   OPTICAL OFFSETS. The art is bottom-anchored in its cell — roughly 22% empty
   above the character, none below, and 28% empty to its right. Centring the BOX
   therefore renders the character low and leaves a hole between it and whatever
   follows. The trims below are fractions of --sprite-cell, so they hold at any
   size, and they are transforms and negative margins rather than layout, so
   they move the picture without moving the box. */

/* Hero. The owl shares a ROW with the headline rather than sitting in the hero's
   own grid: the empty block beside a two-line headline is the space it is meant
   to occupy, and aligning it to the hero instead put it level with the subhead,
   a line it has nothing to do with. Sharing the row means it tracks the
   headline if the copy ever grows to three lines.

   The eyebrow and subhead stay full-width above and below, so the owl reads as
   set into the headline block, not as a third column running the hero's height.

   .sw-jump is on the SECTION, so the jump fires from anywhere in the hero —
   a 150px sprite is a fine hover target, but the hero is the thing being
   pointed at. The right trim closes the cell's dead margin (~28% of the cell
   sits empty to the character's right) so the owl aligns to the measure's right
   edge rather than to the edge of its transparent box. */
.headrow { display: flex; align-items: center; gap: var(--space-9); }
.headrow h1 { flex: 0 1 auto; }

/* Sized in em off the HEADLINE's own scale, not in pixels. --fs-read-h1 is
   clamp(2rem, 5vw, 3.1rem), so a two-line headline stands 2.08em tall and
   anything from 67px to 103px depending on viewport. A fixed 150px owl
   overflowed that block at both ends at every width. 2.1em tracks the headline
   through the whole clamp, so the sprite stays the height of the thing it sits
   beside instead of dictating the row.

   The lift centres the CHARACTER rather than its box: ~22% of the cell is empty
   above the head and none below, so a box centred on the headline renders the
   owl noticeably low. */
/* Both trims exist because the cell is not the character. Measured on the art:
   ~12% of the cell is empty to its left and ~28% to its right. Untrimmed, the
   owl would sit a visible step inside the page margin the headline aligns to,
   and the gap to the text would be `gap` PLUS a quarter-cell of nothing —
   which is what makes an untrimmed sprite look pasted on rather than set. */
.herofig { flex: none; font-size: var(--fs-read-h1); }
.herofig .sprite {
  --sprite-cell: 2.1em;
  margin-left: calc(var(--sprite-cell) * -0.125);
  margin-right: calc(var(--sprite-cell) * -0.25);
  transform: translateY(calc(var(--sprite-cell) * -0.11));
}

/* Work cards. One per header, standing on the title's baseline — the same
   alignment the status pill already uses, so a three-line title keeps all three
   elements on its first line. Idle at rest, running while the card is hovered. */
.workcard header .sprite { --sprite-cell: 26px; flex: none; }
.workcard header h3 { flex: 1 1 auto; }

/* End mark. Where a printer would set a fleuron: the article is over, and the
   back-link below is a choice rather than the only thing left on the page. */
.endmark { display: flex; justify-content: center; margin: var(--stack-section) 0 0; }
.endmark .sprite { --sprite-cell: 32px; }

/* 404 — the only screen reached by accident. The owl idles until you hover it,
   then takes the hit and dies once, holding the last frame. Looping that would
   turn an apology into a taunt. */
.notfound { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-10); align-items: center; padding: var(--stack-section) 0; }
.notfound-fig { display: flex; justify-content: center; }
.notfound-fig .sprite { --sprite-cell: 144px; }
.notfound h1 {
  font-family: var(--font-ui);
  font-size: var(--fs-read-h1);
  font-weight: var(--fw-bold);
  line-height: 1.04;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  margin: var(--space-7) 0 var(--space-9);
  max-width: 20ch;
  text-wrap: balance;
}
.notfound-nav { display: flex; flex-wrap: wrap; gap: var(--space-10); margin-top: var(--stack-block); font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: var(--ls-label); text-transform: uppercase; }
.notfound-nav a { color: var(--text-tertiary); text-decoration: none; border-bottom: var(--bw) solid var(--border-subtle); padding-bottom: var(--space-1); }
.notfound-nav a:hover { color: var(--accent); border-color: var(--accent-line); }

/* Narrow: the figure stops being a column and sits under the text, smaller. A
   176px owl beside a 30ch headline on a phone would own the screen. */
@media (max-width: 720px) {
  .headrow { flex-direction: column; align-items: flex-start; gap: var(--space-7); }
  .notfound { grid-template-columns: minmax(0, 1fr); }
  .notfound-fig { justify-content: flex-start; }
  /* No size override needed — the em sizing already follows --fs-read-h1 down
     its clamp. The left trim goes: stacked, the owl is the first thing on the
     line and a negative left margin would hang it outside the page margin. */
  .herofig .sprite { margin-left: 0; }
  .notfound-fig .sprite { --sprite-cell: 96px; }
}

/* Motif switch (SesebonUI card only). Two radios and :has() — no script,
   because the site sends script-src 'none' and this had to work without an
   exception to it. The state lives in the form control; CSS reads it.

   The winter token block and BOTH swatch colours are generated into the bundle
   from motifs/winter.css and tokens/colors.css, so nothing about the demo can
   drift from the motif it demonstrates. What lives here is only the control. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.motifdemo { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.motifswitch { display: flex; gap: var(--space-2); }
.motifswitch label {
  display: inline-flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-mono); font-size: var(--fs-micro);
  letter-spacing: var(--ls-micro); text-transform: uppercase;
  color: var(--text-tertiary);
  border: var(--bw) solid var(--border-subtle);
  padding: 2px var(--space-3);
  cursor: pointer;
}
.motifswitch label:hover { color: var(--accent); border-color: var(--accent-line); }
.swatch { width: 9px; height: 9px; flex: none; }

/* The selected chip. :has() again rather than `:checked + label`, so the rule
   states which control it depends on instead of relying on markup order. */
.motifswitch:has(#motif-obsidian:checked) label[for="motif-obsidian"],
.motifswitch:has(#motif-winter:checked) label[for="motif-winter"] {
  color: var(--text-primary);
  border-color: var(--accent-line);
  background: var(--accent-wash);
}

/* The radio is visually hidden but still focusable, so its focus ring has to be
   drawn on the label instead — otherwise the control is keyboard-operable with
   no indication of where you are. */
.motifswitch input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- the swatch lab (forty-seven-palettes) ----------
   A filterable before/after theme explorer with no runtime JavaScript.

   Two mechanisms carry it. Each card holds BOTH palettes as custom properties
   (--b* before, --a* shipped) and every painted rule reads a short indirection
   (--s, --p, --k …) rather than the pairs directly, so one :has() rule repoints
   the entire figure. Content that cannot be expressed as a colour — the ratio
   rails, the grade chips, the hex footers — is present twice and swapped by
   visibility, marked .vb and .va.

   The cards paint themselves with the audited values instead of describing
   them, which is the argument of the post: a contrast figure is easy to skim
   past, an unreadable caption is not. */

.sb-prose .swatchlab { background: var(--surface-chrome); border: var(--bw) solid var(--border-default); padding: var(--pad-read); margin: 0 0 var(--stack-para); max-width: 100%; }
.sb-prose .swatchlab .fig-s { margin-bottom: var(--space-7); }
.sb-prose .swatchlab .fig-s em { font-style: italic; color: var(--text-secondary); }

/* ---- controls ---- */
.swbar { display: flex; flex-wrap: wrap; gap: var(--space-5); align-items: center; justify-content: space-between; margin-bottom: var(--space-5); }
.swfilter, .swtoggle { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.swbar label {
  font-family: var(--font-mono); font-size: var(--fs-micro);
  letter-spacing: var(--ls-micro); text-transform: uppercase;
  color: var(--text-tertiary);
  border: var(--bw) solid var(--border-subtle);
  padding: 3px var(--space-5); cursor: pointer;
}
.swbar label:hover { color: var(--accent); border-color: var(--accent-line); }
.swatchlab:has(#f-all:checked)     label[for="f-all"],
.swatchlab:has(#f-bad:checked)     label[for="f-bad"],
.swatchlab:has(#f-mid:checked)     label[for="f-mid"],
.swatchlab:has(#f-ok:checked)      label[for="f-ok"],
.swatchlab:has(#sw-before:checked) label[for="sw-before"],
.swatchlab:has(#sw-after:checked)  label[for="sw-after"] {
  color: var(--text-primary); border-color: var(--accent-line); background: var(--accent-wash);
}
.swbar input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- the grid. Bounded and scrolled, so the whole set stays available
        without the figure running the length of the page. ---- */
.swgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--bw); background: var(--border-subtle);
  border: var(--bw) solid var(--border-subtle);
  max-height: 78vh; overflow-y: auto; overscroll-behavior: contain;
}

.swatchlab:has(#f-bad:checked) .swcard:not(.is-bad),
.swatchlab:has(#f-mid:checked) .swcard:not(.is-mid),
.swatchlab:has(#f-ok:checked)  .swcard:not(.is-ok) { display: none; }

/* ---- the indirection ---- */
.swcard {
  --s: var(--bs); --p: var(--bp); --y: var(--by); --n: var(--bn); --c: var(--bc);
  --g: var(--bg); --k: var(--bk); --i: var(--bi); --r: var(--br); --d: var(--bd);
  --t: var(--bt); --h: var(--bh); --b: var(--bb); --f: var(--bf); --e: var(--be);
  background: var(--surface-raised); display: flex; flex-direction: column;
}
.swatchlab:has(#sw-after:checked) .swcard {
  --s: var(--as); --p: var(--ap); --y: var(--ay); --n: var(--an); --c: var(--ac);
  --g: var(--ag); --k: var(--ak); --i: var(--ai); --r: var(--ar); --d: var(--ad);
  --t: var(--at); --h: var(--ah); --b: var(--ab); --f: var(--af); --e: var(--ae);
}

/* ---- before/after content swap. Each shown state names its own display,
        because these are spans, blocks and flex rows in turn. ---- */
.swcard .va { display: none; }
.swatchlab:has(#sw-after:checked) .swcard .vb { display: none; }
.swatchlab:has(#sw-after:checked) .swname .va { display: inline; }
.swatchlab:has(#sw-after:checked) .rail.va { display: block; }
.swatchlab:has(#sw-after:checked) .swfoot.va { display: flex; }

/* ---- card head ---- */
.swname { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin: 0 !important; padding: var(--space-3) var(--space-5); border-bottom: var(--bw) solid var(--border-subtle); font-family: var(--font-mono); font-size: var(--fs-caption); letter-spacing: var(--ls-wide); color: var(--text-secondary); }
.swatchlab .gd { font-family: var(--font-mono); font-size: var(--fs-micro); font-weight: var(--fw-semibold); letter-spacing: var(--ls-micro); padding: 1px var(--space-3); border: var(--bw) solid; white-space: nowrap; }
.swatchlab .gbad { color: var(--status-alert); border-color: var(--status-alert); background: var(--alert-wash); }
.swatchlab .gmid { color: var(--accent); border-color: var(--accent-line); background: var(--accent-wash); }
.swatchlab .gok  { color: var(--cat-health); border-color: var(--cat-health); }
.swatchlab .gref { color: var(--cat-biographical); border-color: var(--cat-biographical); }

/* ---- the specimen, painted in the audited theme ---- */
.swspec { background: var(--s); padding: var(--space-5); flex: 1; }
.swspec p { margin: 0 0 var(--space-3); max-width: none; }
.swtop { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }
.swtop i { font-style: normal; font-family: var(--font-mono); font-size: var(--fs-micro); letter-spacing: var(--ls-micro); text-transform: uppercase; }
.swlbl { color: var(--c); }
.swidle { color: var(--d); }
.swval { font-family: var(--font-mono); font-size: var(--fs-read-lg); font-weight: var(--fw-medium); line-height: 1; color: var(--p); }
.swval span { font-size: var(--fs-caption); font-weight: var(--fw-regular); margin-left: 2px; }
.swbody  { font-size: var(--fs-read-sm); line-height: 1.4; color: var(--y); }
.swsec   { font-size: var(--fs-caption); color: var(--n); }
.swcap   { font-size: var(--fs-caption); color: var(--c); }
.swghost { font-size: var(--fs-caption); color: var(--g); }
.swtrack { height: 5px; background: var(--t); position: relative; overflow: hidden; }
.swtrack b { position: absolute; inset: 0 38% 0 0; background: var(--k); }
.swrow { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-bottom: 0 !important; }
.swchip, .swalert { font-family: var(--font-mono); font-size: var(--fs-micro); letter-spacing: var(--ls-micro); text-transform: uppercase; padding: 2px var(--space-3); }
.swchip  { background: var(--k); color: var(--i); font-weight: var(--fw-semibold); }
.swalert { color: var(--r); border: var(--bw) solid var(--r); }
.swdot { width: 8px; height: 8px; flex: none; display: inline-block; }
.swdot.dh { background: var(--h); } .swdot.db { background: var(--b); }
.swdot.df { background: var(--f); } .swdot.de { background: var(--e); }

/* ---- the ratio rail ---- */
.swatchlab .rail { padding: var(--space-5); background: var(--surface-sunken); }
.swatchlab .rr { display: grid; grid-template-columns: 4.6rem 1fr 2.4rem; gap: var(--space-3); align-items: center; margin-bottom: 3px; }
.swatchlab .rr i { font-style: normal; }
.swatchlab .rk { font-family: var(--font-mono); font-size: var(--fs-micro); letter-spacing: var(--ls-micro); text-transform: uppercase; color: var(--text-ghost); }
.swatchlab .rt { height: 3px; background: var(--surface-track); position: relative; }
.swatchlab .rt b { position: absolute; left: 0; top: 0; bottom: 0; }
.swatchlab .rv { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-caption); text-align: right; }
.swatchlab .rv.ok { color: var(--cat-health); }
.swatchlab .rv.wn { color: var(--accent); }
.swatchlab .rv.no { color: var(--status-alert); }
.swatchlab .rt b.ok { background: var(--cat-health); }
.swatchlab .rt b.wn { background: var(--accent); }
.swatchlab .rt b.no { background: var(--status-alert); }

/* ---- card foot ---- */
.swfoot { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin: 0 !important; padding: var(--space-3) var(--space-5); border-top: var(--bw) solid var(--border-subtle); font-family: var(--font-mono); font-size: var(--fs-micro); letter-spacing: var(--ls-wide); color: var(--text-ghost); }
.swfoot b { font-weight: var(--fw-regular); white-space: nowrap; }
.swfoot b.ok { color: var(--cat-health); }
.swfoot b.no { color: var(--status-alert); }

@media (max-width: 640px) {
  .swgrid { grid-template-columns: 1fr; max-height: 70vh; }
  .swbar { gap: var(--space-3); }
}

/* ---- sprites (generated — see src/sprite/sprites.json) ---- */
:where(.sprite.idle) { --sprite-cell: 64px; }
.sprite.idle {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-idle.7a0e551c40d3.png);
          mask-image: url(/assets/sprite/owlet-idle.7a0e551c40d3.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-idle 1s steps(4) infinite;
}
@keyframes sb-sprite-idle {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.walk) { --sprite-cell: 64px; }
.sprite.walk {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-walk.58cf83542bf0.png);
          mask-image: url(/assets/sprite/owlet-walk.58cf83542bf0.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-walk 0.72s steps(6) infinite;
}
@keyframes sb-sprite-walk {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.run) { --sprite-cell: 64px; }
.sprite.run {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-run.7d4f44b790cb.png);
          mask-image: url(/assets/sprite/owlet-run.7d4f44b790cb.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-run 0.5s steps(6) infinite;
}
@keyframes sb-sprite-run {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.jump) { --sprite-cell: 64px; }
.sprite.jump {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-jump.4b8597992989.png);
          mask-image: url(/assets/sprite/owlet-jump.4b8597992989.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 8) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 8) var(--sprite-cell);
  animation: sb-sprite-jump 0.9s steps(8) infinite;
}
@keyframes sb-sprite-jump {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 8) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 8) * -1) 0; }
}
:where(.sprite.climb) { --sprite-cell: 64px; }
.sprite.climb {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-climb.0945c3156f59.png);
          mask-image: url(/assets/sprite/owlet-climb.0945c3156f59.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-climb 0.6s steps(4) infinite;
}
@keyframes sb-sprite-climb {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.push) { --sprite-cell: 64px; }
.sprite.push {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-push.ac60883c8860.png);
          mask-image: url(/assets/sprite/owlet-push.ac60883c8860.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-push 0.8s steps(6) infinite;
}
@keyframes sb-sprite-push {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.throw) { --sprite-cell: 64px; }
.sprite.throw {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-throw.ec48ea35929d.png);
          mask-image: url(/assets/sprite/owlet-throw.ec48ea35929d.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-throw 0.45s steps(4) infinite;
}
@keyframes sb-sprite-throw {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.attack) { --sprite-cell: 64px; }
.sprite.attack {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-attack.eae2a42415a7.png);
          mask-image: url(/assets/sprite/owlet-attack.eae2a42415a7.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-attack 0.4s steps(4) infinite;
}
@keyframes sb-sprite-attack {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.attack-two) { --sprite-cell: 64px; }
.sprite.attack-two {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-attack-two.7c9c80cdca24.png);
          mask-image: url(/assets/sprite/owlet-attack-two.7c9c80cdca24.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-attack-two 0.55s steps(6) infinite;
}
@keyframes sb-sprite-attack-two {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.walk-attack) { --sprite-cell: 64px; }
.sprite.walk-attack {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-walk-attack.a4599a53308c.png);
          mask-image: url(/assets/sprite/owlet-walk-attack.a4599a53308c.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-walk-attack 0.72s steps(6) infinite;
}
@keyframes sb-sprite-walk-attack {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.hurt) { --sprite-cell: 64px; }
.sprite.hurt {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-hurt.554c207a7c15.png);
          mask-image: url(/assets/sprite/owlet-hurt.554c207a7c15.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-hurt 0.5s steps(4) infinite;
}
@keyframes sb-sprite-hurt {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.death) { --sprite-cell: 64px; }
.sprite.death {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-death.26c34c689080.png);
          mask-image: url(/assets/sprite/owlet-death.26c34c689080.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 8) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 8) var(--sprite-cell);
  animation: sb-sprite-death 1.1s steps(8) infinite;
}
@keyframes sb-sprite-death {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 8) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 8) * -1) 0; }
}
:where(.sprite.dust-jump) { --sprite-cell: 64px; }
.sprite.dust-jump {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-dust-jump.0862dcecd56c.png);
          mask-image: url(/assets/sprite/owlet-dust-jump.0862dcecd56c.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 5) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 5) var(--sprite-cell);
  animation: sb-sprite-dust-jump 0.5s steps(5) infinite;
}
@keyframes sb-sprite-dust-jump {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 5) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 5) * -1) 0; }
}
:where(.sprite.dust-walk) { --sprite-cell: 64px; }
.sprite.dust-walk {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-dust-walk.86cfff0cbbf3.png);
          mask-image: url(/assets/sprite/owlet-dust-walk.86cfff0cbbf3.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-dust-walk 0.6s steps(6) infinite;
}
@keyframes sb-sprite-dust-walk {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.chest-open) { --sprite-cell: 64px; }
.sprite.chest-open {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-chest-open.c6797b3aff18.png);
          mask-image: url(/assets/sprite/owlet-chest-open.c6797b3aff18.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-chest-open 0.7s steps(6) infinite;
}
@keyframes sb-sprite-chest-open {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.hang) { --sprite-cell: 64px; }
.sprite.hang {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-hang.49dd7a193c99.png);
          mask-image: url(/assets/sprite/owlet-hang.49dd7a193c99.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-hang 0.8s steps(4) infinite;
}
@keyframes sb-sprite-hang {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.happy) { --sprite-cell: 64px; }
.sprite.happy {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-happy.be82f28cf657.png);
          mask-image: url(/assets/sprite/owlet-happy.be82f28cf657.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-happy 0.6s steps(6) infinite;
}
@keyframes sb-sprite-happy {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.idle-two) { --sprite-cell: 64px; }
.sprite.idle-two {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-idle-two.6c2869fa901a.png);
          mask-image: url(/assets/sprite/owlet-idle-two.6c2869fa901a.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-idle-two 1s steps(4) infinite;
}
@keyframes sb-sprite-idle-two {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.lift) { --sprite-cell: 64px; }
.sprite.lift {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-lift.105ba67f58b8.png);
          mask-image: url(/assets/sprite/owlet-lift.105ba67f58b8.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-lift 0.8s steps(6) infinite;
}
@keyframes sb-sprite-lift {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.pull-up) { --sprite-cell: 128px; }
.sprite.pull-up {
  --sprite-aspect: 0.5;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-pull-up.852160f52fb8.png);
          mask-image: url(/assets/sprite/owlet-pull-up.852160f52fb8.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-pull-up 0.9s steps(6) infinite;
}
@keyframes sb-sprite-pull-up {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.repulsion) { --sprite-cell: 64px; }
.sprite.repulsion {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-repulsion.bc74eeef0551.png);
          mask-image: url(/assets/sprite/owlet-repulsion.bc74eeef0551.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-repulsion 0.6s steps(6) infinite;
}
@keyframes sb-sprite-repulsion {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.roll) { --sprite-cell: 64px; }
.sprite.roll {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-roll.7262fb29b185.png);
          mask-image: url(/assets/sprite/owlet-roll.7262fb29b185.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-roll 0.5s steps(6) infinite;
}
@keyframes sb-sprite-roll {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.slide) { --sprite-cell: 64px; }
.sprite.slide {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-slide.5db6f1c8f484.png);
          mask-image: url(/assets/sprite/owlet-slide.5db6f1c8f484.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-slide 0.5s steps(4) infinite;
}
@keyframes sb-sprite-slide {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.squat) { --sprite-cell: 64px; }
.sprite.squat {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-squat.ed375c884d69.png);
          mask-image: url(/assets/sprite/owlet-squat.ed375c884d69.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 4) var(--sprite-cell);
  animation: sb-sprite-squat 0.7s steps(4) infinite;
}
@keyframes sb-sprite-squat {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 4) * -1) 0; }
}
:where(.sprite.throw-two) { --sprite-cell: 64px; }
.sprite.throw-two {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-throw-two.8761fd1e7292.png);
          mask-image: url(/assets/sprite/owlet-throw-two.8761fd1e7292.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-throw-two 0.55s steps(6) infinite;
}
@keyframes sb-sprite-throw-two {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.walk-two) { --sprite-cell: 64px; }
.sprite.walk-two {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-walk-two.1600f5e4d9fe.png);
          mask-image: url(/assets/sprite/owlet-walk-two.1600f5e4d9fe.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-walk-two 0.72s steps(6) infinite;
}
@keyframes sb-sprite-walk-two {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 6) * -1) 0; }
}
:where(.sprite.hurt-death) { --sprite-cell: 64px; }
.sprite.hurt-death {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-hurt-death.9fa571d65aa1.png);
          mask-image: url(/assets/sprite/owlet-hurt-death.9fa571d65aa1.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 12) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 12) var(--sprite-cell);
  animation: sb-sprite-hurt-death 1.6s steps(12) infinite;
}
@keyframes sb-sprite-hurt-death {
  to { -webkit-mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 12) * -1) 0; mask-position: calc(calc(var(--sprite-cell) * var(--sprite-aspect) * 12) * -1) 0; }
}
:where(.sprite.rock-small) { --sprite-cell: 16px; }
.sprite.rock-small {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-rock-small.7bb6540bfe82.png);
          mask-image: url(/assets/sprite/owlet-rock-small.7bb6540bfe82.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 1) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 1) var(--sprite-cell);
}
:where(.sprite.rock-large) { --sprite-cell: 32px; }
.sprite.rock-large {
  --sprite-aspect: 1;
  width: calc(var(--sprite-cell) * var(--sprite-aspect));
  height: var(--sprite-cell);
  -webkit-mask-image: url(/assets/sprite/owlet-rock-large.598ea060da1b.png);
          mask-image: url(/assets/sprite/owlet-rock-large.598ea060da1b.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 1) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 1) var(--sprite-cell);
}
.sw-jump:hover .sprite,
.sw-jump:focus-within .sprite {
  --sprite-aspect: 1;
  -webkit-mask-image: url(/assets/sprite/owlet-jump.4b8597992989.png);
          mask-image: url(/assets/sprite/owlet-jump.4b8597992989.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 8) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 8) var(--sprite-cell);
  animation: sb-sprite-jump 0.9s steps(8) infinite;
}
.sw-run:hover .sprite,
.sw-run:focus-within .sprite {
  --sprite-aspect: 1;
  -webkit-mask-image: url(/assets/sprite/owlet-run.7d4f44b790cb.png);
          mask-image: url(/assets/sprite/owlet-run.7d4f44b790cb.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 6) var(--sprite-cell);
  animation: sb-sprite-run 0.5s steps(6) infinite;
}
.sw-hurt-death:hover .sprite,
.sw-hurt-death:focus-within .sprite {
  --sprite-aspect: 1;
  -webkit-mask-image: url(/assets/sprite/owlet-hurt-death.9fa571d65aa1.png);
          mask-image: url(/assets/sprite/owlet-hurt-death.9fa571d65aa1.png);
  -webkit-mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 12) var(--sprite-cell);
          mask-size: calc(var(--sprite-cell) * var(--sprite-aspect) * 12) var(--sprite-cell);
  animation: sb-sprite-hurt-death 1.6s steps(12) 1 forwards;
}
.sprite.once {
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
}

/* ---- motif demo (generated — see motifs/winter.css) ---- */
/* Lifted verbatim from motifs/winter.css at build time. */
.workcard:has(#motif-winter:checked) {
  /* Cool-shifted surfaces */
  --surface-base:    #04070b;
  --surface-raised:  #0a0f15;
  --surface-sunken:  #070b10;
  --surface-chrome:  #05080c;
  --border-default:  #16202b;
  --border-subtle:   #101822;

  /* Frost accent replaces amber */
  --accent:          #8FD3FF;
  --accent-ink:      #04141f;
  --accent-wash:     rgba(143,211,255,.08);
  --accent-line:     rgba(143,211,255,.20);

  /* Status roles that ALSO read accent shift with it… */
  --status-active:   #8FD3FF;
  /* …but the alert role stays its invariant red. (Intentionally absent.) */

  /* Decoration hooks — host reads these to mount ambient layers */
  --motif-ambient:   rgba(143,211,255,.06);
}
.swatch.obsidian { background: #FFB000; }
.swatch.winter { background: #8FD3FF; }
