/* =======================================================================
   Generated by shadow-mode/build-styles.mjs
   Source of truth: shadow-mode/styles-src/*.css
   Do not edit generated CSS in shadow-mode/*.css directly.
   ======================================================================= */
/* >>> 00-foundation-shell.css >>> */
@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Sora:wght@600;700&display=swap");

@view-transition {
  navigation: auto;
}

/* Phase C.1 — design-system tokens lifted to global. The values
   that previously lived under body[data-page="design-system"] are
   now the project-wide defaults. To re-tone the entire product,
   change a single token in this :root block (or the dark override
   below) and every page picks it up. /design-system stops being
   an island and becomes the live render of the shipping tokens. */
:root {
  /* ── Surface ladder — cool-near-white canvas under a Sui-blue
        sky. Light is the default; dark overrides below. */
  --bg:               #F4F7FB;
  --bg-strong:        #ECF1F8;
  --surface:          #FFFFFF;
  --surface-strong:   #FFFFFF;
  --surface-soft:     #F4F7FB;
  --surface-tint:     #E9EFF8;
  --surface-emphasis: #DCE6F4;
  --text:             #0d1a30;
  --text-strong:      #081528;
  --muted:            #5C6E84;
  --muted-strong:     #3E5168;

  /* Hairlines as low-alpha cobalt — inherit page warmth without
     looking inked-on. */
  --line:        rgba(28, 96, 207, 0.10);
  --line-strong: rgba(28, 96, 207, 0.18);

  /* ── Tone palette — brand cobalt + teal anchors plus the
        bright secondary tones the user picked. AAA companions
        below for tone-on-canvas text on the cool-white surface. */
  --accent:        #1C60CF;
  --accent-strong: #1747A0;
  --accent-soft:   rgba(28, 96, 207, 0.08);
  --cyan:          #0E8A85;   /* 5.4:1 on white (was #14B8B0 — 2.58:1) */
  --cyan-soft:     rgba(14, 138, 133, 0.08);
  --mint:          #27F5B7;   /* user pick — bright cyan-leaning mint */
  --mint-soft:     rgba(39, 245, 183, 0.12);
  --amber:         #FCFB00;   /* user pick — pure yellow, electric */
  --amber-soft:    rgba(252, 251, 0, 0.14);
  --rose:          #FF1934;   /* user pick — pure red */
  --rose-soft:     rgba(255, 25, 52, 0.12);
  --violet:        #7C3AED;
  --violet-soft:   rgba(124, 58, 237, 0.08);

  /* ── Tone-text companions — darker variants to use as TEXT
        colour on the cool-white canvas where the bright values
        fail AA. Component CSS that paints tone text on canvas
        should reference --tone-text-* instead of --tone-*. */
  --mint-text:     #047857;
  --amber-text:    #8A6F00;
  --rose-text:     #C2001A;
  --cyan-text:     #0E8A85;
  --violet-text:   #5B21B6;

  /* ── Sidebar tokens (legacy /workspace shell) */
  --sidebar-bg: #edf1f8;
  --sidebar-line: rgba(10, 24, 48, 0.08);
  --sidebar-text: #5c6e84;
  --sidebar-heading: #0d1a30;
  --sidebar-sub: #5c6e84;
  --sidebar-hover: rgba(10, 24, 48, 0.05);
  --sidebar-active-bg: rgba(28, 96, 207, 0.08);
  --sidebar-active-text: #0d1a30;

  /* ── Shadows tuned for cool-white canvas. */
  --shadow-sm: 0 4px 16px rgba(15, 32, 64, 0.04);
  --shadow-md: 0 12px 32px rgba(15, 32, 64, 0.08), 0 1px 0 rgba(255, 255, 255, 0.6);
  --shadow-lg: 0 24px 64px rgba(15, 32, 64, 0.10), 0 1px 0 rgba(255, 255, 255, 0.6);

  /* ── Radius — bumped per design-system playground (lifted). */
  --radius-xl: 28px;
  --radius-lg: 22px;
  --radius-md: 18px;
  --radius-sm: 12px;
  --radius-xs: 10px;
  --radius-pill: 4px;

  /* ── Motion durations — explicit caps for interactive polish. */
  --motion-fast: 120ms;
  --motion-base: 150ms;
  --motion-slow: 240ms;
  /* Phase D.2 — token for genuine pill / full-round shapes (slider tracks,
     fills, thumbs, chips). Hardcoded 999px values across the project
     drifted from the token system; this brings them under discipline. */
  --radius-full: 999px;

  /* ── Type scale — wider gap between heaviest and lightest tier. */
  --fs-2xs:    0.6rem;
  --fs-xs:     0.68rem;
  --fs-sm:     0.78rem;
  --fs-base:   0.86rem;
  --fs-md:     1rem;
  --fs-lg:     1.2rem;
  --fs-xl:     1.5rem;
  --fs-display: clamp(2.4rem, 4.6vw, 3.4rem);

  /* Phase D.32 — runtime-set count default. The renderer overrides
     this inline (`style="--scenario-count: ${N}"`) so the
     .scenario-grid + .stress-spark count match. Default 6 covers
     the canonical stress ladder (current + 5 stress scenarios). */
  --scenario-count: 6;

  /* --accent-dim, --mint-bright, --cyan-bright, --amber-bright dropped
     per tokens audit §10 — zero call-sites across the codebase. */
  /* C.7 — formerly-ghost token aliases. The names below were used
     across the codebase but never defined in :root, silently falling
     back to browser defaults (serif fonts, no colour). Aliasing them
     to the canonical tokens fixes ~16 components in one pass.
     Phase D.29.5 closed the alias debt: --warning / --warn /
     --text-muted / --text-soft / --tide-text / --tide-text-soft /
     --tide-link / --color-* aliases were rewritten to their
     canonical token names at every callsite, then their alias
     definitions deleted. The remaining --font-mono / --ff* alias
     here is still load-bearing — emitted in legacy template strings
     that are not yet on the canonical font stack. */
  --font-mono:         var(--ff-mono);
  --ff:                "Manrope", "Segoe UI", system-ui, -apple-system, sans-serif;
  --ff-mono:           ui-monospace, SFMono-Regular, Menlo, monospace;
  --ff-display:        "Sora", "Manrope", system-ui, -apple-system, sans-serif;
  /* On-bright-tone text — fixed dark navy that reads on bright
     mint / cyan / amber fills in BOTH themes (e.g. .ws-step-num
     cyan circle, .status-timeline__step--done mint dot icon). */
  --on-tone-text-dark: #07172d;
  --tooltip-bg: #0a1730;
  --tooltip-text: #f8fbff;
  --on-accent-text: #ffffff;
  --range-track: #d8e0ee;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --row-h: 40px;
  --row-h-dense: 32px;
  --strip-h: 56px;
  --elev-0: none;
  --elev-1: 0 1px 0 var(--line);
  --border-soft: 1px solid var(--line);
  --border-strong: 1px solid var(--line-strong);
}

.metric strong, [data-tabular] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

html[data-theme="dark"] {
  /* ── Surface ladder — true near-black canvas + clearer surface
        contrast. Restores the soft → surface → strong order. */
  --bg:               #06060a;
  --bg-strong:        #0a0a10;
  --surface:          #13131c;
  --surface-strong:   #1a1a26;
  --surface-soft:     #0e0e16;
  --surface-tint:     #1c1c28;
  --surface-emphasis: #22222e;
  --text:             #d0d4e0;
  --text-strong:      #f0f2f8;
  --muted:            #7a8298;
  --muted-strong:     #9aa3b6;

  /* Hairlines as alpha-on-white so they inherit the surface tint
     underneath instead of looking pasted on. R7 audit: 0.04 was
     invisible against --surface #13131c on consumer pages where
     surfaces don't carry a brighter card tint to fall back on.
     Bumped to 0.07 / 0.12 so card separation reads. */
  --line:        rgba(255, 255, 255, 0.07);
  --line-strong: rgba(255, 255, 255, 0.12);

  /* ── Tone palette — Momentum-cool anchors. The two brand colours
        (cobalt + teal) are exact; the secondary tones are the user's
        bright picks so nothing reads warm/muddy on near-black canvas. */
  --accent:        #2E7BFF;
  --accent-strong: #1C60CF;
  --accent-soft:   rgba(46, 123, 255, 0.10);
  --cyan:          #2CDFDB;
  --cyan-soft:     rgba(44, 223, 219, 0.10);
  --mint:          #27F5B7;
  --mint-soft:     rgba(39, 245, 183, 0.12);
  --amber:         #FCFB00;
  --amber-soft:    rgba(252, 251, 0, 0.12);
  --rose:          #FF1934;
  --rose-soft:     rgba(255, 25, 52, 0.12);
  --violet:        #A78BFA;
  --violet-soft:   rgba(167, 139, 250, 0.10);

  /* Tone-text companions — on dark canvas the bright values pass
     contrast directly, so the *-text variants alias back to the
     bright ones. Rules that paint tone-on-canvas text reference
     --tone-text-* uniformly across themes. */
  --mint-text:   var(--mint);
  --amber-text:  var(--amber);
  --rose-text:   var(--rose);
  --cyan-text:   var(--cyan);
  --violet-text: var(--violet);

  /* ── Sidebar tokens. */
  --sidebar-bg: #0c0c14;
  --sidebar-line: rgba(255, 255, 255, 0.06);
  --sidebar-text: rgba(255, 255, 255, 0.6);
  --sidebar-heading: rgba(255, 255, 255, 0.85);
  --sidebar-sub: rgba(255, 255, 255, 0.55);
  --sidebar-hover: rgba(255, 255, 255, 0.05);
  --sidebar-active-bg: rgba(46, 123, 255, 0.08);
  --sidebar-active-text: #fff;

  /* ── Shadows — tighter dark-theme shadow with a 1 px highlight rim.
        Reserved for popovers / modals. */
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 12px 32px rgba(0, 0, 0, 0.6), 0 1px 0 rgba(255, 255, 255, 0.04);
  --shadow-lg: 0 24px 64px rgba(0, 0, 0, 0.65), 0 1px 0 rgba(255, 255, 255, 0.04);

  --range-track: #1e2538;
  --tooltip-bg: #1a2a48;
  --tooltip-text: #f0f4ff;
}

/* Phase C.1 — design-system tokens (radius/type/colour) lifted to
   :root + html[data-theme="dark"]. The body[data-page="design-system"]
   token override block is removed; non-token rules below stay so the
   playground keeps its specific layout / chrome (page-header card,
   eyebrow chip, hero, ds-toc, etc). */

/* Tabular numerics + slashed zero on every primitive that renders a
   number — operators scan columns of figures and can't tolerate a 0/O
   ambiguity or a digit-width jump on stepper edits. Per data-density +
   debug + customer reviewers. */
body[data-page="design-system"] .composer__amount,
body[data-page="design-system"] .composer__usd,
body[data-page="design-system"] .balance-pill__amount,
body[data-page="design-system"] .hash-pill__value,
body[data-page="design-system"] .token-amount-row__amount,
body[data-page="design-system"] .tx-receipt-card__amount,
body[data-page="design-system"] .tx-receipt-card__usd,
body[data-page="design-system"] .delta-chip,
body[data-page="design-system"] .meta-line__value,
body[data-page="design-system"] .meta-line__time,
body[data-page="design-system"] .crypto-pill,
body[data-page="design-system"] .crypto-pill strong,
body[data-page="design-system"] .stepper-input input[type="number"],
.ds-hero__amount,
.ds-hero__meta dd {
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: "tnum" 1, "zero" 1;
}

/* B.16.1 — .tx-receipt-card__amount lives on a primitive demo card,
   not the page-level hero. Globally it inherits var(--fs-display)
   from the receipt card's own rule (~line 4198) — same tier as
   .ds-hero__amount. User feedback 2026-04-26: "здоровые цифры,
   чуть поменьше бы". Drop one tier on /design-system only so the
   receipt card reads as secondary to the hero number while still
   being the strongest line on the card itself. Global rule stays
   untouched; readout/live pages still render at the larger tier. */
body[data-page="design-system"] .tx-receipt-card__amount {
  font-size: clamp(1.7rem, 2.8vw, 2.2rem);
}

/* ─── Hero — anchor display number + spark + meta strip ─── */
/* Phase D.11 — .ds-hero now COMPOSES canonical .surface-hero (markup
   is `class="surface surface-hero ds-hero"`). The 3px accent left
   edge, border, radius come from .surface-hero. This block only
   carries playground-specific overrides: flex-column layout for
   head/body/meta stacking, the asymmetric internal gap, and the
   decorative cyan radial that anchors the showcase to the brand
   water/tide metaphor. Demonstrates that consumer pages compose
   canonical primitives + bespoke overrides correctly. */
.ds-hero {
  display: flex;
  flex-direction: column;
  /* P7 fourth-pass — head→body 1.1rem; body→meta 1.65rem total
     (1.1rem flex gap + 0.55rem meta padding-top). Asymmetric on
     purpose so the dashed border at top of meta reads as a
     supporting-strip introducer rather than slicing equal space. */
  gap: 1.1rem;
  padding: 1.4rem 1.55rem;
  /* A+2 fourth-pass — single decorative cyan radial gradient at low
     opacity in the right corner. Cyan = "live data" per the tone
     manifesto; the spark already references the cyan-leaning mint.
     Anchors hero-as-protagonist to the brand water/tide metaphor
     without adding chrome. Static, no animation. */
  background-image: radial-gradient(
    circle at 88% 60%,
    color-mix(in srgb, var(--cyan) 9%, transparent) 0%,
    transparent 55%
  );
  background-size: 60% 100%;
  background-position: right center;
  background-repeat: no-repeat;
}
.ds-hero__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.85rem;
}
.ds-hero__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.2rem;
  align-items: center;
}
.ds-hero__amount {
  font-family: "Sora", "Manrope", system-ui, sans-serif;
  font-size: var(--fs-display);
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--text-strong);
  line-height: 1;
}
.ds-hero__amount-decimals {
  color: var(--muted);
  font-size: 0.55em;
  font-weight: 600;
}
.ds-hero__sub {
  margin-top: 0.5rem;
  display: flex;
  gap: 0.5rem;
  align-items: center;
  font-size: var(--fs-xs);
}
/* Phase D.2 — was inline style="color:var(--mint-text);font-family:
   var(--ff-mono);font-weight:700" / inline style="color:var(--muted);
   font-family:var(--ff-mono)" on the two hero sub-spans. Now class-
   based so the hero stops contradicting the no-inline-styles rule. */
.ds-hero__sub-delta {
  color: var(--mint-text);
  font-family: var(--ff-mono);
  font-weight: 700;
}
.ds-hero__sub-meta {
  color: var(--muted);
  font-family: var(--ff-mono);
}
.ds-hero__chart {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  color: var(--mint);
}
/* Hero sparkline override — global .spark-inline clamps to 48x12 px;
   inside the hero we want it to actually anchor the right side of the
   amount row. User feedback 2026-04-26: "this small green chart is
   hard to even notice — either drop it or make it bigger". Bump to
   roughly the same width as the amount column on desktop, with a
   thicker stroke so the curve reads at a glance. Mobile rules below
   already collapse it to width:100% inside a grid cell. */
.ds-hero__chart .spark-inline {
  width: 280px;
  height: 64px;
}
.ds-hero__chart .spark-inline svg path {
  stroke-width: 2.25;
}
.ds-hero__meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.55rem 1.2rem;
  /* P7 fourth-pass — was 0.95rem; tightened so the dashed border
     reads as a supporting-strip divider (asymmetric vs head→body
     gap of 1.1rem). */
  padding-top: 0.55rem;
  border-top: 1px dashed var(--line);
  margin: 0;
}
.ds-hero__meta dt {
  font-size: var(--fs-2xs);
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: 0.2rem;
  font-family: var(--ff-mono);
}
.ds-hero__meta dd {
  margin: 0;
  font-family: var(--ff-mono);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
}
.ds-hero__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

/* Mobile floor — 480 px breakpoint covers iPhone SE (375) through
   iPhone Pro Max (430). Per mobile reviewer's [BLOCKING-MOBILE]:
   composer collapses, touch-targets reach ≥36 px, modal honors
   95vw, pagination drops non-essential cells. Scope-fenced to
   /design-system; consumer pages stay on their existing rules. */
@media (max-width: 480px) {
  .ds-hero {
    padding: 1.1rem 1.1rem;
  }
  .ds-hero__head {
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  .ds-hero__body {
    grid-template-columns: 1fr;
    gap: 0.65rem;
  }
  .ds-hero__chart {
    overflow: hidden;
    width: 100%;
  }
  .ds-hero__chart .spark-inline {
    width: 100%;
  }

  /* Composer: single-column on mobile so the numeric input gets
     real width. select-trigger drops below input. */
  body[data-page="design-system"] .composer__row {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }
  body[data-page="design-system"] .composer__row .select-trigger {
    grid-column: 1 / -1;
    justify-content: space-between;
  }
  body[data-page="design-system"] .composer__usd {
    grid-column: 1 / -1;
  }

  /* Modal: 95vw fallback so it doesn't overflow the viewport. */
  body[data-page="design-system"] .modal {
    max-width: 95vw;
    width: 95vw;
  }

  /* Toast: drop the 240 px min so tiny copies don't blow out. */
  body[data-page="design-system"] .toast {
    min-width: 0;
    max-width: none;
    width: 100%;
  }
  body[data-page="design-system"] .toast-region--demo {
    width: 100%;
  }

  /* Touch targets ≥36 px (WCAG AA Touch 24 + ergonomic margin) on
     icon-only controls that previously fell to 20-32 px. */
  body[data-page="design-system"] .toast__close,
  body[data-page="design-system"] .hash-pill__btn,
  body[data-page="design-system"] .stepper-input__btn,
  body[data-page="design-system"] .pagination__btn,
  body[data-page="design-system"] .composer__divider button,
  body[data-page="design-system"] .tabs__option {
    min-width: 36px;
    min-height: 36px;
  }
  body[data-page="design-system"] .pagination__btn {
    width: 36px;
    height: 36px;
  }

  /* Pagination collapse: hide non-essential cells so we read as
     "‹ 2 ›" — current page + arrows only. The full pagination
     stays available via tab/keyboard for desktop users. */
  body[data-page="design-system"] .pagination > .pagination__btn:not([aria-current]):not([aria-label*="Previous"]):not([aria-label*="Next"]),
  body[data-page="design-system"] .pagination__ellipsis {
    display: none;
  }

  /* Hero amount clamp tightens on tiny viewports so it doesn't
     blow past the card edge. */
  .ds-hero__amount {
    font-size: clamp(1.85rem, 8vw, 2.4rem);
  }

  /* Tabs need horizontal scroll affordance on mobile rather than
     wrapping. Keep .tabs__option from squishing. */
  body[data-page="design-system"] .tabs {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
  }
  body[data-page="design-system"] .tabs__option {
    scroll-snap-align: start;
  }
}

/* Phase C.1 — old html[data-theme="dark"] body[data-page="design-system"]
   and html[data-theme="light"] body[data-page="design-system"] token
   blocks were lifted to the global :root + html[data-theme="dark"]
   blocks above. /design-system inherits everything; non-token playground
   rules below remain. */

/* Phase D.5 — playground h1 inflation removed. The clamp(1.3rem,
   1.6vw, 1.6rem) override was 8–33% larger than production h1
   clamp(1rem, 1.15vw, 1.2rem), so operators evaluating the DS saw
   inflated type that didn't match what shipped. /design-system now
   uses the global h1 rule like every other page. */

/* Page header — wrapped in surface chrome on /design-system per
   UI 4th-pass T3 + UX #1: bare canvas read as "default browser
   layout, not the design system itself". Card frame anchors the
   eyebrow + H1 + copy as a deliberate top-zone surface. Inner
   padding mirrors .ds-hero. Single brand cue is the cobalt→teal
   hairline at the card foot — left-edge accent intentionally
   skipped (would duplicate .ds-hero / .surface-hero pattern). */
/* Page-header surface chrome — was scoped to /design-system, now
   global per Phase C migration so every consumer page wraps its
   page-header in the same surface frame. Layout is a flex 2-col
   on consumer pages (heading left, page-tools right); /design-system
   has only a heading and reads as single-column. */
.page-header {
  --page-header-x: 1.55rem;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  /* Phase D.28 — was 1.4rem 1.55rem 0.9rem; the asymmetric bottom
     made the page-copy text crowd against the card foot ("текст
     прилипает к низу" — user, viewing /design-system). Symmetric
     1.4rem top/bottom matches the card-foot rhythm; the
     cobalt→teal hairline ::after sits with margin-top 0.7rem and
     reads as a proper underline rather than a divider stuck to text. */
  padding: 1.4rem var(--page-header-x);
  margin-bottom: 1.1rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  /* Phase D.11 — was box-shadow: var(--shadow-md). DS rule §1.6:
     shadows go on TRANSIENT elements only (popovers / modals).
     A static page anchor card with --shadow-md made the header
     float above flat content stack on every consumer page,
     creating a "single floating card on top of disconnected
     stack" feeling — the exact "DS pieces glued on" complaint
     the user raised. The 1px var(--line-strong) border + cobalt
     hairline ::after now carry the frame weight without lifting. */
}

/* Page eyebrow — chip-style. Was scoped to /design-system; lifted
   to global per UX-L7 so /library + every consumer page uses the
   same chip pattern (accent-soft fill, pill radius, accent border,
   Manrope). */
.page-eyebrow {
  display: inline-flex;
  align-items: center;
  /* .page-heading is `display: grid` — grid children stretch
     by default, which makes `inline-flex` paint full-width.
     `justify-self: start` shrinkwraps the chip back to its
     content (also a no-op in non-grid contexts). */
  justify-self: start;
  width: fit-content;
  max-width: 100%;
  margin: 0 0 0.6rem;
  padding: 0.18rem 0.65rem;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--radius-full);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

/* Brand moment — cobalt → teal hairline at the card foot per
   brand-keeper §38 + UI 4th-pass T2 (raw hex → tokens, so theme
   shifts propagate). Uses the canonical brand anchors via the
   /design-system token block (light --accent #1C60CF + --cyan
   #2CDFDB; dark --accent #2E7BFF + --cyan #2CDFDB — both within
   the brand cobalt/teal family). */
/* Brand hairline — now global per Phase C so the cobalt → teal
   handshake reads on every page-header card. */
.page-header::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 0.7rem;
  background: linear-gradient(90deg, var(--accent) 0%, var(--cyan) 100%);
  border-radius: var(--radius-full);
}
/* Light theme reads 2 px too quietly on cool-white canvas; 3 px brings
   it back to brand presence. */
html[data-theme="light"] .page-header::after {
  height: 3px;
}

/* Page-copy on /design-system — keep the global 62ch ceiling but pin
   the inline link to a calmer accent state (the global .page-copy a
   inherits link colour without underline, on a dark canvas the link
   blends into body text). */
body[data-page="design-system"] .page-copy a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
body[data-page="design-system"] .page-copy a:hover {
  text-decoration-thickness: 2px;
}

/* Tone-semantics manifesto — the strongest TIDE line on the page
   was buried in the anti-pattern footer. Hoist into Foundations
   beneath the swatch grid via a .ds-tone-manifesto block. */
body[data-page="design-system"] .ds-tone-manifesto {
  margin-top: 1rem;
  padding: 0.7rem 0.95rem;
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--text-strong);
}
body[data-page="design-system"] .ds-tone-manifesto strong {
  font-weight: 700;
}
body[data-page="design-system"] .ds-tone-manifesto em {
  font-style: normal;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  margin-left: 0.25rem;
}

/* Aspirational marker — primitives demoed in /design-system that
   don't yet have a consumer surface.
   Two forms by element type:
     - Buttons + chips with limited surface: compact ✻ glyph next to
       the label; full text via the existing title attribute.
     - Standalone surfaces (banners, modals, sections) with room for
       sublabel: full "(planned · no consumer yet)" line below.
   Previously a single ::after rule painted long uppercase text INLINE
   on the cobalt button face — unreadable. The button case is now
   compact-glyph only. */
body[data-page="design-system"] .button[data-aspirational="true"]::after,
body[data-page="design-system"] .icon-badge[data-aspirational="true"]::after,
body[data-page="design-system"] .network-badge[data-aspirational="true"]::after {
  content: "✻";
  display: inline;
  margin-left: 0.4em;
  font-size: 0.75em;
  font-weight: 700;
  color: currentColor;
  opacity: 0.7;
  vertical-align: middle;
}
body[data-page="design-system"] .button.button-primary[data-aspirational="true"]::after {
  /* Cobalt button: glyph stays white-ish so it remains visible. */
  color: color-mix(in srgb, var(--surface) 85%, transparent);
  opacity: 1;
}
/* P11 fourth-pass + third-pass C13 — light dashed outline so a
   scrolling designer pre-attentively spots aspirational primitives
   before reading the title. Outlines aren't animated, so no
   reduced-motion gate needed. */
body[data-page="design-system"] [data-aspirational="true"] {
  outline: 1px dashed var(--muted);
  outline-offset: 4px;
  border-radius: var(--radius-xs);
}

/* Print baseline — receipts + policy summaries get printed by
   compliance auditors. Per print reviewer §1: hide nav, hide TOC,
   force solid backgrounds, preserve hash content. Scoped to
   /design-system; consumer pages get their own print blocks
   later. */
@media print {
  body[data-page="design-system"] .app-topbar,
  body[data-page="design-system"] .ds-toc,
  body[data-page="design-system"] .skip-link,
  body[data-page="design-system"] .ds-snippet,
  body[data-page="design-system"] .ds-section__anchor {
    display: none !important;
  }
  body[data-page="design-system"] {
    background: #ffffff !important;
    color: #000 !important;
  }
  body[data-page="design-system"] .surface,
  body[data-page="design-system"] .ds-section,
  body[data-page="design-system"] .tx-receipt-card,
  .ds-hero,
  body[data-page="design-system"] .modal {
    break-inside: avoid;
    page-break-inside: avoid;
    background: #ffffff !important;
    color: #000 !important;
    border: 1px solid #ccc !important;
    box-shadow: none !important;
  }
  body[data-page="design-system"] .hash-pill__value,
  body[data-page="design-system"] .meta-line__value {
    /* Print-friendly mono so OCR doesn't choke on the hashes. */
    font-family: "Courier New", "Courier", monospace !important;
  }
  @page {
    margin: 1.5cm;
  }
}
body[data-page="design-system"] h2 {
  font-size: clamp(1.05rem, 1.25vw, 1.3rem);
}

/* Drop label/eyebrow weight 800 → 700 inside the playground so labels
   actually whisper. */
body[data-page="design-system"] .section-label,
body[data-page="design-system"] .eyebrow,
body[data-page="design-system"] .micro-label {
  font-weight: 700;
}

/* Button-primary contrast: white text on --accent fails AA (3.86:1 in
   dark, ok-but-borderline in light). Scoped override pinned the button
   background to --accent-strong, which clears AA + AAA on white text.
   Hover lifts back to --accent for visible feedback. Kept scoped to
   /design-system while global button styles carry the production rule. */
/* Removed — global .button-primary now uses --accent-strong by default
   (lifted from this scoped fix per Phase C.1 audit UX2). */

/* Chip-row TOC — appears at top of /design-system, jumps to the 7
   shelves below. Replaces a sticky-rail TOC because chips work on
   mobile + desktop without a layout switch. Per content auditor §5
   + UX §8 (sticky TOC alternative). */
body[data-page="design-system"] .ds-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding: 0.85rem 0.95rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  /* Sticky on scroll — keeps the navigation reachable through the
     ~24-section page. Per third-pass UI U6 + UX §1 + frontend LIVE-10
     (3/3 consensus). Phase D.11 — was backdrop-filter: blur(10px) +
     surface 85% — the ONLY element in the system using blur. The
     blur created an isolated chrome treatment that broke composition
     ("DS pieces glued on" — user-flagged). Now uses the same
     translucent surface mix as the topbar (no blur). The 1px
     line-strong border carries the frame; sticky behavior intact. */
  position: sticky;
  /* Phase D.23 — was top: 0.5rem; the topbar above this is sticky
     at z-index 72 with a min-height ~3.2rem (--strip-h family). At
     top: 0.5rem the TOC docked 0.5rem BELOW the topbar leaving a
     visible content sliver above it (broken sticky look). Now docks
     directly below the topbar with a 0.25rem visual gap. */
  top: calc(var(--strip-h, 3.5rem) + 0.25rem);
  z-index: 50;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
}
/* Light theme — UI 4th-pass P4. The blur softens content scrolling
   beneath, but on cool-white --bg + white --surface there's almost
   nothing for the blur to soften (96% identical). Drop blur, raise
   opacity, bump border so the chip row still reads as a separator
   on scroll. Net: cleaner light, same depth feel. */
html[data-theme="light"] body[data-page="design-system"] .ds-toc {
  background: color-mix(in srgb, var(--surface) 96%, transparent);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-color: var(--line-strong);
}
body[data-page="design-system"] .ds-toc__chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--muted-strong);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-decoration: none;
  font-family: var(--ff-mono);
  transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
body[data-page="design-system"] .ds-toc__chip:hover {
  color: var(--text-strong);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--line-strong));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}
body[data-page="design-system"] .ds-toc__chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Active shelf — IntersectionObserver flips aria-current="location"
   on the chip whose shelf is currently in viewport. Per third-pass
   3/3 consensus (UI U6 + UX §2 + frontend LIVE-10). */
body[data-page="design-system"] .ds-toc__chip[aria-current="location"] {
  color: var(--text-strong);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, var(--surface));
}
body[data-page="design-system"] .ds-toc__chip[aria-current="location"] .ds-toc__chip-numeral {
  color: var(--accent);
}
body[data-page="design-system"] .ds-toc__chip-numeral {
  color: var(--muted);
  font-size: var(--fs-2xs);
  letter-spacing: 0.06em;
}
/* Count pill — sits at the right of each TOC chip, shows how many
   primitive sections live under that shelf. Mono digits, slightly
   dimmer than the label. Per UI fourth-pass P10. */
body[data-page="design-system"] .ds-toc__chip-count {
  margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--muted) 12%, transparent);
  color: var(--muted-strong);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
body[data-page="design-system"] .ds-toc__chip[aria-current="location"] .ds-toc__chip-count {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--accent);
}

/* Shelf headers — section-group dividers for the 7-shelf IA. */
body[data-page="design-system"] .ds-shelf__header {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  padding: 1.6rem 0.25rem 0.5rem;
  border-bottom: 1px dashed var(--line);
  /* Sticky TOC's effective height ≈ 3rem (chip row 2.4rem + 0.5rem
     top offset). UX 4th-pass #1 fixed every chip-click landing the
     destination heading underneath the TOC. */
  scroll-margin-top: 3.25rem;
}
body[data-page="design-system"] .ds-shelf__numeral {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.08em;
}
body[data-page="design-system"] .ds-shelf__title {
  margin: 0;
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: -0.005em;
}
body[data-page="design-system"] .ds-shelf__sub {
  margin-left: auto;
  font-size: var(--fs-2xs);
  color: var(--muted);
  font-family: var(--ff-mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Sub-eyebrow — sits above a cluster inside a section, marking
   sub-groups when one section packs 3+ primitive families. Used
   in the On-chain attributes section (Identity / Telemetry /
   Lifecycle) per UX 4th-pass #45. Mono uppercase mirrors the
   global eyebrow rhythm without inventing a new size. */
body[data-page="design-system"] .ds-sub-eyebrow {
  margin: 0 0 0.5rem;
  padding: 0 0 0.35rem;
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-strong);
  border-bottom: 1px dashed var(--line);
}

/* "Reads as" caption — single-sentence operator hint above each
   chart in the Charts section. The bold word is the scan-target
   answer ("where am I", "did this policy survive"); the rest is
   the legend in plain prose. UX 4th-pass #46. */
body[data-page="design-system"] .ds-chart-reads-as {
  margin: 0 0 0.55rem;
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--muted-strong);
  max-width: 64ch;
}
body[data-page="design-system"] .ds-chart-reads-as strong {
  color: var(--text-strong);
  font-weight: 700;
}

/* Frozen hover demo — UX 4th-pass #26. data-hover-frozen pins the
   :hover paint so a designer can read the hover treatment in a
   screenshot without losing it on mouseout. Scoped to the design
   system playground only — never applied on real surfaces. */
body[data-page="design-system"] .button-secondary[data-hover-frozen="true"] {
  background: var(--surface-tint);
  border-color: var(--line-strong);
}

/* .listbox — primitive paired with .select-trigger[aria-expanded=true].
   Sits below or above the trigger; ARIA listbox role. Demoed open
   in /design-system per UX 4th-pass #21. */
body[data-page="design-system"] .ds-listbox-host {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  gap: 0.4rem;
  align-items: stretch;
  min-width: 18rem;
}
body[data-page="design-system"] .listbox {
  list-style: none;
  margin: 0;
  padding: 0.3rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
body[data-page="design-system"] .listbox__option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.55rem;
  border-radius: var(--radius-xs);
  font-size: var(--fs-sm);
  color: var(--text-strong);
  cursor: pointer;
}
body[data-page="design-system"] .listbox__option:hover,
body[data-page="design-system"] .listbox__option:focus-visible {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  outline: none;
}
body[data-page="design-system"] .listbox__option[aria-selected="true"] {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--text-strong);
  font-weight: 700;
}
body[data-page="design-system"] .listbox__option[aria-disabled="true"] {
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.7;
}

/* Section anchor on hover — # link rev-positioned to the right of
   the section head. Stays invisible until hover so it doesn't add
   noise; then surfaces for permalink copy. */
body[data-page="design-system"] .ds-section .section-head {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

/* B.16.2 — A+5 section-head category icon. 14 px glyph sits to the
   left of the section-label text. Muted at rest; flips to accent
   on .ds-section:hover (matches the # anchor permalink affordance).
   Vertical-align middle so it sits with the uppercase eyebrow. */
body[data-page="design-system"] .ds-section .section-label {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}
body[data-page="design-system"] .ds-section__icon {
  color: var(--muted);
  flex: 0 0 auto;
  transition: color 120ms ease;
}
body[data-page="design-system"] .ds-section:hover .ds-section__icon {
  color: var(--accent);
}
body[data-page="design-system"] .ds-section__anchor {
  margin-left: auto;
  color: var(--muted);
  font-family: var(--ff-mono);
  text-decoration: none;
  font-size: var(--fs-md);
  padding: 0 0.4rem;
  opacity: 0;
  transition: opacity 120ms ease, color 120ms ease;
}
body[data-page="design-system"] .ds-section:hover .ds-section__anchor,
body[data-page="design-system"] .ds-section__anchor:focus-visible {
  opacity: 1;
}
body[data-page="design-system"] .ds-section__anchor:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
body[data-page="design-system"] .ds-section__anchor:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-radius: var(--radius-pill);
}
/* A+1 focal-attention anchors — when one .ds-section is hovered,
   the others fade their `#` permalinks. Turns the page into a
   navigable atlas without adding chrome. Modern :has() — Chrome
   105+ / Safari 15.4+ / Firefox 121+; older browsers just keep
   the default opacity behaviour, no breakage. */
@supports selector(:has(:hover)) {
  body[data-page="design-system"]:has(.ds-section:hover) .ds-section:not(:hover) .ds-section__anchor {
    opacity: 0;
  }
}

/* Smooth scroll for in-page anchor jumps — only when reduced-motion
   is OK. Sections get scroll-margin so the chip-row TOC doesn't
   land them under a sticky topbar. */
@media (prefers-reduced-motion: no-preference) {
  body[data-page="design-system"] { scroll-behavior: smooth; }
}
/* Same 3.25rem clears the sticky chip row on chip-click + #hash
   deep-link. UX 4th-pass #1. The .ds-shelf__header rule sets its
   own value above (3.25rem); this rule applies the same to every
   .ds-section so anchor permalinks land cleanly. Mobile portrait
   (<640px) the TOC wraps to two rows — bumped to 5rem. */
body[data-page="design-system"] .ds-section { scroll-margin-top: 3.25rem; }
@media (max-width: 640px) {
  body[data-page="design-system"] .ds-section,
  body[data-page="design-system"] .ds-shelf__header { scroll-margin-top: 5rem; }
}

/* Skip link — keyboard-only operators bypass the topbar / trust-strip
   and land on main content. Phase C.5 lifted from /design-system
   scope to global so every consumer page has the same affordance. */
.skip-link {
  position: fixed;
  top: max(0.5rem, env(safe-area-inset-top));
  left: max(0.5rem, env(safe-area-inset-left));
  padding: 0.5rem 0.85rem;
  background: var(--accent-strong);
  color: var(--on-accent-text);
  border-radius: var(--radius-sm);
  font-weight: 700;
  font-size: var(--fs-sm);
  text-decoration: none;
  z-index: 200;
  transform: translateY(calc(-100% - 1rem));
  transition: transform 120ms ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Icon sizing scale — global tokens (no risk to other pages, no
   existing rule references --icon-*). Used by .token-mark, the new
   icon() helper, and inline glyphs across the playground. */
:root {
  --icon-xs: 12px;
  --icon-sm: 14px;
  --icon-md: 16px;
  --icon-lg: 20px;
  --icon-xl: 24px;
  --icon-2xl: 40px;
  --icon-3xl: 56px;
}

/* Icon helper output — see app.js icon(name, size, opts). Sized via
   the --icon-* tokens above. Single class because we don't need a
   variant dance: the size modifier is the only difference. */
.ds-icon {
  flex: 0 0 auto;
  display: inline-block;
  vertical-align: middle;
  width: var(--icon-md);
  height: var(--icon-md);
}
.ds-icon--xs  { width: var(--icon-xs);  height: var(--icon-xs); }
.ds-icon--sm  { width: var(--icon-sm);  height: var(--icon-sm); }
.ds-icon--md  { width: var(--icon-md);  height: var(--icon-md); }
.ds-icon--lg  { width: var(--icon-lg);  height: var(--icon-lg); }
.ds-icon--xl  { width: var(--icon-xl);  height: var(--icon-xl); }
.ds-icon--2xl { width: var(--icon-2xl); height: var(--icon-2xl); }
.ds-icon--3xl { width: var(--icon-3xl); height: var(--icon-3xl); }

/* Token-mark — circular wrapper around a token logo. 1 px rim,
   var(--surface-soft) inner fill, logo at ~70% of outer width. Used
   anywhere a token logo ships as a self-contained mark (TX rows,
   token-amount-rows, hero KPI tiles, list items). Tone-neutral —
   tone goes on the row around the mark, never on the rim itself. */
.token-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--surface-soft);
  border: 1px solid var(--line);
  overflow: hidden;
  position: relative;
  box-shadow: inset 0 0 0 1px var(--line);
}
.token-mark img {
  width: 70%;
  height: 70%;
  object-fit: contain;
  border-radius: 50%;
  display: block;
}
.token-mark--xs { width: 16px; height: 16px; }
.token-mark--sm { width: 20px; height: 20px; }
.token-mark--md { width: 28px; height: 28px; }
.token-mark--lg { width: 40px; height: 40px; }
.token-mark--xl { width: 56px; height: 56px; }
.token-mark--missing {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 12%, var(--surface-soft));
  border-color: color-mix(in srgb, var(--amber) 35%, transparent);
}

* {
  box-sizing: border-box;
}

html {
  /* Default html bg matches lifted dark --bg #06060a; per-theme
     overrides are inline in each page's <style> head block. */
  background: #06060a;
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: "Manrope", "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: 180ms;
  animation-timing-function: ease;
}

a {
  color: inherit;
  text-decoration: none;
}

button, input, select, textarea {
  font: inherit;
}

button {
  cursor: pointer;
}

img {
  display: block;
  max-width: 100%;
}

[hidden] {
  display: none !important;
}

.app-shell {
  min-height: 100vh;
}

.sidebar-wallet {
  display: none !important;
}

.eyebrow, .section-label, .micro-label, .metric-card span, .note-card span, .hero-chip, .saved-card-meta span, .state-badge, .token-chip span:first-of-type, .route-score {
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.wallet-connect-btn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 2.75rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius-xs);
  background: var(--accent);
  color: var(--on-accent-text);
  font: 600 var(--fs-xs) / 1.3 var(--ff);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.wallet-connect-btn:hover {
  background: var(--accent-strong);
}

.wallet-connect-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.wallet-icon {
  width: 20px;
  height: 20px;
  border-radius: var(--radius-pill);
  flex-shrink: 0;
}

.wallet-address {
  font: 500 var(--fs-xs) / 1.2 var(--ff-mono, var(--ff));
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.wallet-disconnect {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--sidebar-sub);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s, background 0.15s;
}

.wallet-disconnect:hover {
  /* R8: --warning is now an alias of --amber, not rose; the legacy
     rgba(248,113,113,…) was the pre-lift rose. Disconnect is a
     destructive action — rose is the right tone, --rose-text reads
     on the soft hover-fill in both themes. */
  color: var(--rose-text);
  background: var(--rose-soft);
}

.wallet-disconnect svg {
  width: 16px;
  height: 16px;
}

.field-collateral {
  position: relative;
  z-index: 2;
  gap: 0.36rem;
  min-width: 0;
  overflow: visible;
  grid-column: span 2;
  align-content: start;
}

.collateral-picker {
  position: relative;
  min-width: 0;
  width: 100%;
  z-index: 200;
}

.collateral-picker[open] {
  z-index: 2147483000;
}

.collateral-picker:not([open]) .collateral-asset-menu {
  display: none;
}

.collateral-picker > summary {
  list-style: none;
}

.collateral-picker > summary::-webkit-details-marker {
  display: none;
}

.collateral-asset-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.45rem;
  width: 100%;
  min-width: 0;
  min-height: 2.78rem;
  padding: 0 0.88rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  background: var(--bg-strong);
  color: var(--text);
  cursor: pointer;
  transition:
    border-color 150ms ease,
    background-color 150ms ease,
    color 150ms ease;
}

.collateral-asset-trigger-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.collateral-picker[open] .collateral-asset-trigger, .collateral-asset-trigger:hover {
  border-color: var(--line-strong);
  background: var(--surface-soft);
}

.collateral-picker.is-disabled .collateral-asset-trigger {
  opacity: 0.7;
  pointer-events: none;
  cursor: default;
}

.collateral-asset-symbol {
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.collateral-asset-balance {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 600;
  line-height: 1.1;
}

.collateral-asset-trigger svg {
  width: 0.9rem;
  height: 0.9rem;
  flex: 0 0 auto;
  color: var(--muted);
}

.collateral-asset-menu {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2147483000;
  box-sizing: border-box;
  min-width: 0;
  display: grid;
  gap: 0;
  max-height: min(26rem, 70vh);
  overflow-y: auto;
  padding: 0;
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  background: var(--surface-soft);
  box-shadow: var(--shadow-lg);
  isolation: isolate;
  overflow-x: hidden;
}

.collateral-asset-menu[data-placement="top"] {
  border-top: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  box-shadow: var(--shadow-lg);
}

.collateral-asset-option {
  display: grid;
  grid-template-columns: 1.875rem minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 0.25rem 0.58rem;
  width: 100%;
  min-height: 0;
  padding: 0.6rem 1.5rem 0.6rem 2.08rem;
  border: 0;
  border-top: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: background-color 150ms ease;
}

.collateral-asset-option:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.collateral-asset-option-leading {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.collateral-asset-option-leading .collateral-asset-mark {
  width: 1.55rem;
  height: 1.55rem;
}

.collateral-asset-option-leading .collateral-asset-mark-image {
  width: 1.15rem;
  height: 1.15rem;
}

.collateral-asset-option-copy {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
  text-align: left;
}

.collateral-asset-option-symbol-row {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  min-width: 0;
  flex-wrap: wrap;
}

.collateral-asset-option-symbol {
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: 800;
  line-height: 1.05;
}

.collateral-asset-option-type {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: 0.85;
}

.collateral-asset-option-trailing {
  display: grid;
  justify-items: end;
  gap: 0.1rem;
  min-width: 2.4rem;
  text-align: right;
}

.collateral-asset-option-value {
  color: var(--text-strong);
  font-size: var(--fs-base);
  font-weight: 800;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.collateral-asset-option-value.is-manual {
  color: var(--muted-strong);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.collateral-asset-option-value.is-zero {
  color: var(--muted-strong);
}

.collateral-asset-option-value-usd {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  line-height: 1.15;
}

.collateral-asset-option-meta-row {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
}

.collateral-asset-option-rate {
  margin-left: auto;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  letter-spacing: 0.01em;
}

.collateral-asset-option-meta {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  max-width: 100%;
  padding: 0.12rem 0.42rem;
  border: 1px solid color-mix(in srgb, var(--line) 72%, transparent);
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--surface-soft) 65%, transparent);
  color: var(--muted);
  font-family: "Manrope", system-ui, sans-serif;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.03em;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.collateral-asset-option-copy-btn,
.collateral-asset-option-view-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Phase D.33 (UI G-11) — was 1.35rem (~21.6px), failing WCAG 2.5.5
     min tap target (24px). 1.5rem = 24px exactly. */
  width: 1.5rem;
  height: 1.5rem;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--surface-soft) 55%, transparent);
  color: var(--muted);
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
  text-decoration: none;
}

.collateral-asset-option-copy-btn:hover,
.collateral-asset-option-view-btn:hover {
  color: var(--text);
  border-color: var(--line-strong);
  background: var(--surface-soft);
}

.collateral-asset-option-copy-btn.is-copied {
  color: var(--mint);
  border-color: color-mix(in srgb, var(--mint) 45%, transparent);
}

.collateral-asset-mark {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.55rem;
  height: 2.55rem;
  border-radius: var(--radius-full);
  background: var(--surface-soft);
  border: 1px solid var(--line);

}

.collateral-asset-mark-image {
  width: 1.9rem;
  height: 1.9rem;
  object-fit: contain;
}

.collateral-balance-copy {
  flex: 1 1 auto;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.35;
  min-width: 0;
  white-space: normal;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.collateral-balance-chip {
  display: inline-flex;
  align-items: center;
  min-height: 1.5rem;
  max-width: 9rem;
  padding: 0 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface-soft);
  color: var(--muted-strong);
  /* Phase D.32 — was 0.68rem literal; tracked --fs-xs's current value
     but would drift if the token changed. Now references the token. */
  font: 700 var(--fs-xs) / 1 var(--ff);
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-transform: uppercase;
}

.collateral-use-max {
  flex: 0 0 auto;
  min-height: 1.5rem;
  padding: 0 0.55rem;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--line-strong));
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font: 700 0.68rem / 1 var(--ff);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    border-color 150ms ease,
    background-color 150ms ease;
}

.collateral-use-max:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--line-strong));
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

.collateral-use-max:disabled {
  opacity: 0.65;
  cursor: default;
}

.wm-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Modal scrim — dark canvas at 60% opacity tracks both themes:
     dark canvas ≈ #06060a in dark, #F4F7FB in light. Light scrim
     blocks the scrim semantic, so use a dedicated darken pattern. */
  background: color-mix(in srgb, var(--text-strong) 60%, transparent);
  opacity: 0;
  transition: opacity 0.18s ease;
}

.wm-overlay.wm-visible {
  opacity: 1;
}

.wm-modal {
  width: 90vw;
  max-width: 480px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  /* R5: tracks the lifted --radius-lg scale (22 px) instead of a
     hardcoded 16 — modal is the largest surface family member, the
     biggest token in the radius scale fits. */
  border-radius: var(--radius-lg);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  transform: translateY(12px) scale(0.97);
  transition: transform 0.18s ease;
}

.wm-visible .wm-modal {
  transform: translateY(0) scale(1);
}

.wm-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.1rem 1.3rem 0.8rem;
}

.wm-title {
  margin: 0;
  /* Phase D.33 (UI G-19) — was `font: 600 1.05rem / 1.3 var(--ff)`.
     1.05rem off-scale (between --fs-md 1rem and --fs-lg 1.2rem); the
     shorthand also reset font-variant wiping tabular-nums. Aligned
     to canonical type-scale tokens. */
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.4;
  color: var(--text-strong);
}

.wm-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--surface-soft);
  color: var(--muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.wm-close:hover {
  background: var(--surface-emphasis);
  color: var(--text-strong);
}

.wm-close svg {
  width: 16px;
  height: 16px;
}

.wm-body {
  padding: 0.4rem 1.3rem 1.3rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.wm-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
}

.wm-wallet-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.75rem 0.4rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.wm-wallet-btn:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}

.wm-wallet-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-xs);
  object-fit: contain;
}

.wm-wallet-name {
  font: 500 var(--fs-2xs) / 1.3 var(--ff);
  text-align: center;
  word-break: break-word;
}

.wm-install-tag {
  /* Phase D.32 — was 0.55rem (8.8px), below the --fs-2xs (0.6rem ≈
     9.6px) WCAG 1.4.4 floor. Lifted to the floor token. */
  font: 600 var(--fs-2xs) / 1 var(--ff);
  color: var(--accent);
  opacity: 0.7;
}

.wm-divider {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 1rem 0 0.6rem;
}

.wm-divider::before, .wm-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.wm-divider span {
  font: 500 var(--fs-2xs) / 1 var(--ff);
  color: var(--muted);
  white-space: nowrap;
}

.wm-empty {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--muted);
  font-size: var(--fs-sm);
}

@media (max-width: 480px) {
.wm-grid { grid-template-columns: repeat(2, 1fr); }

.wm-modal { max-width: 95vw; }

}

.micro-label {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 800;
}

.theme-toggle {
  display: flex;
  gap: 0.3rem;
  padding: 0.1rem;
  border-radius: var(--radius-xs);
  background: var(--sidebar-hover);
}

.theme-toggle button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 0;
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--sidebar-text);
  padding: 0;
  transition:
    background-color 180ms ease,
    color 180ms ease;
}

.theme-toggle button:hover {
  background: var(--sidebar-hover);
  color: var(--sidebar-heading);
}

.theme-toggle button.is-active {
  background: var(--sidebar-active-bg);

  color: var(--sidebar-active-text);
}

.theme-icon {
  width: 1.05rem;
  height: 1.05rem;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.page-tools, .section-head > div, .saved-card-head > div, .route-card-head > :first-child {
  min-width: 0;
}

/* §9.17 (Phase D.30.5) — canonical page-level container.
   ONE base padding rule for every .app-main on every page. Per-page
   modifier classes (.app-main--topbar, .app-main--setup) may adjust
   width-cap + bottom padding, but inline padding stays system-locked
   so the operator never sees a horizontal page-edge shift between
   /setup → /results → /live transitions. Was: six competing rules
   across 20-live.css and 10-results-workspace.css that produced a
   visible gutter shift between pages. */
.app-main {
  padding-inline: clamp(1rem, 2vw, 1.6rem);
  padding-block: 1rem 2rem;
}
.app-main--topbar {
  /* Phase D.32 (F-1) — was 1680px. /results and /live had a separate
     1440px cap (foundation-shell ~line 4438) which produced visibly
     wider page-edge gutters on those pages vs /workspace and /library
     at the same viewport. Unified to 1440px across every --topbar
     page so the gutter is identical and the cockpit reads as one
     spatial system. The 4438 page-specific override is now redundant
     but kept as a no-op for explicit documentation. */
  width: min(100%, 1440px);
  margin-inline: auto;
  padding-block-end: 5rem;
}
.app-main--setup {
  /* Phase D.32 — was 1700px → 1680px → 1440px. Aligned to --topbar
     so /setup, /workspace, /results, /live, /library all share the
     same content cap and the same horizontal gutter. */
  width: min(100%, 1440px);
  margin-inline: auto;
  padding-block-end: 0.5rem;
}
@media (max-width: 760px) {
  .app-main {
    padding-inline: 0.85rem;
  }
  .app-main--topbar {
    padding-block-end: 4.5rem;
  }
}

/* Canonical topbar primitive shared by Workspace, Setup, Readout,
   Live, Library, and /design-system. Per DS §9.1/§9.2, page shells
   compose this primitive instead of carrying route-local topbar chrome. */
.app-shell--topbar,
.app-shell--setup {
  display: block;
  min-height: 100vh;
}

.app-topbar {
  position: sticky;
  top: 0;
  z-index: 72;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem clamp(1rem, 2vw, 1.6rem);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(18px);
  border-bottom: 1px solid color-mix(in srgb, var(--line) 52%, transparent);
}

.app-topbar__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
  color: var(--text-strong);
  text-decoration: none;
}

.app-topbar__brand:focus-visible,
.app-footer a:focus-visible,
.surface-evidence__summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

.app-topbar__brand img {
  width: 2.75rem;
  height: auto;
  aspect-ratio: 3 / 2;
  flex: 0 0 2.75rem;
  display: block;
}

.app-topbar__brand span {
  font-size: var(--fs-md);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-strong);
}

.app-topbar__actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.65rem;
  min-width: 0;
}

/* Canonical topbar wallet pill. This belongs in the foundation bundle
   because every app surface renders #header-wallet, including Setup,
   which intentionally does not load the runtime-polish bundle. */
.wallet-pill {
  position: relative;
}

.wallet-pill__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 3.1rem;
  padding: 0.42rem 0.78rem;
  border: 1px solid color-mix(in srgb, var(--line-strong) 82%, transparent);
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  color: var(--text-strong);
}

.wallet-pill__main {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-width: 0;
}

.wallet-pill__icon,
.wallet-pill__icon--fallback {
  width: 1.7rem;
  height: 1.7rem;
  border-radius: var(--radius-full);
  flex: 0 0 1.7rem;
}

.wallet-pill__icon--fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--accent-soft) 84%, transparent);
  color: var(--accent);
  font-size: var(--fs-sm);
  font-weight: 800;
}

.wallet-pill__chevron {
  width: 0.92rem;
  height: 0.92rem;
  flex: 0 0 0.92rem;
}

.wallet-popover {
  position: absolute;
  top: calc(100% + 0.45rem);
  right: 0;
  min-width: 13rem;
  padding: 0.35rem;
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--line-strong) 82%, transparent);
  background: color-mix(in srgb, var(--surface-strong) 96%, transparent);
  box-shadow: var(--shadow-md);
  display: grid;
  gap: 0.18rem;
  z-index: 80;
}

.wallet-popover[hidden] {
  display: none;
}

.wallet-popover__action {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 2.4rem;
  padding: 0.5rem 0.72rem;
  border: 0;
  border-radius: var(--radius-xs);
  background: transparent;
  color: var(--text-strong);
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}

.wallet-popover__action:hover {
  background: color-mix(in srgb, var(--accent-soft) 76%, transparent);
}

.wallet-popover__action--danger:hover {
  background: color-mix(in srgb, var(--rose-soft) 80%, transparent);
  color: var(--rose-text);
}

@media (max-width: 760px) {
  .app-topbar {
    min-height: 3.25rem;
    padding: calc(0.32rem + env(safe-area-inset-top, 0px)) 0.55rem 0.32rem;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.45rem;
  }

  .app-topbar__actions {
    width: auto;
    flex: 0 1 auto;
    justify-content: flex-end;
    gap: 0.45rem;
    margin-inline-start: auto;
  }

  .app-topbar__actions > .network-badge {
    display: none !important;
  }

  .app-topbar__brand {
    flex: 0 1 auto;
    gap: 0.45rem;
  }

  .app-topbar__brand img {
    width: 2.2rem;
    flex-basis: 2.2rem;
  }

  .app-topbar__brand span {
    font-size: var(--fs-sm);
    letter-spacing: 0.06em;
  }

  .app-topbar .theme-toggle {
    flex: 0 0 auto;
    min-height: 2.2rem;
    padding: 0.14rem;
  }

  .app-topbar .theme-toggle button,
  .app-topbar .theme-toggle [role="switch"] {
    width: 2rem;
    min-width: 2rem;
    height: 2rem;
  }

  .app-topbar .wallet-connect-btn,
  .app-topbar .wallet-pill__trigger {
    min-height: 2.2rem;
    padding: 0.34rem 0.52rem;
    border-radius: var(--radius-xs);
  }

  .app-topbar .wallet-connect-btn {
    width: auto;
    white-space: nowrap;
  }

  .app-topbar .wallet-icon,
  .app-topbar .wallet-pill__icon,
  .app-topbar .wallet-pill__icon--fallback {
    width: 1.45rem;
    height: 1.45rem;
    flex-basis: 1.45rem;
  }

  .app-topbar .wallet-address {
    max-width: 8ch;
  }
}

/* Design-system playground — visual catalogue page at /design-system.
   Every primitive in this section is the same primitive used in
   Workspace / Setup / Readout, just rendered with mock data so a
   developer can copy the markup. The .ds-* classes here are the
   *playground chrome* (section-micro-label, swatches, code snippets,
   layout demos), not part of the product surface vocabulary. */
.ds-page {
  max-width: 1440px;
  margin-inline: auto;
}
.section-micro-label {
  display: block;
  margin: 0 0 0.4rem;
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.ds-section {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.ds-section__body {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}
.ds-spacer {
  height: 0.6rem;
}
.ds-cluster {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  align-items: center;
}
.ds-stack {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* Token grid — three columns: tones / radii / type */
.ds-token-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.1rem;
}
.ds-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 0.5rem;
}
.ds-swatch {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 35%, transparent);
}
.ds-swatch__chip {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-xs);
  flex: 0 0 auto;
  border: 1px solid var(--line-strong);
}
.ds-swatch__meta {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}
.ds-swatch__meta strong {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--text-strong);
}
.ds-swatch__meta span {
  font-size: var(--fs-2xs);
  color: var(--muted);
  line-height: 1.35;
}

.ds-radii {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: 0.5rem;
}
.ds-radius {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  align-items: center;
  padding: 0.5rem 0.4rem;
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface-soft) 30%, transparent);
  border-radius: var(--radius-sm);
}
.ds-radius__chip {
  width: 36px;
  height: 36px;
  background: color-mix(in srgb, var(--accent) 22%, var(--surface));
  border: 1px solid var(--line-strong);
}
.ds-radius strong {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--text-strong);
}
.ds-radius span {
  font-size: var(--fs-2xs);
  color: var(--muted);
}

.ds-type {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.ds-type-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.25rem 0.5rem;
  border-bottom: 1px dashed var(--line);
}
.ds-type-row:last-child { border-bottom: none; }
.ds-type-row strong {
  color: var(--text-strong);
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ds-type-row span {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
}

/* Iconography showcase — glyph library, size scale, token marks */
.ds-icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 0.45rem;
}
.ds-icon-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.55rem 0.4rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 35%, transparent);
  color: var(--text-strong);
}
.ds-icon-cell span {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
  text-align: center;
  word-break: break-word;
}
.ds-icon-sizes {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.ds-icon-size-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.3rem 0.5rem;
  border-bottom: 1px dashed var(--line);
  color: var(--text-strong);
}
.ds-icon-size-row:last-child { border-bottom: none; }
.ds-icon-size-row span {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
}
.ds-token-marks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.ds-token-mark-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 35%, transparent);
  min-width: 64px;
}
.ds-token-mark-cell span {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
}

/* Surface variants showcase */
.ds-surfaces {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.65rem;
}

/* Card and TX showcase rows */
.ds-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.55rem;
}
.ds-cards--metrics {
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

/* Layout grid demo cells — solid colored placeholders so the column
   ratios are visible at a glance. */
.ds-grid-demo {
  display: grid;
  gap: 0.55rem;
}
.ds-grid-demo--hero { grid-template-columns: minmax(0, 1.5fr) minmax(280px, 1fr); }
.ds-grid-demo--credibility { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
.ds-grid-demo--details { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); }
.ds-grid-demo--setup { grid-template-columns: minmax(0, 1fr) minmax(320px, 380px); }
.ds-grid-cell {
  padding: 1.1rem 1rem;
  border: 1px dashed color-mix(in srgb, var(--accent) 50%, var(--line-strong));
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--accent);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.ds-grid-cell--alt {
  border-color: color-mix(in srgb, var(--mint) 50%, var(--line-strong));
  background: color-mix(in srgb, var(--mint) 6%, transparent);
  color: var(--mint);
}
@media (max-width: 720px) {
  .ds-grid-demo--hero,
  .ds-grid-demo--credibility,
  .ds-grid-demo--details,
  .ds-grid-demo--setup {
    grid-template-columns: 1fr;
  }
}

/* Snippet code blocks — collapsed by default, expand to copy markup */
.ds-snippet {
  margin-top: 0.4rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 35%, transparent);
}
.ds-snippet > summary {
  cursor: pointer;
  list-style: none;
  padding: 0.4rem 0.65rem;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.ds-snippet > summary::-webkit-details-marker { display: none; }
.ds-snippet > summary::before {
  content: "›";
  display: inline-block;
  margin-right: 0.4rem;
  transition: transform 150ms ease;
}
.ds-snippet[open] > summary::before {
  transform: rotate(90deg);
}
.ds-snippet[open] > summary {
  border-bottom: 1px solid var(--line);
  color: var(--text-strong);
}
.ds-snippet pre {
  margin: 0;
  padding: 0.7rem 0.85rem;
  overflow-x: auto;
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  line-height: 1.5;
  color: var(--text);
  background: transparent;
}

/* Anti-pattern list */
.ds-anti-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.ds-anti-list li {
  padding: 0.45rem 0.65rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--rose);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--rose) 5%, transparent);
  font-size: var(--fs-xs);
  line-height: 1.5;
}
.ds-anti-list strong {
  color: var(--text-strong);
  margin-right: 0.3rem;
}

/* ──────────────────────────────────────────────────────────────────
   Form-control primitives — canonical reusable chrome that the
   design-system playground promotes from page-local one-offs. Live
   globally so any future page can pull them; only USED in the
   /design-system playground today, so other pages stay untouched.
   ────────────────────────────────────────────────────────────────── */

/* .toggle-switch — sliding switch wrapping a real <input type="checkbox">.
   Off = muted track. On = accent track + thumb pushed right. */
.toggle-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  cursor: pointer;
  font-size: var(--fs-sm);
  color: var(--text-strong);
  user-select: none;
}
.toggle-switch input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.toggle-switch__track {
  width: 34px;
  height: 20px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--muted) 25%, transparent);
  border: 1px solid var(--line-strong);
  position: relative;
  transition: background 120ms ease, border-color 120ms ease;
  flex: 0 0 auto;
}
.toggle-switch__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--text-strong);
  box-shadow: var(--shadow-sm);
  transition: left 140ms ease, background 120ms ease;
}
.toggle-switch input[type="checkbox"]:checked + .toggle-switch__track {
  background: var(--accent);
  border-color: var(--accent);
}
.toggle-switch input[type="checkbox"]:checked + .toggle-switch__track .toggle-switch__thumb {
  left: 16px;
  background: var(--surface);
}
.toggle-switch input[type="checkbox"]:focus-visible + .toggle-switch__track {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.toggle-switch input[type="checkbox"]:disabled + .toggle-switch__track {
  opacity: 0.45;
  cursor: not-allowed;
}

/* .segmented — canonical button-group (replaces page-local
   .swap-card__preset pattern). Encloses 2+ .segmented__option buttons. */
.segmented {
  display: inline-flex;
  gap: 0;
  padding: 3px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
}
.segmented__option {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted-strong);
  padding: 0.32rem 0.75rem;
  font-size: var(--fs-xs);
  font-weight: 600;
  border-radius: calc(var(--radius-sm) - 3px);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.segmented__option:hover {
  color: var(--text-strong);
}
.segmented__option[aria-pressed="true"],
.segmented__option.is-active {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}
.segmented__option:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.segmented__option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* .segmented--exclusive — radiogroup variant for mutually-exclusive
   choices (mode selector, network selector). Visual matches
   .segmented but ARIA semantics are role="radiogroup" + role="radio"
   + aria-checked. Per Phase-C Q8 + frontend §24. The default
   .segmented stays toggle-button-with-aria-pressed for non-exclusive
   filters / sort-orders. */
.segmented--exclusive .segmented__option[aria-checked="true"],
.segmented--exclusive .segmented__option:has(input:checked) {
  background: var(--surface);
  color: var(--text-strong);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}

/* Strategy preset cards — large starter choices for non-expert users.
   Use when a profile/template is the primary path through a form. They
   are heavier than .segmented options and lighter than saved policy rows. */
.strategy-goal-copy {
  margin: -0.18rem 0 0;
  max-width: 52rem;
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: 1.45;
}
.strategy-presets--profiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.72rem;
}
.strategy-preset {
  appearance: none;
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(2.2rem, 1fr) auto;
  gap: 0.55rem;
  align-content: start;
  min-height: 8.4rem;
  padding: 0.95rem 1rem 0.9rem;
  border: 1px solid var(--line-strong);
  border-left: 4px solid color-mix(in srgb, var(--line-strong) 78%, transparent);
  border-radius: var(--radius-sm);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--surface-strong) 70%, transparent), transparent 75%),
    var(--surface-soft);
  color: var(--muted-strong);
  text-align: left;
  cursor: pointer;
  transition:
    background-color 150ms ease,
    border-color 150ms ease,
    color 150ms ease,
    transform 150ms ease;
}
.strategy-preset:hover {
  border-color: color-mix(in srgb, var(--accent) 54%, var(--line-strong));
  border-left-color: color-mix(in srgb, var(--accent) 72%, var(--line-strong));
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 7%, var(--surface-strong)), transparent 80%),
    var(--surface);
}
.strategy-preset[aria-pressed="true"] {
  border-color: color-mix(in srgb, var(--accent) 46%, var(--line-strong));
  border-left-color: var(--accent);
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 12%, var(--surface-strong)), transparent 84%),
    var(--surface);
  color: var(--text-strong);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent),
    0 1px 0 color-mix(in srgb, var(--accent) 14%, transparent);
}
.strategy-preset__topline,
.strategy-preset__name {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
}
.strategy-preset__topline {
  justify-content: space-between;
}
.strategy-preset__name strong,
.strategy-preset strong {
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1.12;
  color: var(--text-strong);
}
.strategy-preset__cue {
  flex: 0 0 auto;
  padding: 0.16rem 0.42rem;
  border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--line));
  border-radius: var(--radius-pill);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  font-size: var(--fs-2xs);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.strategy-preset[aria-pressed="true"] .strategy-preset__cue {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--line));
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-strong);
}
.strategy-preset em {
  display: block;
  max-width: 28rem;
  font-style: normal;
  font-size: var(--fs-sm);
  line-height: 1.38;
  color: var(--muted);
  opacity: 0.95;
}
.strategy-preset__stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.38rem;
  padding-top: 0.52rem;
  border-top: 1px solid color-mix(in srgb, var(--line) 80%, transparent);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
}
.strategy-preset__stats > span {
  display: grid;
  gap: 0.12rem;
  min-width: 0;
}
.strategy-preset__stats small {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.strategy-preset__stats b {
  display: inline;
  color: var(--text-strong);
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1.05;
}
.strategy-preset__stats span span {
  font-size: var(--fs-2xs);
  color: var(--muted);
}
@media (max-width: 900px) {
  .strategy-presets--profiles {
    grid-template-columns: minmax(0, 1fr);
  }
  .strategy-preset {
    min-height: 0;
  }
}

/* .select-trigger — canonical "click-to-pick" trigger (chevron + label).
   Used as the visual replacement for collateral-picker summaries. */
.select-trigger {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.75rem;
  background: var(--surface-soft);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--text-strong);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  min-height: 36px;
}
.select-trigger:hover {
  background: var(--surface-tint);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--line-strong));
}
.select-trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.select-trigger__icon {
  margin-left: auto;
  color: var(--muted);
  display: inline-flex;
}
.select-trigger[aria-expanded="true"] .select-trigger__icon {
  transform: rotate(180deg);
}
.select-trigger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* .stepper-input — number input with +/- step buttons. */
.stepper-input {
  display: inline-flex;
  align-items: stretch;
  min-height: 2.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  overflow: hidden;
}
.stepper-input__btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted-strong);
  min-width: 2.75rem;
  display: inline-flex;
  align-items: center;
  align-self: stretch;
  justify-content: center;
  height: auto;
  cursor: pointer;
  /* R6: lifted --fs-md is now 1rem; +/- glyphs at body-level competing
     with field labels. Step down to xs so the glyph recedes. */
  font-size: var(--fs-xs);
  font-weight: 700;
  transition: background 120ms ease, color 120ms ease;
}
.stepper-input__btn:hover {
  background: var(--surface-tint);
  color: var(--text-strong);
}
.stepper-input__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.stepper-input__btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.stepper-input input[type="number"] {
  align-self: stretch;
  width: 64px;
  height: auto;
  background: transparent;
  border: 0;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  color: var(--text-strong);
  text-align: center;
  font-size: var(--fs-sm);
  font-weight: 600;
  font-family: var(--ff-mono);
  -moz-appearance: textfield;
}
.stepper-input input[type="number"]::-webkit-inner-spin-button,
.stepper-input input[type="number"]::-webkit-outer-spin-button {
  appearance: none;
  margin: 0;
}
.stepper-input input[type="number"]:focus { outline: 0; }

/* .range-slider — canonical accent-tinted range slider. The fill is
   driven by --range-fill (set inline as a percent) so the accent track
   visually shows the value. Single-thumb only; range pair lives later. */
.range-slider {
  --range-fill: 50%;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  width: 100%;
}
.range-slider__head {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-2xs);
  color: var(--muted);
  font-family: var(--ff-mono);
}
.range-slider input[type="range"] {
  appearance: none;
  width: 100%;
  height: 6px;
  border-radius: var(--radius-full);
  background: linear-gradient(
    to right,
    var(--accent) 0%,
    var(--accent) var(--range-fill),
    color-mix(in srgb, var(--muted) 30%, transparent) var(--range-fill),
    color-mix(in srgb, var(--muted) 30%, transparent) 100%
  );
  outline: none;
  cursor: pointer;
}
.range-slider input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.range-slider input[type="range"]::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  cursor: pointer;
}
.range-slider input[type="range"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* .checkbox-row / .radio-row — native checkbox + radio styled to match
   the playground's tone palette. Simple inline-flex wrappers. */
.choice-row {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  font-size: var(--fs-sm);
  color: var(--text-strong);
}
.choice-row input[type="checkbox"],
.choice-row input[type="radio"] {
  appearance: none;
  width: 16px;
  height: 16px;
  margin: 0;
  border: 1px solid var(--line-strong);
  background: var(--surface-soft);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease, border-color 120ms ease;
}
.choice-row input[type="checkbox"] { border-radius: var(--radius-pill); }
.choice-row input[type="radio"]    { border-radius: 50%; }
.choice-row input[type="checkbox"]:checked,
.choice-row input[type="radio"]:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.choice-row input[type="checkbox"]:checked::after {
  content: "";
  width: 8px;
  height: 4px;
  border-left: 2px solid var(--surface);
  border-bottom: 2px solid var(--surface);
  transform: rotate(-45deg) translate(1px, -1px);
}
.choice-row input[type="radio"]:checked::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--surface);
}
.choice-row input[type="checkbox"]:focus-visible,
.choice-row input[type="radio"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.choice-row input[type="checkbox"]:disabled,
.choice-row input[type="radio"]:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Playground chrome for form-control sections. */
.ds-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0.9rem;
}
.ds-form-cell {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.ds-form-cell > .section-micro-label {
  margin: 0;
}
.ds-form-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem 1.1rem;
  align-items: center;
}

/* ──────────────────────────────────────────────────────────────────
   State primitives — spinner · skeleton · progress · toast · modal.
   Tooltip already lives in 20-live.css ([data-tooltip]); a copy is
   surfaced here so the playground can demo it without depending on
   the live bundle.
   ────────────────────────────────────────────────────────────────── */

/* .spinner — generic standalone (promoted from .btn-spinner). The
   button variant stays working; .btn-spinner is now an alias. */
.spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid color-mix(in srgb, currentColor 25%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spinnerSpin 0.6s linear infinite;
  vertical-align: middle;
  flex: 0 0 auto;
}
.spinner--xs { width: 0.75em; height: 0.75em; border-width: 1.5px; }
.spinner--sm { width: 0.85em; height: 0.85em; border-width: 1.5px; }
.spinner--md { width: 1.1em;  height: 1.1em;  border-width: 2px; }
.spinner--lg { width: 1.4em;  height: 1.4em;  border-width: 2.5px; }
@keyframes spinnerSpin {
  to { transform: rotate(360deg); }
}

/* .skeleton — animated placeholder. .skeleton--line is a single text
   line; .skeleton--block is a card-shaped placeholder. */
.skeleton {
  display: block;
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--muted) 12%, transparent);
}
.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--muted) 18%, transparent) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: skeletonShimmer 1.4s linear infinite;
}
.skeleton--line  { height: 0.85rem; width: 100%; }
.skeleton--block { height: 64px; width: 100%; border-radius: var(--radius-sm); }
.skeleton--circle { height: var(--radius-xl); width: var(--radius-xl); border-radius: 50%; }
@keyframes skeletonShimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.ui-skeleton {
  display: grid;
  gap: var(--space-3);
  width: 100%;
}

.ui-skeleton span {
  display: block;
}

.ui-skeleton__pill,
.ui-skeleton__title,
.ui-skeleton__line,
.ui-skeleton__bar,
.ui-skeleton__card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 72%, var(--line) 28%);
}

.ui-skeleton__pill::after,
.ui-skeleton__title::after,
.ui-skeleton__line::after,
.ui-skeleton__bar::after,
.ui-skeleton__card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 8%, transparent), transparent);
  transform: translateX(-100%);
  animation: skeletonShimmer 1.4s linear infinite;
}

.ui-skeleton__pill { width: 9rem; height: 1.35rem; border-radius: var(--radius-full); }
.ui-skeleton__title { width: min(18rem, 62%); height: 2.1rem; }
.ui-skeleton__line { width: min(36rem, 78%); height: 0.9rem; }
.ui-skeleton__bar { width: 100%; height: 2.4rem; }
.ui-skeleton__card { width: 100%; height: 5.5rem; }

.ui-skeleton--list {
  padding: var(--space-2) 0;
}

/* .progress — linear progress bar. Set --progress (0-100) inline. */
.progress {
  --progress: 50%;
  display: block;
  width: 100%;
  height: 6px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--muted) 18%, transparent);
  overflow: hidden;
  position: relative;
}
.progress::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  background: var(--accent);
  border-radius: inherit;
  /* Q12: animate transform (compositor-only) instead of width
     (forces layout per frame). --progress drives a translateX so
     the bar still grows from the left edge but paints cheap. */
  transform: translateX(calc(-100% + var(--progress)));
  transform-origin: left center;
  transition: transform 220ms ease;
}
.progress--mint::after  { background: var(--mint); }
.progress--amber::after { background: var(--amber); }
.progress--rose::after  { background: var(--rose); }
.progress--indeterminate::after {
  width: 30%;
  transform: translateX(-100%);
  animation: progressIndeterminate 1.4s ease-in-out infinite;
}
@keyframes progressIndeterminate {
  /* Compositor-only: transform: translateX, not left. Per perf §8 +
     motion §2.8/§2.9. Container is .progress (overflow:hidden). */
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(400%); }
}

/* .toast + .toast-region — non-blocking notification. Region is the
   stacking host (top-right by default). */
.toast-region {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-end;
}
.toast-region--demo {
  position: relative;
  width: 100%;
  align-items: stretch;
}
.toast {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow-md);
  min-width: 240px;
  max-width: 360px;
}
.toast--mint  { border-left-color: var(--mint); }
.toast--amber { border-left-color: var(--amber); }
.toast--rose  { border-left-color: var(--rose); }
.toast__icon {
  color: var(--accent);
  display: inline-flex;
  margin-top: 2px;
  flex: 0 0 auto;
}
.toast--mint  .toast__icon { color: var(--mint-text); }
.toast--amber .toast__icon { color: var(--amber-text); }
.toast--rose  .toast__icon { color: var(--rose-text); }
.toast__body {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1 1 auto;
  min-width: 0;
}
.toast__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  margin: 0;
}
.toast__copy {
  font-size: var(--fs-xs);
  color: var(--muted-strong);
  margin: 0;
  line-height: 1.4;
}
.toast__close {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 2px;
  border-radius: var(--radius-pill);
  flex: 0 0 auto;
}
.toast__close:hover { color: var(--text-strong); }
.toast__close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  color: var(--text-strong);
}

/* .modal — overlay dialog. Built on <dialog>, but the playground
   demo positions it inline so the visual treatment is reviewable
   without opening a real dialog element. */
.modal {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  padding: 0;
  box-shadow: var(--shadow-lg);
  max-width: 440px;
  width: 100%;
}
/* When the same .modal chrome is mounted inside a native <dialog>,
   the element can be opened with .showModal() — focus trap + ESC +
   click-outside come for free. Backdrop styled to match TIDE
   (near-black under dark, cool-white under light). */
dialog.modal {
  margin: auto;
  border: 1px solid var(--line-strong);
}
dialog.modal::backdrop {
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
/* P6 fourth-pass — light theme's cool-white --bg at 85% reads as
   "no scrim" against the white canvas; tilt the scrim toward the
   cobalt-navy family used elsewhere so the dialog actually pops. */
html[data-theme="light"] dialog.modal::backdrop {
  /* Cobalt-tinged dark scrim — the cool-white --bg at 85% reads as
     "no scrim" on white canvas, so we tilt toward the brand cobalt
     family. This is one of the rare component-rule rgba literals
     that's intentional (matched by EXEMPT_DECLARATIONS in the
     discipline test); the value is the cobalt-navy mix endpoint
     that color-mix can't yield from existing tokens. */
  background: rgba(15, 32, 64, 0.32);
}
.modal__head {
  padding: 1rem 1.1rem 0.6rem;
  border-bottom: 1px solid var(--line);
}
.modal__title {
  margin: 0 0 0.2rem;
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--text-strong);
}
.modal__sub {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.modal__body {
  padding: 0.85rem 1.1rem;
  font-size: var(--fs-sm);
  color: var(--text);
  line-height: 1.5;
}
.modal__foot {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
  padding: 0.75rem 1.1rem 0.95rem;
  border-top: 1px solid var(--line);
}

/* Tooltip — duplicate of [data-tooltip] from 20-live.css so the
   playground works without depending on the live bundle. Same selector
   so the rule is idempotent across pages. */
.ds-tooltip-host {
  display: inline-flex;
  gap: 0.5rem;
  align-items: center;
}

/* Playground chrome for state-primitive sections. */
.ds-state-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0.9rem;
}
.ds-state-cell {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 35%, transparent);
}
.ds-state-cell > .section-micro-label {
  margin: 0;
}
.ds-skeleton-stack {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* B.16.4 / UI 4th-pass A+4 — self-driving skeleton demo. The cell
   cycles between skeletons-visible and content-visible to teach
   "this is what the load looks like in motion". Cycle: each of 5
   rows resolves at 4 s intervals (steps at 16% / 32% / 48% / 64%
   / 80% of a 25 s cycle), pauses with all content visible 80→92%,
   resets between 92% and 100%. step-end timing means flips happen
   at single instants — no fade. Reduced-motion: animation paused
   on the first frame, skeletons stay visible. Scope-fenced. */
body[data-page="design-system"] .ds-skeleton-demo {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
body[data-page="design-system"] .ds-skeleton-demo__row {
  /* Skeleton + real-content stack in the same grid cell so they
     occupy identical space; only opacity/visibility toggles between
     them. Without grid stacking they'd flex side-by-side and the
     "complete" flip would shift layout. */
  display: grid;
  grid-template-areas: "stack";
  align-items: center;
  min-height: 1.4rem;
}
body[data-page="design-system"] .ds-skeleton-demo__skel,
body[data-page="design-system"] .ds-skeleton-demo__real {
  grid-area: stack;
  transition: none;
}
body[data-page="design-system"] .ds-skeleton-demo__skel--media {
  /* Wrapper for the media row's two skeleton children (circle +
     line). Internal flex so circle + line sit side-by-side, while
     the wrapper itself stacks in the grid cell with the content. */
  display: flex;
  align-items: center;
  gap: 0.55rem;
}
body[data-page="design-system"] .ds-skeleton-demo__real {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: var(--fs-sm);
  color: var(--text-strong);
  opacity: 0;
  visibility: hidden;
}
body[data-page="design-system"] .ds-skeleton-demo__real--block {
  display: block;
  padding: 0.55rem 0.7rem;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
  border-radius: var(--radius-xs);
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--accent);
}
body[data-page="design-system"] .ds-avatar-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
  flex: 0 0 auto;
}

@media (prefers-reduced-motion: no-preference) {
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="1"] .ds-skeleton-demo__skel { animation: ds-skel-out  25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="2"] .ds-skeleton-demo__skel { animation: ds-skel-out2 25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="3"] .ds-skeleton-demo__skel { animation: ds-skel-out3 25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="4"] .ds-skeleton-demo__skel { animation: ds-skel-out4 25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="5"] .ds-skeleton-demo__skel { animation: ds-skel-out5 25s steps(1, end) infinite both; }

  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="1"] .ds-skeleton-demo__real { animation: ds-real-in  25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="2"] .ds-skeleton-demo__real { animation: ds-real-in2 25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="3"] .ds-skeleton-demo__real { animation: ds-real-in3 25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="4"] .ds-skeleton-demo__real { animation: ds-real-in4 25s steps(1, end) infinite both; }
  body[data-page="design-system"] .ds-skeleton-demo__row[data-step="5"] .ds-skeleton-demo__real { animation: ds-real-in5 25s steps(1, end) infinite both; }
}

/* Skeleton fades out at row's "complete" step (16/32/48/64/80%);
   resets at 92% so the next cycle starts clean. */
@keyframes ds-skel-out  { 0%{opacity:1;visibility:visible} 16%{opacity:0;visibility:hidden} 92%{opacity:1;visibility:visible} 100%{opacity:1;visibility:visible} }
@keyframes ds-skel-out2 { 0%{opacity:1;visibility:visible} 32%{opacity:0;visibility:hidden} 92%{opacity:1;visibility:visible} 100%{opacity:1;visibility:visible} }
@keyframes ds-skel-out3 { 0%{opacity:1;visibility:visible} 48%{opacity:0;visibility:hidden} 92%{opacity:1;visibility:visible} 100%{opacity:1;visibility:visible} }
@keyframes ds-skel-out4 { 0%{opacity:1;visibility:visible} 64%{opacity:0;visibility:hidden} 92%{opacity:1;visibility:visible} 100%{opacity:1;visibility:visible} }
@keyframes ds-skel-out5 { 0%{opacity:1;visibility:visible} 80%{opacity:0;visibility:hidden} 92%{opacity:1;visibility:visible} 100%{opacity:1;visibility:visible} }

/* Real content appears at row's "complete" step; hides at 92% reset. */
@keyframes ds-real-in  { 0%{opacity:0;visibility:hidden} 16%{opacity:1;visibility:visible} 92%{opacity:0;visibility:hidden} 100%{opacity:0;visibility:hidden} }
@keyframes ds-real-in2 { 0%{opacity:0;visibility:hidden} 32%{opacity:1;visibility:visible} 92%{opacity:0;visibility:hidden} 100%{opacity:0;visibility:hidden} }
@keyframes ds-real-in3 { 0%{opacity:0;visibility:hidden} 48%{opacity:1;visibility:visible} 92%{opacity:0;visibility:hidden} 100%{opacity:0;visibility:hidden} }
@keyframes ds-real-in4 { 0%{opacity:0;visibility:hidden} 64%{opacity:1;visibility:visible} 92%{opacity:0;visibility:hidden} 100%{opacity:0;visibility:hidden} }
@keyframes ds-real-in5 { 0%{opacity:0;visibility:hidden} 80%{opacity:1;visibility:visible} 92%{opacity:0;visibility:hidden} 100%{opacity:0;visibility:hidden} }

/* ──────────────────────────────────────────────────────────────────
   Data-density atoms — small reusable bits (delta-chip, spark-inline,
   token-amount-row, meta-line) that data-heavy surfaces compose into
   rows. Globally available; design-system playground demos them.
   ────────────────────────────────────────────────────────────────── */

/* .delta-chip — signed numeric pill (mint up, rose down). The sign
   is visual, not just colour, so it survives colour-blind users. */
.delta-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-full);
  font-size: var(--fs-2xs);
  font-weight: 700;
  font-family: var(--ff-mono);
  letter-spacing: 0.01em;
  border: 1px solid color-mix(in srgb, var(--muted) 18%, transparent);
  background: color-mix(in srgb, var(--muted) 8%, transparent);
  color: var(--muted-strong);
}
/* Tone TEXT uses --tone-text companions (alias to bright tone in
   dark, dark companion in light) so AA contrast holds across themes
   without per-theme rules. Tone FILL stays on bright values. */
.delta-chip--up {
  border-color: color-mix(in srgb, var(--mint) 35%, transparent);
  background: color-mix(in srgb, var(--mint) 14%, transparent);
  color: var(--mint-text);
}
.delta-chip--down {
  border-color: color-mix(in srgb, var(--rose) 35%, transparent);
  background: color-mix(in srgb, var(--rose) 14%, transparent);
  color: var(--rose-text);
}
.delta-chip__arrow {
  font-size: 0.7em;
  line-height: 1;
}

/* .event-chart — Polymarket-style price chart with horizontal level
   lines + vertical event markers. Used for the "decision trail"
   surface where operators see how policy decisions tracked against
   BTC price. SVG markup is emitted by renderEventChart() in app.js. */
.event-chart {
  display: block;
  width: 100%;
  max-width: 100%;
  font-variant-numeric: tabular-nums;
}
.event-chart text { font-feature-settings: "tnum" 1, "zero" 1; }

/* .spark-inline — tiny standalone sparkline. Pure SVG, sized via
   width/height attrs. Tone follows currentColor so the parent row's
   accent flows through. Mostly used inside table rows. */
.spark-inline {
  display: inline-block;
  vertical-align: middle;
  height: 12px;
  width: 48px;
  color: var(--accent);
}
.spark-inline--mint  { color: var(--mint-text); }
.spark-inline--rose  { color: var(--rose-text); }
.spark-inline--amber { color: var(--amber-text); }
.spark-inline--cyan  { color: var(--cyan-text); }
.spark-inline svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}
.spark-inline svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* .token-amount-row — row pattern: token mark + symbol + amount + USD. */
.token-amount-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 35%, transparent);
}
.token-amount-row__sym {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  min-width: 4ch;
}
.token-amount-row__name {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin-left: -0.35rem;
}
.token-amount-row__amount {
  margin-left: auto;
  font-family: var(--ff-mono);
  font-size: var(--fs-sm);
  color: var(--text-strong);
  font-weight: 600;
  text-align: right;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.05rem;
}
.token-amount-row__amount small {
  font-size: var(--fs-2xs);
  color: var(--muted);
  font-weight: 500;
}

/* .meta-line — label · value · timestamp pattern (evidence + receipts). */
.meta-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem 0.7rem;
  font-size: var(--fs-xs);
  line-height: 1.5;
  padding: 0.35rem 0;
  border-bottom: 1px dashed var(--line);
}
.meta-line:last-child { border-bottom: 0; }
.meta-line__label {
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: var(--fs-2xs);
  min-width: 8ch;
}
.meta-line__value {
  color: var(--text-strong);
  font-family: var(--ff-mono);
  word-break: break-all;
}
.meta-line__time {
  margin-left: auto;
  color: var(--muted);
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  white-space: nowrap;
}

/* Playground chrome for data-density section. */
.ds-density-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.9rem;
}
.ds-density-cell {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

/* ──────────────────────────────────────────────────────────────────
   Navigation primitives — breadcrumb, tabs, pagination. Globally
   available; design-system playground demos them.
   ────────────────────────────────────────────────────────────────── */

/* .breadcrumb — back-trail. Use chevron-right between hops. */
.breadcrumb {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.breadcrumb__item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--muted);
}
.breadcrumb__item a,
.breadcrumb__item button {
  color: var(--muted);
  text-decoration: none;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-size: inherit;
  font-weight: 500;
}
.breadcrumb__item a:hover,
.breadcrumb__item button:hover {
  color: var(--text-strong);
}
.breadcrumb__item--current {
  color: var(--text-strong);
  font-weight: 600;
}
.breadcrumb__sep {
  color: color-mix(in srgb, var(--muted) 50%, transparent);
  display: inline-flex;
}
.breadcrumb__sep svg {
  width: 14px;
  height: 14px;
}

/* .tabs — horizontal tab strip. Underline indicator on the active tab.
   Use role="tablist" + role="tab" + aria-selected on the actual nav. */
.tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--line-strong);
  position: relative;
  overflow-x: auto;
  scrollbar-width: thin;
}
.tabs__option {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted-strong);
  padding: 0.55rem 0.85rem;
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  position: relative;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 120ms ease, border-color 120ms ease;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.tabs__option:hover {
  color: var(--text-strong);
}
.tabs__option[aria-selected="true"],
.tabs__option.is-active {
  color: var(--text-strong);
  border-bottom-color: var(--accent);
}
.tabs__option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -4px;
  border-radius: var(--radius-xs);
}
.tabs__option:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.tabs__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  font-size: var(--fs-2xs);
  font-weight: 700;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--muted) 18%, transparent);
  color: var(--muted-strong);
  font-family: var(--ff-mono);
}
.tabs__option[aria-selected="true"] .tabs__count,
.tabs__option.is-active .tabs__count {
  background: var(--accent);
  color: var(--surface);
}

/* .pagination — page-cursor row: prev · 1 · 2 · … · next. */
.pagination {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
.pagination__btn {
  appearance: none;
  border: 1px solid var(--line-strong);
  background: var(--surface-soft);
  color: var(--muted-strong);
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  font-weight: 600;
  font-family: var(--ff-mono);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.pagination__btn:hover {
  background: var(--surface-tint);
  color: var(--text-strong);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line-strong));
}
.pagination__btn[aria-current="page"],
.pagination__btn.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--surface);
}
.pagination__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.pagination__btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.pagination__ellipsis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 32px;
  color: var(--muted);
  font-family: var(--ff-mono);
}

/* Playground chrome for the navigation section. */
.ds-nav-stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.ds-nav-cell {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.ds-nav-cell > .section-micro-label {
  margin: 0;
}

/* ──────────────────────────────────────────────────────────────────
   Failure-surface primitives — empty, error, validation, confirm,
   diff. Operator-grade dashboards spend ~30% of their time showing
   "nothing here yet" / "couldn't load" / "are you sure" / "what
   changed". Cataloguing these in /design-system makes those states
   first-class instead of ad-hoc.
   ────────────────────────────────────────────────────────────────── */

/* .empty-state — "nothing here yet" / "not connected" / "error". */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.55rem;
  padding: 2rem 1.25rem;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-soft) 50%, transparent);
}
.empty-state__icon {
  display: inline-flex;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--muted) 14%, transparent);
  color: var(--muted-strong);
}
.empty-state__title {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--text-strong);
  margin: 0;
  line-height: 1.3;
}
.empty-state__copy {
  font-size: var(--fs-xs);
  color: var(--muted-strong);
  margin: 0;
  max-width: 38ch;
  line-height: 1.55;
}
.empty-state__cta { margin-top: 0.55rem; }
.empty-state--error {
  border-color: color-mix(in srgb, var(--rose) 35%, var(--line-strong));
  background: color-mix(in srgb, var(--rose) 5%, var(--surface-soft));
}
.empty-state--error .empty-state__icon {
  color: var(--rose-text);
  background: color-mix(in srgb, var(--rose) 14%, transparent);
}
.empty-state--warn {
  border-color: color-mix(in srgb, var(--amber) 35%, var(--line-strong));
}
.empty-state--warn .empty-state__icon {
  color: var(--amber-text);
  background: color-mix(in srgb, var(--amber) 14%, transparent);
}
.empty-state--not-connected .empty-state__icon {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

/* .field validation modifiers — pair the existing .field chrome with
   warn/error/valid tones. Inline error message inherits the modifier
   colour via .field__small. */
/* Phase D.28 — DS rule §9.8: no raw bright tones on body content.
   Field state borders previously used raw --amber / --rose / --mint
   (chip-fill tones), which read as loud yellow / red / electric green
   on dark theme. Now use color-mix at 55% over --line-strong so the
   tone reads as a soft "notice" border, matching the .has-collision
   precedent from D.10. */
.field--warn  input, .field--warn  select, .field--warn  textarea {
  border-color: color-mix(in srgb, var(--amber) 55%, var(--line-strong));
  background: color-mix(in srgb, var(--amber) 5%, transparent);
}
.field--warn  small { color: var(--amber-text); }
.field--error input, .field--error select, .field--error textarea {
  border-color: color-mix(in srgb, var(--rose) 55%, var(--line-strong));
  background: color-mix(in srgb, var(--rose) 5%, transparent);
}
.field--error small { color: var(--rose-text); }
.field--valid input, .field--valid select, .field--valid textarea {
  border-color: color-mix(in srgb, var(--mint) 55%, var(--line-strong));
  background: color-mix(in srgb, var(--mint) 5%, transparent);
}
.field--valid small { color: var(--mint-text); }

/* .confirm-banner — "are you sure / this is irreversible" disclosure
   above a primary action. Lives next to a CTA, not inline as a toast. */
.confirm-banner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0.85rem 1rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--rose);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--rose) 5%, var(--surface));
  align-items: center;
}
.confirm-banner__icon {
  display: inline-flex;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--rose) 15%, transparent);
  color: var(--rose-text);
  flex: 0 0 auto;
}
.confirm-banner__copy {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.confirm-banner__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  margin: 0;
}
.confirm-banner__detail {
  font-size: var(--fs-xs);
  color: var(--muted-strong);
  margin: 0;
  line-height: 1.45;
}
.confirm-banner__action { display: inline-flex; gap: 0.4rem; }
.confirm-banner--warn {
  border-left-color: var(--amber);
  background: color-mix(in srgb, var(--amber) 5%, var(--surface));
}
.confirm-banner--warn .confirm-banner__icon {
  background: color-mix(in srgb, var(--amber) 15%, transparent);
  color: var(--amber-text);
}
.confirm-banner--accent {
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 5%, var(--surface));
}
.confirm-banner--accent .confirm-banner__icon {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  color: var(--accent);
}

/* .diff-row — before / arrow / after. Used in policy review surfaces
   ("changing X from Y to Z") and unwind preview. */
.diff-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 0.6rem;
  align-items: center;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 35%, transparent);
}
.diff-row__label {
  font-size: var(--fs-2xs);
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: 0.15rem;
  font-family: var(--ff-mono);
}
.diff-row__before {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--muted) 60%, transparent);
}
.diff-row__after {
  font-family: var(--ff-mono);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  text-align: right;
}
.diff-row__arrow {
  color: var(--muted);
  display: inline-flex;
  align-items: center;
}
.diff-row--up   .diff-row__after { color: var(--mint-text); }
.diff-row--down .diff-row__after { color: var(--rose-text); }
.diff-row--neutral .diff-row__after { color: var(--text-strong); }

/* ──────────────────────────────────────────────────────────────────
   Missing primitives — search-field · kbd · status-timeline ·
   icon-badge · drop-zone · date-field. Filling the operator-grade
   coverage gaps flagged by UX §3 and customer §10.
   ────────────────────────────────────────────────────────────────── */

/* .search-field — input with leading search icon + optional clear */
.search-field {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem 0.4rem 0.55rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  transition: border-color 120ms ease;
  width: 100%;
  max-width: 360px;
}
.search-field:focus-within { border-color: var(--accent); }
.search-field__icon { color: var(--muted); display: inline-flex; flex-shrink: 0; }
.search-field input {
  flex: 1 1 auto;
  background: transparent;
  border: 0;
  outline: 0;
  font-size: var(--fs-sm);
  color: var(--text-strong);
  min-width: 0;
  padding: 0;
}
.search-field input::placeholder { color: var(--muted); }
.search-field__clear {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 2px;
  border-radius: var(--radius-pill);
  color: var(--muted);
  cursor: pointer;
  display: inline-flex;
  flex-shrink: 0;
}
.search-field__clear:hover { color: var(--text-strong); }
.search-field__clear:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* .kbd — keyboard shortcut hint, used inline next to action labels. */
.kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  padding: 0.05rem 0.35rem;
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted-strong);
  background: color-mix(in srgb, var(--muted) 14%, transparent);
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  line-height: 1.2;
  transition: background 80ms ease, border-color 80ms ease, color 80ms ease;
}
/* B.16.3 — A+3 live kbd press flash. JS adds .kbd--pressed for
   220 ms when the operator presses the matching key on the page.
   Scoped to /design-system so the demo stays inside the playground. */
body[data-page="design-system"] .kbd--pressed {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

/* .status-timeline — multi-step progress (signing flow / setup
   wizard). Vertical stepper with done/current/pending/failed states. */
.status-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.status-timeline__step {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  gap: 0.7rem;
  padding: 0.4rem 0;
  position: relative;
}
.status-timeline__step:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 11px;
  top: 28px;
  bottom: -2px;
  width: 2px;
  background: var(--line-strong);
}
.status-timeline__step--done::after  { background: var(--mint); }
.status-timeline__step--current::after { background: var(--accent); }
.status-timeline__step--failed::after { background: var(--rose); }
.status-timeline__dot {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--line-strong);
  background: var(--surface);
  color: var(--muted);
  flex-shrink: 0;
}
.status-timeline__step--done .status-timeline__dot {
  border-color: var(--mint);
  background: var(--mint);
  /* Bright mint fill needs a fixed dark glyph for legibility in both
     themes (--bg in light is near-white → invisible). */
  color: var(--on-tone-text-dark);
}
.status-timeline__step--current .status-timeline__dot {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--surface);
}
.status-timeline__step--failed .status-timeline__dot {
  border-color: var(--rose);
  background: var(--rose);
  color: var(--surface);
}
.status-timeline__copy {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}
.status-timeline__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  line-height: 1.4;
}
.status-timeline__step--done .status-timeline__title,
.status-timeline__step--pending .status-timeline__title {
  font-weight: 600;
  color: var(--muted-strong);
}
.status-timeline__sub {
  font-size: var(--fs-2xs);
  color: var(--muted);
  font-family: var(--ff-mono);
}
.status-timeline__copy .hash-pill {
  width: fit-content;
  max-width: min(100%, 34rem);
  margin-top: 0.12rem;
}

.signing-timeline-panel {
  display: grid;
  gap: var(--space-3);
  border-left-color: var(--accent);
}

.signing-timeline-panel[hidden] {
  display: none;
}

.signing-timeline-panel__steps {
  max-width: 44rem;
}

/* .icon-badge — small tone-coded inline badge with optional icon.
   Lightweight alternative to .signing-state for inline contexts. */
.icon-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  max-width: 100%;
  padding: 0.18rem 0.55rem;
  border-radius: var(--radius-full);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--muted) 10%, transparent);
  color: var(--muted-strong);
  border: 1px solid var(--line-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.icon-badge--mint   { color: var(--mint-text);  background: color-mix(in srgb, var(--mint) 12%, transparent);   border-color: color-mix(in srgb, var(--mint) 35%, var(--line-strong)); }
.icon-badge--amber  { color: var(--amber-text); background: color-mix(in srgb, var(--amber) 12%, transparent);  border-color: color-mix(in srgb, var(--amber) 35%, var(--line-strong)); }
.icon-badge--rose   { color: var(--rose-text);  background: color-mix(in srgb, var(--rose) 12%, transparent);   border-color: color-mix(in srgb, var(--rose) 35%, var(--line-strong)); }
.icon-badge--cyan   { color: var(--cyan-text);   background: color-mix(in srgb, var(--cyan) 12%, transparent);   border-color: color-mix(in srgb, var(--cyan) 35%, var(--line-strong)); }
.icon-badge--violet { color: var(--violet-text); background: color-mix(in srgb, var(--violet) 12%, transparent); border-color: color-mix(in srgb, var(--violet) 35%, var(--line-strong)); }
.icon-badge--accent { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); border-color: color-mix(in srgb, var(--accent) 35%, var(--line-strong)); }

/* .drop-zone — dashed-border drop target (paste-pack / file upload). */
.drop-zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 130px;
  padding: 1.6rem 1.2rem;
  border: 2px dashed var(--line-strong);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-soft) 50%, transparent);
  text-align: center;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}
.drop-zone:hover,
.drop-zone:focus-within,
.drop-zone--dragging {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}
.drop-zone__icon {
  display: inline-flex;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.drop-zone__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
}
.drop-zone__sub {
  font-size: var(--fs-2xs);
  color: var(--muted);
  line-height: 1.5;
}

/* .calendar — custom month-grid date picker. Replaces the native
   browser popup that <input type="date"> opens (system chrome,
   uncasable, ignores our palette). The native popup is shadow-DOM
   in every browser; the only path to TIDE-on-brand picker is a
   custom one. Static demo on /design-system; interactive bindings
   are a follow-up commit when .date-field gets wired to open this
   instead of the native picker. */
.calendar {
  display: inline-flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 0.85rem 0.95rem 0.75rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-md);
  width: 280px;
  max-width: 100%;
}
.calendar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
}
.calendar__title {
  margin: 0;
  font-family: var(--ff-mono);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: 0.02em;
}
.calendar__nav {
  display: inline-flex;
  gap: 0.2rem;
}
.calendar__nav-btn {
  appearance: none;
  border: 1px solid var(--line-strong);
  background: var(--surface-soft);
  color: var(--muted-strong);
  width: 26px;
  height: 26px;
  border-radius: var(--radius-xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.calendar__nav-btn:hover {
  color: var(--text-strong);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line-strong));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-soft));
}
.calendar__nav-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.calendar__weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.15rem;
}
.calendar__weekday {
  text-align: center;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-family: var(--ff-mono);
  padding: 0.25rem 0;
}
.calendar__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.15rem;
}
.calendar__day {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  font-family: var(--ff-mono);
  font-variant-numeric: tabular-nums slashed-zero;
  font-size: var(--fs-xs);
  font-weight: 600;
  height: 30px;
  border-radius: var(--radius-xs);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.calendar__day:hover {
  background: var(--surface-tint);
  color: var(--text-strong);
}
.calendar__day:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.calendar__day--outside {
  color: var(--muted);
  opacity: 0.5;
}
.calendar__day--today {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--line-strong));
  color: var(--text-strong);
}
.calendar__day--selected {
  background: var(--accent);
  color: var(--surface);
  border-color: var(--accent);
}
/* P12 fourth-pass + third-pass S7 — gentle overshoot pop-in on day
   selection. 180 ms cubic-bezier(0.34, 1.56, 0.64, 1) is the Stripe-
   calibre "pick me" animation. Reduced-motion users skip the keyframe
   (the rule below sits inside the prefers-reduced-motion: no-pref
   guard). Scope-fenced to /design-system. */
@media (prefers-reduced-motion: no-preference) {
  body[data-page="design-system"] .calendar__day--selected {
    animation: ds-calendar-pop 180ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
  }
}
@keyframes ds-calendar-pop {
  0%   { transform: scale(0.85); }
  60%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
.calendar__day--selected:hover {
  background: var(--accent-strong);
  color: var(--surface);
}
.calendar__day--in-range {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--text-strong);
  border-radius: 0;
}
.calendar__day--disabled {
  color: var(--muted);
  opacity: 0.35;
  cursor: not-allowed;
  text-decoration: line-through;
}
.calendar__day--disabled:hover {
  background: transparent;
  color: var(--muted);
}
.calendar__foot {
  display: flex;
  justify-content: space-between;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--line);
}
.calendar__foot-btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--accent);
  font-size: var(--fs-xs);
  font-weight: 700;
  cursor: pointer;
  padding: 0.2rem 0.3rem;
  border-radius: var(--radius-xs);
}
.calendar__foot-btn:hover { color: var(--accent-strong); }
.calendar__foot-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* .date-field — wrapper around <input type="date">. Native picker
   stays; our chrome wraps it. */
.date-field {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
}
.date-field:focus-within { border-color: var(--accent); }
.date-field__icon { color: var(--muted); display: inline-flex; flex-shrink: 0; }
.date-field input[type="date"] {
  background: transparent;
  border: 0;
  outline: 0;
  font-family: var(--ff-mono);
  font-size: var(--fs-sm);
  color: var(--text-strong);
  font-variant-numeric: tabular-nums slashed-zero;
  padding: 0;
}
.date-field input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.7;
}

/* ──────────────────────────────────────────────────────────────────
   Crypto attributes — wallet address · tx hash · network badge ·
   block pill · gas pill · signing state · balance pill. The bits
   that mark a screen as "actually on-chain" rather than "generic
   dashboard". All globally available; design-system playground
   demos them.
   ────────────────────────────────────────────────────────────────── */

/* .wallet-address / .tx-hash — monospace hash with copy + explorer.
   Same shape; the modifier just tunes the prefix glyph colour. */
.hash-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.28rem 0.5rem 0.28rem 0.55rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full);
  background: var(--surface-soft);
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--text-strong);
  max-width: 100%;
}
.hash-pill__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex: 0 0 auto;
}
.hash-pill--tx     .hash-pill__dot { background: var(--cyan); }
.hash-pill--object .hash-pill__dot { background: var(--violet); }
/* Walrus blob ids are NOT Sui object ids — different namespace, different
   explorer. Amber dot keeps the storage/persist semantic distinct from
   the violet --object pill. UI 4th-pass V4. */
.hash-pill--walrus .hash-pill__dot { background: var(--amber); }
.hash-pill--signed .hash-pill__dot { background: var(--mint); }
.hash-pill--failed .hash-pill__dot { background: var(--rose); }
.hash-pill__value {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hash-pill__btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 2px;
  border-radius: var(--radius-pill);
  transition: color 120ms ease, background 120ms ease;
}
.hash-pill__btn:hover {
  color: var(--text-strong);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.hash-pill__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
/* Copy success — JS sets data-state="copied" for 1.2s after a
   successful clipboard.writeText. Mint tint + check-glyph overlay
   so users get explicit confirmation without spawning a toast.
   Per third-pass UI+UX+frontend 3/3 consensus on hash-pill feedback. */
.hash-pill__btn[data-state="copied"] {
  color: var(--mint);
  background: color-mix(in srgb, var(--mint) 28%, transparent);
}
.hash-pill__btn[data-state="copied"] svg {
  display: none;
}
.hash-pill__btn[data-state="copied"]::after {
  content: "";
  width: 12px;
  height: 12px;
  /* SVG stroke literal hex matches --mint (#27F5B7); url() bodies
     can't reference CSS variables, so if --mint shifts, update the
     literal here (and the light-theme rule below — %23047857 matches
     --mint-text). UI 4th-pass R3 sync watch. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2327F5B7' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  display: inline-block;
}
html[data-theme="light"] .hash-pill__btn[data-state="copied"] {
  color: var(--mint-text);
  background: color-mix(in srgb, var(--mint-text) 16%, transparent);
}
html[data-theme="light"] .hash-pill__btn[data-state="copied"]::after {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23047857' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
}

/* .network-badge — testnet/mainnet/devnet pill with a status dot
   that pulses on live networks. */
.network-badge {
  --network-dot: var(--muted-strong);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.18rem 0.55rem 0.18rem 0.5rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--line-strong);
  background: var(--surface-soft);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-strong);
  font-family: var(--ff-mono);
}
.network-badge__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--network-dot);
  flex: 0 0 auto;
  box-shadow: 0 0 0 0 var(--network-dot);
  animation: none;
}
.network-badge[data-state="live"] .network-badge__dot {
  animation: networkPulse 2s ease-in-out infinite;
}
.network-badge--testnet { --network-dot: var(--cyan); border-color: color-mix(in srgb, var(--cyan) 35%, var(--line-strong)); }
.network-badge--mainnet { --network-dot: var(--mint);  border-color: color-mix(in srgb, var(--mint)  35%, var(--line-strong)); }
.network-badge--devnet  { --network-dot: var(--violet); border-color: color-mix(in srgb, var(--violet) 35%, var(--line-strong)); }
.network-badge--rpc-down {
  --network-dot: var(--rose);
  border-color: color-mix(in srgb, var(--rose) 35%, var(--line-strong));
}
.network-badge--rpc-down .network-badge__dot { animation: none; }
.network-badge--no-wallet {
  --network-dot: var(--muted-strong);
  border-color: var(--line-strong);
}
.network-badge--no-wallet .network-badge__dot { animation: none; }
@keyframes networkPulse {
  0%   { box-shadow: 0 0 0 0   color-mix(in srgb, var(--network-dot) 60%, transparent); }
  60%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--network-dot) 0%,  transparent); }
  100% { box-shadow: 0 0 0 0   color-mix(in srgb, var(--network-dot) 0%,  transparent); }
}

/* Reduced-motion guard. Operators with vestibular sensitivity get
   continuous motion otherwise — test-engineer + a11y-deep + motion
   reviewers all flagged this as blocking. Disables the four infinite
   keyframes on /design-system primitives without removing them
   (so the visual still renders, just static). */
@media (prefers-reduced-motion: reduce) {
  .spinner,
  .skeleton::after,
  .ui-skeleton__pill::after,
  .ui-skeleton__title::after,
  .ui-skeleton__line::after,
  .ui-skeleton__bar::after,
  .ui-skeleton__card::after,
  .progress--indeterminate::after,
  .network-badge__dot {
    animation: none !important;
  }
  .skeleton,
  .ui-skeleton__pill,
  .ui-skeleton__title,
  .ui-skeleton__line,
  .ui-skeleton__bar,
  .ui-skeleton__card,
  .progress--indeterminate {
    /* Without shimmer / animation, give the placeholder a stronger
       visible state so it still reads as "loading". */
    background: color-mix(in srgb, var(--muted) 22%, transparent);
  }
  /* All transitions tightened to 0.01s so state changes are still
     observable but not animated. */
  .toggle-switch__track,
  .toggle-switch__thumb,
  .segmented__option,
  .select-trigger,
  .tabs__option,
  .pagination__btn,
  .composer__divider button,
  .toast,
  .progress::after,
  .allocation-bar__seg,
  .range-slider input[type="range"],
  .drop-zone,
  .search-field,
  .date-field,
  .ds-toc__chip,
  .kbd {
    transition-duration: 0.01s !important;
    animation-duration: 0.01s !important;
  }
}

/* .crypto-pill — generic small attribute pill (block height, gas, etc.) */
.crypto-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.22rem 0.55rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-xs);
  background: var(--surface-soft);
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted-strong);
}
.crypto-pill strong {
  color: var(--text-strong);
  font-weight: 700;
}
.crypto-pill__icon {
  color: var(--muted);
  display: inline-flex;
}

/* .signing-state — pending/signing/signed/failed indicator. Replaces
   the page-local pre-sign-dialog status copy with a reusable atom. */
.signing-state {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.32rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 65%, transparent);
  font-size: var(--fs-xs);
  color: var(--text-strong);
}
.signing-state__icon {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--accent);
}
/* Lifecycle: pending → signing → signed (signature applied,
   awaiting on-chain) → receipt (proof anchored, terminal happy)
   → failed. UX 4th-pass #28 split signed from receipt — they are
   two different moments and the operator must see both. Tone
   mapping per the manifesto:
     pending = muted    (no decision yet)
     signing = accent   (action firing)
     signed  = cyan     (live in-flight data — awaiting confirmation)
     receipt = mint     (terminal success — proof anchored)
     failed  = rose     (terminal failure) */
.signing-state--pending  { border-left-color: var(--muted);  }
.signing-state--pending  .signing-state__icon { color: var(--muted); }
.signing-state--signing  { border-left-color: var(--accent); }
.signing-state--signing  .signing-state__icon { color: var(--accent); }
.signing-state--signed   { border-left-color: var(--cyan);   }
.signing-state--signed   .signing-state__icon { color: var(--cyan-text); }
.signing-state--receipt  { border-left-color: var(--mint);   }
.signing-state--receipt  .signing-state__icon { color: var(--mint-text); }
.signing-state--failed   { border-left-color: var(--rose);   }
.signing-state--failed   .signing-state__icon { color: var(--rose-text); }

/* .balance-pill — token + amount in a pill (compact wallet readout). */
.balance-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.28rem 0.6rem 0.28rem 0.35rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full);
  background: var(--surface-soft);
}
.balance-pill__amount {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--text-strong);
}
.balance-pill__sym {
  font-size: var(--fs-2xs);
  color: var(--muted);
  letter-spacing: 0.04em;
}

/* ──────────────────────────────────────────────────────────────────
   Composer — input/output orchestrated row (swap-card pattern,
   canonical form). Promotes the page-local .swap-card structure
   into a reusable primitive.
   ────────────────────────────────────────────────────────────────── */

.composer {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
}
.composer__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(140px, auto);
  gap: 0.55rem;
  align-items: center;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
  position: relative;
}
.composer__label {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: var(--fs-2xs);
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
}
.composer__label small {
  text-transform: none;
  letter-spacing: 0;
  font-family: var(--ff-mono);
  color: var(--muted-strong);
}
.composer__amount {
  appearance: none;
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--text-strong);
  font-family: "Sora", "Manrope", system-ui, sans-serif;
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: -0.025em;
  padding: 0;
  outline: none;
}
.composer__amount::-webkit-outer-spin-button,
.composer__amount::-webkit-inner-spin-button { appearance: none; margin: 0; }
.composer__amount[type="number"] { -moz-appearance: textfield; }
.composer__usd {
  grid-column: 1 / 2;
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
}
.composer__divider {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  height: 1px;
  margin: 0.15rem 0;
}
.composer__divider::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: var(--line);
}
.composer__divider button {
  appearance: none;
  position: relative;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--accent);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 200ms ease, color 120ms ease;
}
.composer__divider button:hover {
  color: var(--text-strong);
  transform: rotate(180deg);
}
.composer__summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.25rem 0.75rem;
  padding: 0.5rem 0.55rem 0;
  font-size: var(--fs-2xs);
  font-family: var(--ff-mono);
}
.composer__summary dt { color: var(--muted); }
.composer__summary dd { margin: 0; color: var(--text-strong); text-align: right; }
.composer__cta {
  margin-top: 0.55rem;
}

/* ──────────────────────────────────────────────────────────────────
   Transactions — canonical .tx-row and .tx-receipt-card (large mint
   summary card).
   ────────────────────────────────────────────────────────────────── */

.tx-receipt-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.65rem 1rem;
  padding: 0.95rem 1.1rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--accent) 8%, var(--surface)) 0%,
    var(--surface) 100%
  );
  position: relative;
}
.tx-receipt-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
}
.tx-receipt-card__head {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
}
.tx-receipt-card__title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--text-strong);
  margin: 0;
}
.tx-receipt-card__title-icon {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--mint) 18%, transparent);
  color: var(--mint);
  flex: 0 0 auto;
}
.tx-receipt-card__amount {
  font-family: "Sora", "Manrope", system-ui, sans-serif;
  font-size: var(--fs-display);
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--text-strong);
  line-height: 1;
}
.tx-receipt-card__usd {
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  color: var(--muted);
  align-self: flex-end;
}
.tx-receipt-card__meta {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
  padding-top: 0.55rem;
  border-top: 1px dashed var(--line);
}

/* Playground chrome for the new sections. */
.ds-crypto-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.9rem;
}
.ds-crypto-cell {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.ds-crypto-cell > .section-micro-label {
  margin: 0;
}
/* .allocation-bar — horizontal stacked bar (collateral / debt /
   buffer split). Tone-coded segments + legend underneath. */
.allocation-bar {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.allocation-bar__track {
  display: flex;
  width: 100%;
  height: 14px;
  border-radius: var(--radius-full);
  overflow: hidden;
  background: color-mix(in srgb, var(--muted) 15%, transparent);
  border: 1px solid var(--line);
}
.allocation-bar__seg {
  height: 100%;
  transition: width 240ms ease;
}
.allocation-bar__seg--accent { background: var(--accent); }
.allocation-bar__seg--mint   { background: var(--mint); }
.allocation-bar__seg--amber  { background: var(--amber); }
.allocation-bar__seg--rose   { background: var(--rose); }
.allocation-bar__seg--cyan   { background: var(--cyan); }
.allocation-bar__seg--violet { background: var(--violet); }
.allocation-bar__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.1rem;
  font-size: var(--fs-xs);
}
.allocation-bar__legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--muted-strong);
  font-family: var(--ff-mono);
}
.allocation-bar__legend-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  flex: 0 0 auto;
}
.allocation-bar__legend-item strong {
  color: var(--text-strong);
  font-weight: 700;
}

.page-tools {
  display: grid;
  justify-items: end;
  gap: var(--space-2);
  align-self: center;
}

.page-heading {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
  flex: 1;
}

.eyebrow, .section-label, .micro-label, .metric-card span, .note-card span, .saved-card-meta span, .route-score {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 800;
}

h1, h2, h3, strong {
  color: var(--text-strong);
}

h1, h2 {
  margin: 0;
  font-family: "Sora", "Manrope", sans-serif;
}

h1 {
  max-width: none;
  font-size: clamp(1rem, 1.15vw, 1.2rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}

h2 {
  font-size: clamp(0.92rem, 1.05vw, 1.12rem);
  line-height: 1.15;
  letter-spacing: -0.03em;
}

.page-copy, .surface-copy, .note-card p, .metric-card p, .saved-card p, .status-line, .empty-copy, .empty-panel p, .route-card p, .log-card p {
  color: var(--muted);
  line-height: 1.65;
}

.page-copy {
  max-width: 62ch;
  margin: 0.2rem 0 0;
  font-size: var(--fs-base);
  line-height: 1.4;
}

.status-line {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.5;
  max-width: 50ch;
}

.status-line.is-error {
  /* Phase D.32 — body-text contrast (§9.8). var(--rose) is the bright
     graphic tone; var(--rose-text) is the readable companion that
     clears AA on every surface variant. */
  color: var(--rose-text);
}

/* Trust labels — safety-posture pill row. Phase C.0a: rewritten
   onto design tokens so the strip lives inside the same colour
   system as everything else. Tone-semantic mapping per the
   manifesto:
     --shadow   = operating posture           → muted (neutral)
     --testnet  = live network                → cyan (live data)
     --safe     = safety promise (positive)   → mint (healthy)
     --readonly = constraint / discipline     → accent (info/posture)
   readonly was rose previously, which mis-cued "danger / liquidation"
   when the actual semantic is "we deliberately don't do this" — a
   discipline statement, not an emergency. accent (cobalt) is the
   right tier per the manifesto. */
.trust-labels {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.25rem;
}

.trust-labels[hidden] { display: none; }

.trust-labels.trust-strip {
  margin: 0;
  padding: 0.45rem 1.1rem;
  justify-content: flex-start;
  align-items: center;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface) 60%, transparent);
}

/* Phase D.10 → D.32 rewrite — `.trust-strip--in-header` lives INSIDE
   the `.page-header` card and visually fills the bottom row. The prior
   implementation used `margin: 0.7rem -1.55rem -0.9rem` to break out
   horizontally and pull up to align with the parent's padding-bottom
   of 0.9rem (then-current value). When D.28 changed `.page-header`
   padding to symmetric 1.4rem, AND `.page-header-compact` overrode
   padding-bottom to 0.1rem, the negative-bottom-margin alignment
   broke — on /setup, /results, /live, /library the trust-strip's
   visible bottom edge fell BELOW the card border, rendering the
   condensed chip as an orphan element on bare bg between two surfaces.
   Rewrite: page-header gets padding-bottom 0 when a trust-strip is
   inside it (the strip's own padding becomes the card's bottom
   padding). Trust-strip has 0 margin-bottom; horizontal -1.55rem
   negative margins still extend to the card border. Result: the
   trust-strip becomes the genuine bottom row of the card on all
   page-header variants regardless of compact/non-compact. */
.page-header:has(.trust-strip--in-header) {
  padding-bottom: 0;
}
.page-header-compact:has(.trust-strip--in-header) {
  padding-bottom: 0;
}
.trust-labels.trust-strip--in-header {
  width: 100%;
  flex: 1 0 100%;
  min-height: 3.25rem;
  margin: 0.7rem calc(var(--page-header-x) * -1) 0;
  padding: 0.7rem var(--page-header-x);
  border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  border-bottom: 0;
  border-bottom-left-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-soft) 50%, transparent);
}

.trust-labels.trust-strip--in-header:empty {
  display: none;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
/* When trust-strip is in-header, suppress the brand hairline below
   it so we don't double-stamp horizontal lines at the card foot. */
.page-header:has(.trust-strip--in-header)::after {
  display: none;
}

.trust-label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.22rem 0.65rem;
  border-radius: var(--radius-full);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.2;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--muted-strong);
}

.trust-label--shadow {
  border-color: var(--line-strong);
  color: var(--muted-strong);
}

/* Phase D.32 — trust-label text is persistent body-scale chrome
   (0.68rem) that was using raw bright tones (--cyan / --mint) on the
   dark theme. Per §9.8 body text uses the readable -text companions.
   Was: dark-theme uses raw bright + light-theme overrides to -text.
   Now: -text companions on both themes, removing the override block. */
.trust-label--testnet {
  border-color: color-mix(in srgb, var(--cyan) 40%, var(--line-strong));
  background: color-mix(in srgb, var(--cyan) 10%, transparent);
  color: var(--cyan-text);
}

.trust-label--safe {
  border-color: color-mix(in srgb, var(--mint) 40%, var(--line-strong));
  background: color-mix(in srgb, var(--mint) 10%, transparent);
  color: var(--mint-text);
}

.trust-label--readonly {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line-strong));
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
}

.proof-timeline .status-timeline {
  list-style: none;
  margin: 0.6rem 0 0.5rem;
  padding: 0;
}

.proof-timeline__actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.proof-timeline[data-state="receipt-pending"]::before {
  background: color-mix(in srgb, var(--amber) 72%, transparent);
}

.proof-timeline--pending .status-timeline__step--pending .status-timeline__dot {
  background: transparent;
  color: var(--muted);
  border-color: var(--line-strong);
}

.status-timeline__links {
  font-size: var(--fs-xs);
  opacity: 0.85;
}

.status-timeline__links a {
  color: var(--accent);
}

.proof-digests {
  font-family: var(--font-mono, monospace);
  font-size: var(--fs-sm);
  word-break: break-all;
  color: var(--muted);
  margin-top: 0.3rem;
}

.proof-digests code {
  background: transparent;
  color: var(--text-strong);
  padding: 0;
}

.pre-sign-dialog {
  max-width: 32rem;
  width: calc(100vw - 2rem);
  max-height: min(44rem, calc(100dvh - 2rem));
  overflow: hidden;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
}

.pre-sign-dialog::backdrop {
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  backdrop-filter: blur(4px);
}

.pre-sign-form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  max-height: inherit;
  overflow: auto;
  padding: 1.2rem 1.2rem 1rem;
}

.pre-sign-head h3 {
  margin: 0 0 0.25rem;
  font-size: var(--fs-md);
  font-weight: 700;
}

.pre-sign-head .pre-sign-subtitle {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--muted);
}

.pre-sign-body {
  margin: 0;
  font-size: var(--fs-base);
  line-height: 1.45;
  color: var(--text);
}

.pre-sign-section-label {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.3rem;
}

.pre-sign-calls {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.pre-sign-calls li {
  padding: 0.35rem 0.55rem;
  border-radius: var(--radius-xs);
  border: 1px solid color-mix(in srgb, var(--cyan) 32%, var(--line-strong));
  background: color-mix(in srgb, var(--cyan) 8%, transparent);
}

.pre-sign-calls code {
  font-family: var(--font-mono, monospace);
  font-size: var(--fs-sm);
  word-break: break-all;
  background: transparent;
  padding: 0;
}

.pre-sign-fields {
  display: grid;
  grid-template-columns: minmax(9rem, auto) 1fr;
  gap: 0.3rem 0.8rem;
  margin: 0;
  font-size: var(--fs-base);
}

.pre-sign-fields dt {
  color: var(--muted);
  font-weight: 500;
}

.pre-sign-fields dd {
  margin: 0;
  font-family: var(--ff-mono);
  font-size: var(--fs-sm);
  word-break: break-all;
  color: var(--text);
}

.pre-sign-advanced {
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--surface) 78%, transparent);
  padding: 0.65rem 0.75rem;
}

.pre-sign-advanced[hidden] {
  display: none;
}

.pre-sign-advanced summary {
  cursor: pointer;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 650;
}

.pre-sign-advanced summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

.pre-sign-advanced-calls {
  margin-top: 0.75rem;
}

.pre-sign-fields--advanced {
  margin-top: 0.75rem;
}

.pre-sign-warning {
  margin: 0;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-xs);
  /* UX3: was hardcoded amber-yellow rgba from pre-lift palette; now
     tracks --amber + --amber-text. text companion ensures AA on
     light theme white. */
  border: 1px solid color-mix(in srgb, var(--amber) 35%, var(--line-strong));
  background: var(--amber-soft);
  color: var(--amber-text);
  font-size: var(--fs-sm);
}

.pre-sign-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.3rem;
  position: sticky;
  bottom: -1rem;
  padding-top: 0.5rem;
  padding-bottom: 0.2rem;
  background: var(--surface);
}

.action-cluster {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  min-width: 0;
}

.action-disabled-hint {
  flex-basis: 100%;
  max-width: 34rem;
  margin: -0.25rem 0 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.35;
}

.page-header--product .action-disabled-hint {
  margin-left: auto;
  text-align: right;
}

.workspace-actions {
  margin-top: 0.8rem;
}

.action-cluster-compact .button {
  min-width: 5.5rem;
  min-height: 2.2rem;
  padding-inline: 0.85rem;
  font-size: var(--fs-sm);
  white-space: normal;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 2.75rem;
  padding: 0 1rem;
  border: 0;
  border-radius: var(--radius-xs);
  font-size: var(--fs-base);
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
  transition:
    border-color 150ms ease,
    background-color 150ms ease,
    color 150ms ease,
    transform 100ms ease;
}

.button:active {
  transform: scale(0.97);
}

/* Phase C.1.fix — UX2: --accent (#2E7BFF dark / #1C60CF light) with
   white text was borderline AA in dark; --accent-strong is the safe
   choice and clears AAA. Hover lifts back to --accent for visible
   feedback. (Inverted from prior global rule; the /design-system
   scoped fix is now redundant and will be removed.) */
.button-primary {
  background: var(--accent-strong);
  color: var(--on-accent-text);
  border: 0;
}

.button-primary:hover {
  background: var(--accent);
}

.button-secondary {
  background: var(--surface-strong);
  color: var(--text-strong);
  border: 1px solid var(--line);
}

.button-secondary:hover {
  background: var(--surface-tint);
  border-color: var(--line-strong);
}

.button-danger {
  /* C.4 — was hardcoded Tailwind red (#dc2626 / #b91c1c). Tracks
     the lifted --rose tone family. Hover tone-strong via mix. */
  background: var(--rose);
  color: var(--surface);
  border: 0;
}

.button-danger:hover {
  background: color-mix(in srgb, var(--rose) 85%, #000);
}

.button-ghost {
  background: transparent;
  color: var(--muted-strong);
}

.button-ghost:hover {
  background: var(--surface-soft);
}

.button-ghost.is-danger {
  color: var(--rose-text);
}

.button.is-saved {
  color: var(--mint);
  background: color-mix(in srgb, var(--mint) 14%, transparent);
  border-color: color-mix(in srgb, var(--mint) 40%, transparent);
}

.button.is-error {
  color: var(--rose);
  background: color-mix(in srgb, var(--rose) 14%, transparent);
  border-color: color-mix(in srgb, var(--rose) 40%, transparent);
}

.button.is-pending {
  color: var(--muted-strong);
  background: color-mix(in srgb, var(--line) 20%, transparent);
}

.page-stack {
  display: grid;
  /* Phase D.33 (UI G-13) — was 0.9rem fixed; clamp gives a tighter
     rhythm at narrow viewports while preserving breathing room at wide. */
  gap: clamp(0.65rem, 0.8vw, 0.85rem);
  min-width: 0;
}

.page-stack > *,
.surface,
.surface-hero {
  min-width: 0;
  max-width: 100%;
}

.content-grid {
  display: grid;
  gap: 1rem;
  align-items: start;
}

.content-grid-main {
  grid-template-columns: minmax(0, 1.1fr) minmax(280px, 0.9fr);
}

body[data-page="results"] .content-grid-main {
  grid-template-columns: minmax(0, 1.02fr) minmax(320px, 0.98fr);
}

/* C.2.1 L6 — /library two-col grid stacks below 720 px so neither
   column squeezes against its 280 px floor with no escape valve. */
@media (max-width: 720px) {
  body[data-page="library"] .content-grid-main {
    grid-template-columns: 1fr;
  }
}

/* Phase D.15 — Library asymmetric workbench grid: saved-runs is P1
   (3fr inventory column), compare is P2 (2fr auxiliary tool that
   only activates after picking two runs). The equal-weight 50/50
   .content-grid-main flattened the priority. .library-grid encodes
   the asymmetry as a named primitive instead of mutating the
   shared .content-grid-main utility. */
.library-grid {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(280px, 2fr);
  gap: 1rem;
  align-items: start;
}
.library-grid__aside {
  position: sticky;
  top: 1rem;
}
@media (max-width: 920px) {
  .library-grid {
    grid-template-columns: 1fr;
  }
  .library-grid__aside {
    position: static;
  }
}

.surface {
  position: relative;
  z-index: 1;
  padding: 1.1rem 1.15rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface);

  transition: border-color 200ms ease, box-shadow 200ms ease;
}

/* Phase D.11 — surface tone-down modifier. Same chrome as .surface
   but stepped down to surface-soft bg + line border (one tier softer)
   so the operator reads "this is supplemental / P3 context, not the
   primary surface in this column". Used for leaderboards, footnote
   archives, and aside contexts that need to remain visible but yield
   visual priority to neighbors. */
.surface.surface--soft {
  background: var(--surface-soft);
  border-color: var(--line);
}

/* ──────────────────────────────────────────────────────────────────
   READOUT page — unified Results + Live surface
   ──────────────────────────────────────────────────────────────────
   Each section gets its OWN named layout (per Create's pattern). No
   generic .grid-60-40 utility; every block invents the rhythm its
   content needs. Status strip is a flex row, position hero is a
   60/40 grid, action ribbon is full-width slim, autopilot ledger
   is a horizontal scroll rail, route+execute is a 50/25/25 grid,
   position details is a 40/60 grid.
*/

/* Status strip — slim row at the top of Readout. Mode chip · scenario
   name · run meta · trust posture · rail name. Reads like a Bloomberg
   ticker line: dense, single-row, scannable. */
.readout-status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.05rem 0.1rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-size: var(--fs-xs);
}
.readout-status-name {
  font-weight: 700;
  color: var(--text-strong);
}
.readout-status-meta {
  color: var(--muted);
}
.readout-status-spacer {
  flex: 1 1 auto;
}
.readout-status-rail {
  font-weight: 700;
  color: var(--muted-strong);
  font-size: var(--fs-xs);
}

/* Position hero — 60 / 40 asymmetric grid. Charts pair on the left,
   KPI tiles on the right. Verdict line sits above both as a single-
   line headline. */
.readout-hero {
  /* Phase D.33 (UI G-24) — was 0.85rem 1rem 0.95rem (asymmetric off-grid).
     Aligned to spacing scale; symmetric vertical so the section reads
     balanced when collapsed at narrow viewports. */
  padding: var(--space-3) var(--space-4) var(--space-4);
  min-width: 0;
}
.readout-hero-verdict {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.7rem;
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  line-height: 1.4;
}
.readout-hero-verdict__dot {
  /* Phase D.33 (UI G-22) — was 0.6rem (matches --fs-2xs by accident
     but is not on the spacing scale). var(--space-2) = 0.5rem (8px),
     the canonical small-decorative size. */
  width: var(--space-2);
  height: var(--space-2);
  border-radius: 50%;
  background: var(--mint);
  flex: 0 0 auto;
}
.readout-hero-verdict--warn .readout-hero-verdict__dot { background: var(--amber); }
.readout-hero-verdict--danger .readout-hero-verdict__dot { background: var(--rose); }
.readout-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 1fr);
  gap: 1rem;
  align-items: start;
  min-width: 0;
}
.readout-hero-charts {
  min-width: 0;
}
.readout-hero-kpis {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.55rem;
  align-content: start;
  min-width: 0;
}
@media (max-width: 980px) {
  .readout-hero-grid {
    grid-template-columns: 1fr;
  }
}

/* Action ribbon — verdict copy + bullets + CTAs in a slim full-width
   strip. Tone-coloured left border by verdict tone. */
.readout-action {
  padding: 0;
  border: 0;
  background: transparent;
}
.readout-action-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1rem;
  align-items: center;
  padding: 0.72rem 0.9rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  border-left: 4px solid var(--mint);
  background: color-mix(in srgb, var(--surface-soft) 42%, transparent);
  min-width: 0;
  max-width: 100%;
}
.readout-action-card--blocked,
.readout-action-card--danger {
  border-left-color: var(--rose);
}
.readout-action-card--review,
.readout-action-card--warn,
.readout-action-card--amber {
  border-left-color: var(--amber);
}
.readout-action-card--compact {
  grid-template-columns: minmax(0, 1fr) auto;
  padding: 0.58rem 0.72rem;
  border-left-width: 1px;
  background: color-mix(in srgb, var(--amber-soft) 34%, transparent);
}
.readout-action-copy {
  display: grid;
  gap: 0.4rem;
  min-width: 0;
}
.readout-action-copy h2 {
  margin: 0;
  font-size: clamp(1rem, 1.6vw, 1.25rem);
}
.readout-action-line {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.65rem;
  align-items: baseline;
  margin: 0;
  color: var(--muted);
}
.readout-action-line strong {
  color: var(--text-strong);
  font-size: var(--fs-md);
}
.readout-action-cta {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex: 0 0 auto;
}
.readout-action-proof {
  margin-top: 0.6rem;
}
/* Phase D.8 — readout-action-footnotes is now a <details> disclosure
   so the three P3 paragraphs (model drag / fee preview / policy
   object status) don't visually compete with the verdict bullets
   above. Default: collapsed, summary line only. Open: expanded with
   muted footnote copy. */
.readout-action-footnotes {
  display: block;
  margin-top: 0.6rem;
  font-size: var(--fs-xs);
  color: var(--muted);
}
.readout-action-footnotes > summary {
  list-style: none;
  cursor: pointer;
  min-height: 2.75rem;
  padding: 0.35rem 0;
  display: flex;
  align-items: center;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted-strong);
  user-select: none;
}
.readout-action-footnotes > summary::-webkit-details-marker { display: none; }
.readout-action-footnotes > summary::before {
  content: "▸ ";
  display: inline-block;
  width: 1.1em;
  transition: transform 120ms ease;
}
.readout-action-footnotes[open] > summary::before {
  content: "▾ ";
}
.readout-action-footnotes[open] {
  display: grid;
  gap: 0.3rem;
  padding: 0.4rem 0.6rem 0.6rem;
  border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--surface-soft) 70%, transparent);
}
.readout-action-footnotes .section-footnote {
  margin: 0;
  font-size: var(--fs-xs);
  line-height: 1.45;
  color: var(--muted);
}
@media (max-width: 760px) {
  .readout-action-card {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .readout-action-cta {
    flex-direction: row;
    flex-wrap: wrap;
    min-width: 0;
  }
  .readout-action-cta .button,
  .readout-action-cta button,
  .readout-action-cta a {
    min-width: 0;
    max-width: 100%;
  }
}

/* Activity ledger — vertical TX-feed style. Each row reads like a
   wallet transaction line: time · kind chip · action title + detail
   · external link with short hash. Monospace numerics, dashed
   dividers between rows. Replaces the horizontal scroll-card rail —
   transaction feeds are vertical lists in every wallet UI an operator
   has muscle memory for. */
.readout-autopilot {
  padding: 0.65rem 0.85rem 0.75rem;
}
.activity-ledger-head-actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.activity-ledger-controls {
  display: inline-flex;
  align-items: center;
}
.activity-ledger-filter .segmented__option {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.activity-ledger-filter__count {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
}
.activity-ledger-filter .segmented__option[aria-pressed="true"] .activity-ledger-filter__count {
  color: var(--text-strong);
}
/* Canonical name: .tx-feed / .tx-row* per feedback_autopilot_language.md
   memory ("no Autopilot language until mainnet exec ships"). */
.tx-feed {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  column-gap: 1.5rem;
}
.tx-feed--mini {
  margin-top: var(--space-2);
}
@media (min-width: 1080px) {
  .readout-autopilot .tx-feed {
    grid-template-columns: 1fr 1fr;
  }
  .readout-autopilot .tx-feed > .tx-row:nth-child(2) {
    border-top: none;
    padding-top: 0.3rem;
  }
}
.tx-row {
  display: grid;
  grid-template-columns: 5.5rem auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.85rem;
  padding: 0.5rem 0;
  border-top: 1px dashed color-mix(in srgb, var(--line) 70%, transparent);
  font-variant-numeric: tabular-nums;
}
.tx-row:first-child {
  border-top: none;
  padding-top: 0.3rem;
}
.tx-row__time {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
  white-space: nowrap;
}
.tx-row__kind {
  display: inline-flex;
  align-items: center;
  padding: 0.12rem 0.5rem;
  border-radius: var(--radius-full);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  background: color-mix(in srgb, var(--surface-strong) 80%, transparent);
  color: var(--muted-strong);
}
.tx-row__kind--receipt {
  color: var(--mint);
  background: color-mix(in srgb, var(--mint) 14%, transparent);
}
.tx-row__kind--wallet {
  color: var(--cyan);
  background: color-mix(in srgb, var(--cyan) 14%, transparent);
}
.tx-row__kind--control {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.tx-row__kind--pause {
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 14%, transparent);
}
.tx-row__kind--danger {
  color: var(--rose);
  background: color-mix(in srgb, var(--rose) 14%, transparent);
}
.tx-row__body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}
.tx-row__body strong {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--text-strong);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tx-row__body span {
  font-size: var(--fs-2xs);
  color: var(--muted);
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tx-row__link {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.tx-row__link:hover {
  text-decoration: underline;
}
.tx-row__link--hash {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  white-space: normal;
}
.tx-row__link--hash:hover {
  text-decoration: none;
}
.tx-row__link--hash > a {
  color: var(--accent);
  text-decoration: none;
}
.tx-row__link--hash > a:hover {
  text-decoration: underline;
}
.tx-row__link--quiet {
  color: var(--muted);
  font-weight: 400;
  cursor: default;
}
.tx-row__link--quiet:hover {
  text-decoration: none;
}
@media (max-width: 720px) {
  .tx-row {
    grid-template-columns: 5rem auto;
    grid-template-rows: auto auto;
    row-gap: 0.25rem;
  }
  .tx-row__body {
    grid-column: 1 / -1;
  }
  .tx-row__link {
    grid-column: 1 / -1;
    justify-self: start;
  }
}

/* Credibility row — Stress ladder (left) + Decision engine (right).
   3:2 split because the stress card grid is denser content; engine
   block is a small chip ladder + decision text. The previous layout
   tried to pair Route + Execute in a 50/25/25 grid, which left an
   ugly empty third column and a tall Live readout sausaging next to
   a short rail card stack — that grid is gone, route + execute now
   stack full-width vertically below this credibility row. */
.readout-credibility {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: 0.6rem;
  align-items: start;
}
@media (max-width: 1080px) {
  .readout-credibility {
    grid-template-columns: 1fr;
  }
}

/* Position details — 40 / 60 grid. Pressure points (warn cards,
   shorter list) on the left; Operator review (longer checklist) on
   the right. Two surfaces side-by-side instead of two stacked
   full-width sections. */
.readout-position-details {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  /* Phase D.33 (UI G-17) — was 0.6rem (off-grid). var(--space-3) = 12px on-grid. */
  gap: var(--space-3);
  /* Phase D.32 — was align-items: start, which let the two columns
     have unequal heights when one card had more content (Pressure
     points ~1500px vs Operator gate ~1640px on /results). align-items:
     stretch makes both cards fill the row height so they read as a
     balanced 2-col block, not a stair-step. */
  align-items: stretch;
}
@media (max-width: 920px) {
  .readout-position-details {
    grid-template-columns: 1fr;
  }
}

/* Trust banner — auto-promoted top-of-page warning on Live when a
   P1 trust condition is failing (unsigned feed, no rail pack, no run).
   In the healthy state the host section stays `hidden`; this rule
   lights it up only when the renderer added the modifier classes. */
.trust-banner {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--line-strong);
}
.trust-banner__copy {
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
  flex: 1 1 auto;
  min-width: 0;
}
.trust-banner__copy strong {
  color: var(--text-strong);
  font-size: var(--fs-md);
  line-height: 1.25;
}
.trust-banner__copy span {
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.45;
}
.trust-banner--warn {
  border-color: color-mix(in srgb, var(--amber) 55%, var(--line-strong));
  background: color-mix(in srgb, var(--amber) 8%, var(--surface));
}
.trust-banner--warn .section-label { color: var(--amber-text); }
.trust-banner--danger {
  border-color: color-mix(in srgb, var(--rose) 55%, var(--line-strong));
  background: color-mix(in srgb, var(--rose) 8%, var(--surface));
}
.trust-banner--danger .section-label { color: var(--rose-text); }
.trust-banner--neutral {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line-strong));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}
.trust-banner--neutral .section-label { color: var(--accent); }

/* Pressure-points "show more" — progressive disclosure inside the
   primary-flow surface so promoting the panel out of Evidence
   doesn't pay the full layout cost on every Readout first paint. */
.press-points-more {
  margin-top: 0.4rem;
}
.press-points-more > summary {
  cursor: pointer;
  list-style: none;
  min-height: 2.75rem;
  padding: 0.45rem 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  border: 1px dashed color-mix(in srgb, var(--line-strong) 70%, transparent);
  background: color-mix(in srgb, var(--surface-soft) 40%, transparent);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.02em;
  text-align: center;
}
.press-points-more > summary::-webkit-details-marker { display: none; }
.press-points-more[open] > summary {
  margin-bottom: 0.4rem;
  border-style: solid;
  color: var(--text-strong);
}
.press-points-more > summary:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--line-strong));
  color: var(--accent);
}

/* Collapsible evidence group — used on Results + Live pages to hide
   developer / provenance sections by default and keep the primary
   flow visible. Styled to echo a normal surface so the accordion
   feels part of the rhythm, not a separate control. */
.surface-evidence {
  position: relative;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  overflow: clip;
}
.surface-evidence[open] {
  background: var(--surface);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line-strong));
}
.surface-evidence__summary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.85rem 1.1rem;
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-sm);
  color: var(--muted);
  transition: background-color 160ms ease, color 160ms ease;
}
.surface-evidence__summary::-webkit-details-marker { display: none; }
.surface-evidence__summary::before {
  content: "";
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  margin-right: 0.1rem;
  transition: transform 180ms ease;
}
.surface-evidence[open] > .surface-evidence__summary::before {
  transform: rotate(45deg);
}
.surface-evidence__summary:hover {
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  color: var(--text-strong);
}
.surface-evidence__summary .section-label {
  color: var(--accent);
  flex: 0 0 auto;
}
.surface-evidence__summary strong {
  color: var(--text-strong);
  font-weight: 600;
  flex: 1 1 auto;
  min-width: 0;
}
.surface-evidence__hint {
  font-size: var(--fs-xs);
  color: var(--muted);
  flex: 0 0 auto;
}
.surface-evidence__body {
  display: grid;
  gap: 0.55rem;
  padding: 0.55rem 0.55rem 0.75rem;
}
.surface-evidence__body .surface {
  background: color-mix(in srgb, var(--surface) 85%, transparent);
}

/* Readout's Live position center — built as a route-card to mirror
   the Diagnostics card on the right of Results. Each metric carries
   a tiny visualisation (pip-dots / mini gauge / horizontal bar) so
   the column reads as data, not prose. */

.route-card--readout {
  border: 0;
  padding: 0;
  background: transparent;
}
.route-card--readout .route-role {
  background: color-mix(in srgb, var(--cyan) 18%, transparent);
  color: var(--cyan);
}

/* Monitor variant — same shape as the Live readout route-card on
   Results, tinted with the accent (mint) so an operator scanning
   the Live page can tell at a glance which surface they're on. */
.route-card--monitor {
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--line-strong));
}
.route-card--monitor .route-role {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}

/* 4 px tonal left edge on the primary / backup route cards rendered
   by renderRouteCard() — primary = mint, backup = amber. Mirrors
   Workspace's policy/saved card accent grammar so the route panel
   reads as part of the same design family rather than two undifferenti­
   ated cards. The padding stays balanced because the inner head/title
   already sit inside the .route-card padding box. */
.route-card-primary {
  border-left: 4px solid color-mix(in srgb, var(--mint) 80%, var(--line-strong));
}
.route-card-backup {
  border-left: 4px solid color-mix(in srgb, var(--amber) 75%, var(--line-strong));
}

/* Tone variants for .route-score (the small chip on the right of
   .route-card-meta). Used by the Monitor card to color the operator
   status label without inventing a new component. */
.route-score--ok {
  color: var(--mint);
  background: color-mix(in srgb, var(--mint) 12%, transparent);
}
.route-score--warn {
  color: var(--amber);
  background: color-mix(in srgb, var(--amber) 14%, transparent);
}
.route-score--danger {
  color: var(--rose);
  background: color-mix(in srgb, var(--rose) 14%, transparent);
}
.route-card-meta-hint {
  font-size: var(--fs-xs);
  color: var(--muted);
}
.route-card-meta-hint a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dashed color-mix(in srgb, var(--muted) 50%, transparent);
}
.route-card-meta-hint a:hover {
  color: var(--accent);
}

.live-position-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-3) var(--space-4);
  padding: var(--space-3) 0 0;
  border-top: 1px dashed var(--line);
  background: transparent;
}

.live-boundary-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px dashed var(--line);
}

.live-boundary-card {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
}

.live-boundary-card__head {
  display: grid;
  gap: var(--space-1);
}

.live-boundary-card__head span,
.live-boundary-facts span {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.live-boundary-card__head strong {
  color: var(--text-strong);
  font-size: var(--fs-md);
}

.live-boundary-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}

.live-boundary-facts div {
  display: grid;
  gap: 0.28rem;
  min-width: 0;
}

.live-boundary-facts strong {
  color: var(--text-strong);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.live-boundary-facts em {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-style: normal;
  line-height: 1.35;
}

@media (max-width: 1080px) {
  .live-boundary-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .live-boundary-facts {
    grid-template-columns: 1fr;
  }
}

.readout-hero-cell {
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
  min-width: 0;
}
.readout-hero-label {
  font-size: var(--fs-2xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.readout-hero-cell strong {
  font-size: var(--fs-lg);
  color: var(--text-strong);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.readout-hero-sub {
  font-size: var(--fs-2xs);
  color: var(--muted);
  line-height: 1.4;
}

.pip-dots {
  display: flex;
  gap: 0.25rem;
  align-items: center;
}
.pip {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--muted) 30%, transparent);
  border: 1px solid color-mix(in srgb, var(--muted) 45%, transparent);
}
.pip--done {
  background: var(--mint);
  border-color: var(--mint);
}
.pip-dots--partial .pip--done {
  background: var(--accent);
  border-color: var(--accent);
}
.pip-dots__empty {
  font-size: var(--fs-2xs);
  color: var(--muted);
}

.route-metrics--readout {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.85rem 1.1rem;
  margin-top: 0.55rem;
}

.readout-metric-with-viz {
  display: flex;
  flex-direction: column;
  gap: 0.32rem;
  min-width: 0;
}
.readout-metric-sub {
  font-size: var(--fs-2xs);
  color: var(--muted);
}
/* Position + Price scale charts — Polymarket-shaped horizontal bars
   that read together as a vertical pair on Live monitor (Position
   answers "how close am I to my LTV threshold", Price answers "how
   far does BTC have to drop"). On Results Live readout the Position
   chart appears alone. Same band grammar (rose liq → amber warn →
   mint target), same needle style (cyan dot + label), same tone
   variants — they read as one chart in two registers, not as two
   separate widgets. */
.position-scale,
.price-scale {
  display: grid;
  grid-template-rows: auto auto;
  gap: 0.3rem;
  margin: 0;
  padding: 0.45rem 0.6rem 0.5rem;
  border: 1px solid color-mix(in srgb, var(--line-strong) 55%, transparent);
  border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--surface-soft) 32%, transparent);
}
.position-scale__caption,
.price-scale__caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: var(--fs-2xs);
}
.position-scale__head,
.price-scale__head {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  min-width: 0;
}
.position-scale__head .section-label,
.price-scale__head .section-label {
  margin: 0;
  font-size: var(--fs-2xs);
}
.position-scale__current,
.price-scale__current {
  font-family: "Sora", "Manrope", sans-serif;
  font-size: var(--fs-base);
  font-weight: 800;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.position-scale__current--ok,
.price-scale__current--ok { color: var(--mint-text); }
.position-scale__current--low,
.price-scale__current--low { color: var(--cyan-text); }
.position-scale__current--warn,
.price-scale__current--warn { color: var(--amber-text); }
.position-scale__current--danger,
.price-scale__current--danger { color: var(--rose-text); }

.position-scale__legend,
.price-scale__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  align-items: center;
}
.legend-chip {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-xs);
  font-weight: 700;
  padding: 0.08rem 0.4rem;
  border-radius: var(--radius-full);
  letter-spacing: 0.01em;
  white-space: nowrap;
  line-height: 1.3;
}
.legend-chip--mint {
  color: var(--mint-text);
  background: color-mix(in srgb, var(--mint) 14%, transparent);
}
.legend-chip--amber {
  color: var(--amber-text);
  background: color-mix(in srgb, var(--amber) 14%, transparent);
}
.legend-chip--rose {
  color: var(--rose-text);
  background: color-mix(in srgb, var(--rose) 14%, transparent);
}

.position-scale__track,
.price-scale__track {
  position: relative;
  height: 6px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--muted) 18%, transparent);
  overflow: visible;
}
.position-scale__band,
.price-scale__band {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: var(--radius-full);
}
.position-scale__band--target,
.price-scale__band--target {
  background: var(--mint);
}
.position-scale__band--warn,
.price-scale__band--warn {
  background: var(--amber);
}
.position-scale__band--danger,
.price-scale__band--danger {
  background: var(--rose);
}
.position-scale__needle,
.price-scale__needle {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
}
.position-scale__needle-dot,
.price-scale__needle-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--cyan);
  border: 2px solid var(--surface);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--cyan) 80%, transparent),
    0 0 8px color-mix(in srgb, var(--cyan) 50%, transparent);
}
.position-scale__needle[data-tone="warn"] .position-scale__needle-dot,
.price-scale__needle[data-tone="warn"] .price-scale__needle-dot {
  background: var(--amber);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--amber) 80%, transparent),
    0 0 10px color-mix(in srgb, var(--amber) 55%, transparent);
}
.position-scale__needle[data-tone="danger"] .position-scale__needle-dot,
.price-scale__needle[data-tone="danger"] .price-scale__needle-dot {
  background: var(--rose);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--rose) 80%, transparent),
    0 0 10px color-mix(in srgb, var(--rose) 55%, transparent);
}
/* Needle label hidden — the current value already lives in the
   caption header (.price-scale__current). Keeping it floating above
   the bar made the chart taller than necessary. */
.position-scale__needle-label,
.price-scale__needle-label {
  display: none;
}
.position-scale__ticks,
.price-scale__ticks {
  display: none;
}

.price-scale__headroom {
  margin: 0.2rem 0 0;
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.35;
}
.price-scale__headroom strong {
  color: var(--text-strong);
}
.price-scale__headroom--danger {
  /* Phase D.32 — P0 liquidation threshold prose; raw bright rose
     fails AA on light surface tiles. var(--rose-text) is the readable
     companion that clears 4.5:1 on all surface variants. */
  color: var(--rose-text) !important;
}

/* Pair wrapper — Readout hero stacks the two charts inside a single
   bordered surface with one shared header so they read as a unit.
   Slim version: tight padding, dashed divider between the two charts,
   no per-chart border (border belongs to the pair shell). */
.scale-pair {
  display: grid;
  gap: 0.25rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid color-mix(in srgb, var(--line-strong) 50%, transparent);
  border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--surface-soft) 28%, transparent);
}
.scale-pair__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  font-size: var(--fs-2xs);
}
.scale-pair > .price-scale,
.scale-pair > .position-scale {
  border: none;
  background: transparent;
  padding: 0.2rem 0 0.3rem;
  border-radius: 0;
}
.scale-pair > .price-scale + .position-scale {
  border-top: 1px dashed color-mix(in srgb, var(--line-strong) 30%, transparent);
}
@media (max-width: 640px) {
  .position-scale__caption {
    gap: 0.45rem;
  }
  .position-scale__legend {
    width: 100%;
  }
}

.readout-bar {
  position: relative;
  height: 6px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--muted) 22%, transparent);
  overflow: hidden;
}
.readout-bar__fill {
  height: 100%;
  border-radius: inherit;
  transition: width 0.3s ease;
}
.readout-bar--good .readout-bar__fill { background: var(--mint); }
.readout-bar--warn .readout-bar__fill { background: var(--amber); }
.readout-bar--bad  .readout-bar__fill { background: var(--rose); }

.route-card-actions {
  margin-top: 0.65rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

/* Compact section-head — used inside Evidence sub-blocks where the
   surface itself is already nested. Same structure as .section-head
   but with the regime/badge floated to the right of the title row
   instead of stacking vertically. */
.section-head-compact {
  align-items: center;
  /* Phase D.10 — was 0.55rem (~9px). At that gap the h2 sits flush
     against the next content row (strategy-preset cards / swap-stat
     tiles / chart canvas) and read as cramped. Lifted to 0.85rem
     (~14px) so the section-head reads as a deliberate block boundary
     while staying visually compact compared to .section-head proper. */
  margin-bottom: 0.85rem;
}
.section-head-compact > div {
  flex: 1 1 auto;
}

/* Decision-engine summary — one composed diagnostic row below the
   stress cards. Keeps current action, ladder, and worst-state together
   without stacking three pancake strips. */
.engine-summary {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.25fr);
  gap: var(--space-5);
  align-items: stretch;
  margin-top: var(--space-5);
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-soft) 32%, transparent);
}
.engine-summary__decision,
.engine-summary__ladder {
  min-width: 0;
}
.engine-summary__decision {
  display: grid;
  gap: 0.42rem;
  padding-right: var(--space-5);
  border-right: 1px solid color-mix(in srgb, var(--line) 72%, transparent);
}
.engine-summary__decision p,
.engine-summary__worst {
  margin: 0;
  color: var(--muted);
  line-height: 1.45;
}
.engine-decision-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.engine-decision-head > span {
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.engine-decision-head strong {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--text-strong);
}

/* State-flow chip strip — compact horizontal ladder of operating
   states. Replaces the .state-flow node-with-arrow visualization
   inside the Decision-engine block where space is tighter. The
   active state is highlighted with the accent ring; the worst-case
   state from the stress ladder gets a rose underline so the eye
   can spot drift between current and worst-case. */
.engine-flow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: var(--space-2);
}
.engine-flow-chip {
  font-size: var(--fs-xs);
  font-weight: 500;
  padding: 0.18rem 0.55rem;
  border-radius: var(--radius-full);
  color: var(--muted);
  border: 1px solid transparent;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.engine-flow-chip.is-active {
  color: var(--text-strong);
  border-color: color-mix(in srgb, var(--accent) 65%, var(--line));
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.engine-flow-chip.is-worst {
  color: var(--rose);
  border-color: color-mix(in srgb, var(--rose) 55%, var(--line));
  background: color-mix(in srgb, var(--rose) 8%, transparent);
}
.engine-flow-sep {
  color: var(--muted);
  opacity: 0.5;
  font-size: var(--fs-xs);
}
.engine-summary__worst {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px dashed color-mix(in srgb, var(--line) 72%, transparent);
}
.engine-summary__worst strong {
  color: var(--text-strong);
}
@media (max-width: 860px) {
  .engine-summary {
    grid-template-columns: 1fr;
  }

  .engine-summary__decision {
    padding-right: 0;
    padding-bottom: var(--space-4);
    border-right: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--line) 72%, transparent);
  }
}

body[data-page="results"] .page-stack {
  gap: 0.55rem;
}

body[data-page="results"] .surface-hero {
  padding: 0.65rem 1.15rem 0.55rem;
}

.surface-hero {
  position: relative;
  padding: 0.85rem 1.25rem 0.75rem 1.15rem;
  background: var(--surface);

  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  color: var(--text);
  overflow: visible;
}

.surface-hero::before {
  content: none;
}

.surface-hero h2, .surface-hero strong {
  color: var(--text-strong);
}

.surface-hero .section-label, .surface-hero .surface-copy, .surface-hero .hero-copy-block .surface-copy, .surface-hero .metric-card span, .surface-hero .metric-card p {
  color: var(--muted);
}

.surface-hero .metric-card, .surface-hero .note-card {
  border-color: var(--line);
  background: transparent;
}

/* C.2.1 L1 — was using ghost tokens (--line-soft, --surface-muted,
   --text-muted) that don't exist in the lifted token block; the
   bare 8px / 10px / 12px / 14px values also drifted from the rem-
   scaled --space-* and --fs-* tokens. Now tracks the design system. */
.leaderboard-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.leaderboard-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-3) var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-soft);
}

.leaderboard-row strong { font-size: var(--fs-base); }

.leaderboard-meta { font-size: var(--fs-xs); color: var(--muted); }

.section-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
  padding-bottom: 0;
  border-bottom: none;
}

body[data-page="results"] .section-head {
  margin-bottom: 0.75rem;
}

/* Tighter card rhythm on Readout + Live to match the Workspace/Create
   density. Lighter padding + softer border on inner surfaces inside
   2-col content-grids so adjacent cards don't overwhelm the scan. */
body[data-page="results"] .page-stack,
body[data-page="live"] .page-stack {
  gap: 0.55rem;
}

body[data-page="results"] .surface,
body[data-page="live"] .surface {
  padding: 0.95rem 1.05rem;
}
body[data-page="results"] .surface-hero,
body[data-page="live"] .surface-hero {
  padding: 0.9rem 1.1rem 0.85rem;
}

body[data-page="results"] #readout-action.surface,
body[data-page="live"] #readout-action.surface,
body[data-page="results"] #readout-action.surface-hero,
body[data-page="live"] #readout-action.surface-hero {
  padding: 0;
  border: 0;
  background: transparent;
  min-width: 0;
  max-width: 100%;
}

/* Chart sections should read as visualization, not a nested card.
   The graph primitive already carries axes, labels, controls, and
   legends; adding .surface chrome around it creates the "panel under
   a chart" look. */
body[data-page="results"] #results-scenarios.surface,
body[data-page="live"] #results-scenarios.surface {
  padding: var(--space-2) 0 0;
  border: 0;
  background: transparent;
  min-width: 0;
  max-width: 100%;
}

body[data-page="results"] #readout-hero,
body[data-page="live"] #readout-hero,
body[data-page="results"] #results-market-forecast,
body[data-page="live"] #results-market-forecast {
  min-width: 0;
  max-width: 100%;
}

body[data-page="results"] .content-grid > .surface,
body[data-page="live"] .content-grid > .surface {
  border-color: color-mix(in srgb, var(--line-strong) 80%, transparent);
}

/* Footnotes packed into a single-line bar when they live inside the
   hero glance, so model-drag + TIDE-fee lines read as one info strip
   not two paragraphs. */
body[data-page="results"] .surface-hero .section-footnote {
  margin: 0.55rem 0 0;
  padding: 0.55rem 0.75rem;
  background: color-mix(in srgb, var(--surface-soft) 55%, transparent);
  border: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
  border-radius: var(--radius-xs);
  font-size: var(--fs-xs);
  line-height: 1.45;
}
body[data-page="results"] .surface-hero .section-footnote + .section-footnote {
  margin-top: 0.35rem;
}

.hero-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 1.3rem;
  padding: 0.12rem 0.5rem;
  border-radius: var(--radius-full);
  background: var(--surface-strong);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: var(--fs-2xs);
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
}

.metric-card, .note-card, .route-card, .empty-panel, .saved-card, .log-card {
  display: grid;
  gap: 0.25rem;
  min-width: 0;
  padding: 0.6rem 0.5rem;
  border-radius: 0;
  border: none;
  background: transparent;

  overflow: hidden;
  transition: background-color 200ms ease;
}

.metric-card span {
  display: block;
}

.metric-card strong, .note-card strong, .route-card strong, .saved-card strong, .log-card strong {
  display: block;
  margin-top: 0.35rem;
  font-weight: 800;
  min-width: 0;
  overflow-wrap: anywhere;
}

.metric-card strong {
  font-size: clamp(1.3rem, 2vw, 1.75rem);
  line-height: 1.05;
  margin-top: 0.15rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
}

.metric-card p, .note-card p, .route-card p, .log-card p {
  margin: 0.3rem 0 0;
  font-size: var(--fs-sm);
  overflow-wrap: anywhere;
}

.token-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.route-card .route-card-head {
  align-items: flex-start;
}

.route-card .token-row {
  margin-top: 0.9rem;
}

.form-grid {
  display: grid;
  gap: 0.6rem;
}

.create-scope-hint {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 600;
  line-height: 1.45;
}

.create-scope-hint[data-tone="good"] {
  color: var(--mint);
}

.create-scope-hint[data-tone="warn"] {
  color: var(--amber);
}

.position-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
  align-items: start;
  overflow: visible;
}

.field-compact {
  gap: 0.2rem;
}

.field-compact span {
  font-size: var(--fs-xs);
}

.field-compact input {
  min-height: 2rem;
  font-variant-numeric: tabular-nums;
}

.guardrails-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem 0.65rem;
  margin-top: 0.85rem;
}

@media (max-width: 760px) {
.guardrails-grid {
    grid-template-columns: repeat(2, 1fr);
  }

.collateral-balance-copy {
    white-space: normal;
  }

}

.field-dollar-hint {
  display: block;
  margin-top: -0.1rem;
  color: var(--cyan);
  font-size: var(--fs-2xs);
  font-weight: 600;
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}

.form-grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.form-grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.field {
  display: grid;
  gap: 0.35rem;
  position: relative;
}

.field span {
  color: var(--muted-strong);
  font-size: var(--fs-sm);
  font-weight: 700;
}

.field small {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 20;
  color: var(--text);
  background: var(--surface-strong);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-xs);
  padding: 0.45rem 0.6rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.45;

  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
  transition-delay: 0s;
}

.field:hover small, .field:focus-within small {
  opacity: 1;
  pointer-events: auto;
  transition-delay: 1.5s;
}

.field input, .field select, .text-area {
  width: 100%;
  min-height: 2.4rem;
  padding: 0 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  background: var(--bg-strong);
  color: var(--text);
  font-size: var(--fs-base);
  font-weight: 500;
  transition:
    border-color 150ms ease,
    background-color 150ms ease;
}

.field input:hover, .field select:hover, .text-area:hover {
  border-color: var(--line-strong);
  background: var(--surface-soft);
}

.field input:focus, .field select:focus, .text-area:focus {
  outline: none;
  border-color: var(--accent);

  background: var(--surface-soft);
}

.field input[type="number"] {
  -moz-appearance: textfield;
}

.field input[type="number"]::-webkit-inner-spin-button, .field input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}

.field input[type="number"]:hover {
  -moz-appearance: auto;
}

.field input[type="number"]:hover::-webkit-inner-spin-button, .field input[type="number"]:hover::-webkit-outer-spin-button {
  -webkit-appearance: inner-spin-button;
  appearance: auto;
  opacity: 0.6;
  height: 1.6rem;
  cursor: pointer;
}

.field input[type="number"]:hover::-webkit-inner-spin-button:hover, .field input[type="number"]:hover::-webkit-outer-spin-button:hover {
  opacity: 1;
}

.range-combo {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 0.6rem;
}

.range-combo input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 2.75rem;
  border-radius: var(--radius-pill);
  background: linear-gradient(
    to right,
    var(--accent) 0%,
    var(--accent) var(--range-fill, 50%),
    color-mix(in srgb, var(--muted) 30%, transparent) var(--range-fill, 50%),
    color-mix(in srgb, var(--muted) 30%, transparent) 100%
  );
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 6px;
  outline: none;
  cursor: pointer;
  border: none;
  min-height: 2.75rem;
  padding: 0;
}

.range-combo input[type="range"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

html[data-theme="dark"] .range-combo input[type="range"] {
  background: linear-gradient(
    to right,
    var(--accent) 0%,
    var(--accent) var(--range-fill, 50%),
    color-mix(in srgb, var(--muted) 30%, transparent) var(--range-fill, 50%),
    color-mix(in srgb, var(--muted) 30%, transparent) 100%
  );
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 6px;
}

.range-combo input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  cursor: grab;
  transition: transform 150ms ease, box-shadow 150ms ease;
  box-shadow: var(--shadow-sm);
}

.range-combo input[type="range"]::-webkit-slider-thumb:hover {
  transform: scale(1.15);

}

.range-combo input[type="range"]::-webkit-slider-thumb:active {
  cursor: grabbing;
  transform: scale(1.05);
}

.range-combo input[type="range"]::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--accent);
  cursor: grab;
}

.range-combo .range-value {
  min-width: 3.2rem;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-xs);
  background: var(--surface-tint);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}

.range-combo .range-value-input {
  width: 3.8rem;
  min-height: 1.7rem;
  padding: 0.15rem 0.35rem;
  border-radius: var(--radius-xs);
  border: 1px solid var(--line);
  background: var(--surface-tint);
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
  transition: border-color 150ms ease, background 150ms ease;
}

.range-combo .range-value-input:hover {
  border-color: var(--line-strong);
  background: var(--surface-soft);
}

.range-combo .range-value-input:focus {
  outline: none;
  border-color: var(--accent);

  background: var(--surface-soft);
}

.range-combo .range-value-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.range-value-input::-webkit-inner-spin-button, .range-value-input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.range-value-input { -moz-appearance: textfield; }

.text-area {
  min-height: 6rem;
  padding: 0.82rem 0.88rem;
  resize: vertical;
}

.inline-title-shell {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.2rem;
  padding: 0 0.1rem 0 0;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
}

.inline-title-icon {
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
}

.inline-title-shell input {
  width: 100%;
  min-width: 0;
  min-height: 1.8rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text-strong);
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1.1;
}

.inline-title-shell input::placeholder {
  color: var(--muted);
  opacity: 1;
}

.inline-title-shell:focus-within {
  color: var(--accent);
  border-bottom-color: var(--accent-soft);
}

.inline-title-shell input:focus {
  outline: none;

}

.disclosure {
  overflow: hidden;
}

.disclosure-head {
  display: flex;
  justify-content: space-between;
  list-style: none;
  cursor: pointer;
  transition: opacity 200ms ease;
}

.disclosure-head:hover {
  opacity: 0.8;
}

.disclosure-head::-webkit-details-marker {
  display: none;
}

.disclosure-head::after {
  content: "+";
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.8rem;
  height: 1.8rem;
  flex: 0 0 auto;
  border-radius: var(--radius-xs);
  background: var(--surface-soft);
  color: var(--muted);
  font-size: var(--fs-lg);
  font-weight: 700;
  line-height: 1;
  transition: transform 200ms ease, background-color 200ms ease;
}

.disclosure[open] .disclosure-head::after {
  content: "-";
  transform: none;
  background: var(--accent-soft);
  color: var(--accent);
}

.disclosure[open] .disclosure-head {
  margin-bottom: 1rem;
}

.visual-mark {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  padding: 0;
  overflow: hidden;
  border-radius: 50%;
  border: 0;
  background: var(--surface-soft);
  width: 24px;
  height: 24px;
}

.visual-mark-md { width: 28px; height: 28px; flex: 0 0 28px; }
.visual-mark-lg { width: 40px; height: 40px; flex: 0 0 40px; }

.visual-mark.is-fallback {
  border-radius: var(--radius-full);
  background: var(--surface-emphasis);
}

.visual-mark-image {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  object-position: center;
  display: block;
}

.entity-inline {
  display: inline-grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0.55rem;
  min-width: 0;
  width: 100%;
}

.entity-copy {
  display: grid;
  gap: 0.18rem;
  min-width: 0;
}

.entity-copy strong, .entity-copy span {
  display: block;
}

.entity-copy strong, .entity-copy span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.entity-copy span {
  color: var(--muted);
  font-size: var(--fs-base);
}

.token-chip {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  min-width: 0;
  gap: 0.36rem;
  min-height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text-strong);
  font-size: var(--fs-base);
  font-weight: 700;
  line-height: 1;
}

.token-chip .visual-mark {
  background: transparent;
  border-radius: 50%;
}

.token-chip-label {
  min-width: 0;
  line-height: 1.08;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.route-grid {
  display: grid;
  gap: 0.85rem;
}

.route-card {
  position: relative;
  padding: 0.2rem 0 0.2rem 0.85rem;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.route-grid .route-card + .route-card {
  padding-top: 0.8rem;
  border-top: 1px solid var(--line);
}

.route-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.1rem;
  bottom: 0.1rem;
  width: 2px;
  border-radius: var(--radius-full);
  background: var(--line-strong);
}

.route-card-title {
  display: grid;
  gap: 0.52rem;
  min-width: 0;
}

.route-card-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.route-role {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  min-height: 1.15rem;
  padding: 0 0.38rem;
  border-radius: var(--radius-full);
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.route-card-head, .saved-card-head, .log-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-width: 0;
}

.route-score, .state-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-width: 0;
  max-width: 100%;
  min-height: 1.3rem;
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--muted-strong);
  font-size: var(--fs-2xs);
  font-weight: 800;
  line-height: 1.2;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* C.2.1 UX-L1 + UX-L5 — tone modifiers for the state-badge so chips
   carry semantic colour. Used on /library saved-card head (review
   status: mint / amber / rose) and meta line (mode: cyan / muted). */
.state-badge--mint {
  color: var(--mint-text);
  border-color: color-mix(in srgb, var(--mint) 38%, var(--line-strong));
  background: color-mix(in srgb, var(--mint) 10%, var(--surface));
}
.state-badge--amber {
  color: var(--amber-text);
  border-color: color-mix(in srgb, var(--amber) 38%, var(--line-strong));
  background: color-mix(in srgb, var(--amber) 10%, var(--surface));
}
.state-badge--rose {
  color: var(--rose-text);
  border-color: color-mix(in srgb, var(--rose) 38%, var(--line-strong));
  background: color-mix(in srgb, var(--rose) 10%, var(--surface));
}
.state-badge--cyan {
  color: var(--cyan-text);
  border-color: color-mix(in srgb, var(--cyan) 38%, var(--line-strong));
  background: color-mix(in srgb, var(--cyan) 10%, var(--surface));
}
.state-badge--accent {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line-strong));
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}
.state-badge--violet {
  color: var(--violet-text);
  border-color: color-mix(in srgb, var(--violet) 38%, var(--line-strong));
  background: color-mix(in srgb, var(--violet) 10%, var(--surface));
}
.state-badge--muted { /* base — same as no modifier; explicit for legibility */ }

.saved-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.6rem;
  margin-top: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
}

.route-metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: var(--fs-sm);
}

.route-metrics > div {
  min-width: 0;
}

.route-metrics strong {
  margin-top: 0.25rem;
}

/* Strip default chrome from raw meta spans, but leave state-badge
   chrome alone — C.2.1 places a tone-coded mode chip in the meta
   row alongside plain text rows. */
.saved-card-meta > span:not(.state-badge) {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  min-width: 0;
  max-width: 100%;
  min-height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  line-height: 1.25;
  text-align: center;
  overflow-wrap: anywhere;
}

.empty-panel {
  display: grid;
  gap: 0.8rem;
  min-height: 180px;
  align-content: center;
  background: var(--surface-soft);
}

.log-card, .note-card {
  background: transparent;
  padding: 0.5rem 0 0.5rem 0.65rem;
  border-left: 2px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.log-card[data-state="Observe"] { border-left-color: var(--cyan); }

.log-card[data-state="Maintain"] { border-left-color: var(--mint); }

.log-card[data-state="BuildBuffer"] { border-left-color: var(--amber); }

.log-card[data-state="DeRisk"] { border-left-color: var(--violet); }

.log-card[data-state="StressLockdown"] { border-left-color: var(--rose); }

#saved-scenarios {
  gap: 0;
}

.saved-card {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto;
  gap: 0.3rem 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  align-items: center;
}

.saved-card-head {
  grid-column: 1;
}

.saved-card-meta {
  grid-column: 1;
}

.saved-card .action-cluster {
  grid-column: 2;
  grid-row: 1 / -1;
}

.saved-card:last-child {
  border-bottom: 0;
}

.saved-card p, .saved-card-head p {
  margin: 0.2rem 0 0;
  overflow-wrap: anywhere;
}

/* C.2.1 L2 — .delta / .delta.positive / .delta.negative /
   .delta.neutral were a hand-rolled duplicate of .delta-chip with
   no live consumers in app.js or any .html. Deleted. Use
   .delta-chip + .delta-chip--up / --down for new sites. */

.review-hero {
  display: grid;
  gap: 0.55rem;
  padding: 0.7rem 0.8rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--bg-strong);
}

.review-hero-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.review-hero-top strong {
  font-size: var(--fs-xl);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.review-progress {
  overflow: hidden;
  width: 100%;
  height: 0.38rem;
  border-radius: var(--radius-full);
  background: var(--surface-tint);
}

.review-progress span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: currentColor;
  opacity: 0.85;
  transition: width 600ms cubic-bezier(0.4, 0, 0.2, 1);
}

.review-badge, .review-flag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 1.55rem;
  padding: 0.12rem 0.55rem;
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.review-badge {
  border: 0;
  gap: 0.32rem;
}

.badge-icon {
  width: 0.9rem;
  height: 0.9rem;
  flex: 0 0 auto;
}

.review-flag {
  background: transparent;
  color: var(--amber);
  flex: 0 0 auto;
}

.operator-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.14fr) minmax(280px, 0.86fr);
  gap: 1.2rem;
  align-items: start;
  margin-top: 0.8rem;
}

.operator-stack {
  display: grid;
  gap: 0.85rem;
  min-width: 0;
}

.operator-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.6rem 1rem;
  margin-top: 0;
  padding-top: 0.15rem;
  border-top: 0;
}

.operator-fact {
  display: grid;
  gap: 0.15rem;
  min-width: 0;
  padding: 0.05rem 0 0.55rem;
  border-bottom: 1px solid var(--line);
}

.operator-fact span {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.operator-fact strong {
  margin: 0.05rem 0 0;
  font-size: var(--fs-md);
  line-height: 1.1;
}

.operator-fact p {
  margin: 0.18rem 0 0;
  color: var(--muted);
  line-height: 1.35;
}

.review-list-shell {
  border: 0;
  border-radius: 0;
  background: transparent;
  overflow: visible;
}

.review-list {
  display: grid;
  gap: 0;
}

.review-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 0.7rem;
  min-width: 0;
  padding: 0.65rem 0;
  border-top: 1px solid var(--line);
  background: transparent;
}

.review-item.is-first {
  border-top: 0;
  padding-top: 0;
}

.review-item input {
  position: static;
  opacity: 1;
  pointer-events: auto;
}

.review-check {
  appearance: none;
  -webkit-appearance: none;
  display: inline-grid;
  place-items: center;
  width: 1rem;
  height: 1rem;
  margin-top: 0.1rem;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-soft);

  flex: 0 0 auto;
  cursor: pointer;
  transition:
    border-color 160ms ease,
    background-color 160ms ease,
    box-shadow 160ms ease;
}

.review-check:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 10%, transparent);
}

.review-check:checked, .review-item.is-done .review-check {
  border-color: transparent;
  background:
    center / 0.7rem 0.7rem no-repeat
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.2 8.4 6.4 11.4 12.6 4.8' fill='none' stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.2'/%3E%3C/svg%3E"),
    var(--accent);

}

.review-copy {
  display: grid;
  gap: 0.24rem;
  min-width: 0;
}

.review-copy strong, .review-copy small {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Phase D.30.4 — explicit type ramp so the operator-review item reads
   as "primary statement + qualifier", not "tiny label + giant
   confirm-glyph". The review item is the pre-anchor decision content;
   the checkbox is the certification glyph. Was inheriting body fs
   (which on this page is --fs-sm), making labels visually subservient
   to the 16px check. Now: strong at --fs-md matches the check height,
   small at --fs-base reads as a clear sub-line. */
.review-copy strong {
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1.35;
  color: var(--text-strong);
}

.review-copy small {
  color: var(--muted);
  font-size: var(--fs-base);
  line-height: 1.5;
}

.review-item.is-done {
  background: transparent;
}

.review-item.is-done .review-copy small {
  color: var(--muted-strong);
}

.operator-form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.9rem;
}

.operator-form-shell {
  padding-top: 0.4rem;
  border-top: 1px solid var(--line);
}

.operator-actions {
  padding-top: 0.45rem;
}

.review-flag {
  width: 1.25rem;
  height: 1.25rem;
  min-height: auto;
  padding: 0;
  border-radius: 0;
  font-size: 0;
  position: relative;
  background: transparent;
  color: var(--amber);
  cursor: help;
  align-self: start;
  margin-top: 0.18rem;
  filter: none;
}

.review-flag svg {
  width: 1.25rem;
  height: 1.25rem;
}

.review-flag::after {
  content: attr(data-tooltip);
  position: absolute;
  right: -0.25rem;
  bottom: calc(100% + 0.45rem);
  min-width: max-content;
  max-width: 18rem;
  padding: 0.45rem 0.6rem;
  border-radius: var(--radius-xs);
  background: var(--tooltip-bg);
  color: var(--tooltip-text);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: none;
  white-space: normal;

  opacity: 0;
  transform: translateY(4px);
  pointer-events: none;
  transition:
    opacity 150ms ease,
    transform 150ms ease;
  z-index: 10;
}

.review-flag:hover::after, .review-flag:focus-visible::after {
  opacity: 1;
  transform: translateY(0);
}

body[data-page="results"] #results-route {
  padding-top: 0.05rem;
}

.section-footnote {
  margin: 0.55rem 0 0;
  padding-top: 0.55rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: 1.5;
}

.section-footnote strong {
  color: var(--text-strong);
}

/* Phase D.28 — .live-feed-list / -row / -head / -meta / -stats / -copy
   / -disclosure family removed (~95 lines). Consumed only inside the
   dead `renderLiveAllocatorList` / `renderLiveSupplementalList` /
   `renderLiveSupplementalSection` (purged in D.28.2). DS rule §9.10. */

.fact-list {
  display: grid;
  gap: 0;
}

.fact-list-compact {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 1.4rem;
  margin-top: 0.6rem;
}

.fact-row-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0 2rem;
}

.fact-row-grid .fact-row {
  padding: 0.5rem 0;
  border-top: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  background: transparent;
}

.fact-row {
  display: grid;
  gap: 0.08rem;
  min-width: 0;
  padding: 0.55rem 0.5rem 0.6rem;
  border-top: 1px solid var(--line);
}

.fact-list .fact-row:first-child, .fact-list-compact .fact-row:nth-child(-n + 2) {
  padding-top: 0;
  border-top: 0;
}

.fact-row span {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.compare-header {
  margin-bottom: 0.3rem;
}

.fact-row strong {
  margin: 0;
  font-size: var(--fs-md);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.fact-row[data-tone="success"] strong {
  color: var(--mint);
}

.fact-row[data-tone="warn"] strong {
  color: var(--amber);
}

.fact-row[data-tone="danger"] strong {
  color: var(--rose);
}

.fact-row p {
  margin: 0.08rem 0 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.35;
}

/* Operating-state stripes — tone color-mix tracks the lifted palette,
   so changing --cyan / --mint / --amber / --violet / --rose updates
   every state stripe at once. */
[data-state="Observe"] {
  border-bottom-color: color-mix(in srgb, var(--cyan) 18%, transparent);
}

[data-state="Maintain"] {
  border-bottom-color: color-mix(in srgb, var(--mint) 18%, transparent);
}

[data-state="BuildBuffer"] {
  border-bottom-color: color-mix(in srgb, var(--amber) 18%, transparent);
}

[data-state="DeRisk"] {
  border-bottom-color: color-mix(in srgb, var(--violet) 20%, transparent);
}

[data-state="StressLockdown"] {
  border-bottom-color: color-mix(in srgb, var(--rose) 20%, transparent);
}

[data-state="Observe"] .state-badge {
  background: var(--cyan-soft);
  color: var(--cyan);
  border-color: var(--cyan-soft);
}

[data-state="Maintain"] .state-badge {
  background: var(--mint-soft);
  color: var(--mint);
  border-color: var(--mint-soft);
}

[data-state="BuildBuffer"] .state-badge {
  background: var(--amber-soft);
  color: var(--amber);
  border-color: var(--amber-soft);
}

[data-state="DeRisk"] .state-badge {
  background: var(--violet-soft);
  color: var(--violet);
  border-color: var(--violet-soft);
}

[data-state="StressLockdown"] .state-badge {
  background: var(--rose-soft);
  color: var(--rose);
  border-color: var(--rose-soft);
}

.setup-toolbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.setup-footer-bar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  margin-top: var(--space-3);
  border-top: var(--border-soft);
  background: var(--surface);
}

.setup-footer-bar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
  flex: 0 0 auto;
  position: relative;
}

.setup-footer-bar__primary {
  min-width: 11rem;
}

.setup-footer-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-sm);
  border: var(--border-soft);
  background: var(--surface-soft);
  color: var(--muted-strong);
  cursor: pointer;
  padding: 0;
  transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}

.setup-footer-iconbtn:hover {
  color: var(--text-strong);
  background: var(--surface-tint);
  border-color: var(--line-strong);
}

.setup-footer-iconbtn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.setup-footer-iconbtn svg { width: 15px; height: 15px; }

.setup-footer-iconbtn .setup-footer-iconbtn__icon--saved { display: none; }

/* C.4 — was hardcoded Tailwind green family (#16a34a / #15803d).
   Tracks --mint family; --mint-text reads on the soft pill in
   both themes. */
.setup-footer-iconbtn[data-state="saved"] {
  color: var(--mint-text);
  border-color: color-mix(in srgb, var(--mint) 50%, var(--line-strong));
  background: color-mix(in srgb, var(--mint) 12%, transparent);
}

.setup-footer-iconbtn[data-state="saved"]:hover {
  color: var(--mint-text);
  background: color-mix(in srgb, var(--mint) 18%, transparent);
}

.setup-footer-iconbtn[data-state="saved"] .setup-footer-iconbtn__icon--idle { display: none; }
.setup-footer-iconbtn[data-state="saved"] .setup-footer-iconbtn__icon--saved { display: block; }

/* Phase D.8 — labeled variant: save-as-draft button now carries an
   inline text label so the operator doesn't have to read the
   tooltip to know what it does. The reset button stays icon-only
   (destructive-secondary, less primary). */
.setup-footer-iconbtn--labeled {
  width: auto;
  padding: 0 0.7rem 0 0.55rem;
  gap: 0.4rem;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.setup-footer-iconbtn__label {
  white-space: nowrap;
}
.setup-footer-iconbtn .setup-footer-iconbtn__label--saved { display: none; }
.setup-footer-iconbtn[data-state="saved"] .setup-footer-iconbtn__label--idle { display: none; }
.setup-footer-iconbtn[data-state="saved"] .setup-footer-iconbtn__label--saved { display: inline; }

.setup-footer-bar.setup-footer-summary, .setup-footer-summary {
  --preview-tone: var(--accent);
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: minmax(0, auto) minmax(18rem, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  padding: 0.75rem var(--space-4);
  min-height: 76px;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  background: var(--surface);

  overflow: visible;
}

.setup-footer-summary[data-tone="stable"] { --preview-tone: var(--mint); }

.setup-footer-summary[data-tone="warn"], .setup-footer-summary[data-tone="blocked"] { --preview-tone: var(--amber); }

.setup-footer-summary[data-tone="danger"], .setup-footer-summary[data-tone="critical"] { --preview-tone: var(--rose); }

.setup-footer-summary__left {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: auto;
  min-width: 0;
}

.setup-footer-summary__left .create-preview-ring {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
}

.setup-footer-summary__left .create-preview-ring::before {
  inset: 5px;
}

.setup-footer-summary__left .create-preview-ring strong {
  font-size: var(--fs-base);
}

.setup-footer-summary__left .create-preview-ring span {
  font-size: 0.5rem;
  margin-top: 0.05rem;
  letter-spacing: 0.1em;
}

.setup-footer-summary__meta {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.setup-footer-summary__meta .create-preview-title {
  font-size: var(--fs-base);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 11rem;
}

.setup-footer-summary__pills {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.3rem;
}

/* Phase D.5 — preview copy + next-action hint were sr-only, so the
   plain-English summary the operator filled in was invisible to
   sighted users (only screen readers heard it). Now both lines render
   inline under the pills as muted body copy, sized to fit on a single
   line with truncation if longer than the meta column. */
.setup-footer-summary__meta .create-preview-copy,
.setup-footer-summary__meta .create-preview-next {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: 1.35;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.setup-footer-summary__meta .create-preview-next {
  color: var(--muted);
}
.setup-footer-summary__meta .create-preview-copy:empty,
.setup-footer-summary__meta .create-preview-next:empty {
  display: none;
}

.setup-footer-summary__pills .create-preview-asset {
  min-width: 10rem;
}

.setup-footer-summary__pills .create-preview-pill[data-create-preview-scope] {
  min-width: 7.5rem;
  justify-content: center;
  display: inline-flex;
  align-items: center;
}

.setup-footer-summary__pills .create-preview-asset, .setup-footer-summary__pills .create-preview-pill {
  min-height: 1.3rem;
  padding: 0 0.55rem;
  font-size: var(--fs-2xs);
  letter-spacing: 0.08em;
}

.setup-footer-summary__mid {
  display: grid !important;
  grid-auto-flow: column !important;
  grid-auto-columns: minmax(0, 1fr) !important;
  grid-template-columns: unset !important;
  align-items: center;
  gap: 0 !important;
  padding: 0 0.2rem;
  border: 0;
  min-width: 0;
  overflow: visible !important;
  flex-wrap: nowrap !important;
}

.setup-footer-summary__mid .create-preview-metric {
  display: grid !important;
  grid-template-columns: none !important;
  gap: 0.08rem;
  min-width: 0;
  padding: 0 0.55rem;
  border-left: 1px solid color-mix(in srgb, var(--line) 76%, transparent);
  overflow: visible !important;
}

.setup-footer-summary__mid .create-preview-metric:first-child {
  padding-left: 0.15rem;
  border-left: 0;
}

.setup-footer-summary__mid .create-preview-metric span {
  font-family: "Manrope", "Sora", sans-serif;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--muted-strong);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: visible !important;
  text-overflow: clip !important;
}

.setup-footer-summary__mid .create-preview-metric strong {
  font-family: "Sora", "Manrope", sans-serif;
  font-size: var(--fs-base);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: visible !important;
  text-overflow: clip !important;
}

.setup-footer-summary__right {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  justify-self: end;
  flex-wrap: wrap;
  justify-content: flex-end;
}

@media (max-width: 1100px) {
.setup-footer-summary {
    grid-template-columns: 1fr;
    min-height: 0;
  }

.setup-footer-summary__left {
    width: auto;
  }

.setup-footer-summary__mid {
    overflow: visible;
  }

.setup-footer-summary__right {
    justify-self: start;
    justify-content: flex-start;
  }

}


.btc-price-meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.2rem;
  font-size: var(--fs-xs);
  color: var(--muted);
}

.btc-price-meta__reset {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: inherit;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
}

.btc-price-meta__reset[hidden] { display: none; }

.field-amount-error {
  margin-top: 0.25rem;
  font-size: var(--fs-xs);
  color: var(--rose);
}

.field-amount-error[hidden] { display: none; }

.scenario-workbench-host {
  display: grid;
  gap: var(--space-4);
  min-width: 0;
}

a.button, button.button, a[data-nav], .saved-card [data-action], [data-review-check], [data-theme-value] {
  cursor: pointer;
}

.saved-card [data-action]:hover {
  transform: translateY(-1px);
}

.page-header-compact {
  padding-bottom: 0.1rem;
  margin-bottom: 0.15rem;
}

.page-header--product {
  --page-header-x: 1.15rem;
  gap: var(--space-2);
  padding: 0.85rem var(--page-header-x);
  margin-bottom: 0.65rem;
  background: color-mix(in srgb, var(--surface) 86%, transparent);
}

.page-header--product .page-eyebrow {
  margin-bottom: 0.45rem;
}

.page-header--product .page-copy {
  max-width: 48rem;
  font-size: var(--fs-sm);
  line-height: 1.45;
}

.page-header--product .page-tools {
  gap: 0.45rem;
}

.page-header--product .action-cluster {
  gap: 0.45rem;
}

.page-header--product .action-cluster .button,
.page-header--product .page-tools > .button {
  min-height: 2.25rem;
  padding-block: 0.42rem;
}

.page-header--product .trust-labels.trust-strip--in-header {
  margin: 0.45rem 0 0;
  padding: 0;
  border: 0;
  background: transparent;
}

.page-header--product:has(.trust-strip--in-header) {
  padding-bottom: 0.85rem;
}

.page-header--product:has(.trust-strip--in-header)::after {
  display: none;
}

.page-header-compact .inline-title-shell {
  border-bottom: 1px dashed transparent;
  transition: border-color 0.2s ease;
}

.page-header-compact .inline-title-shell:hover {
  border-bottom-color: var(--line-strong);
}

.page-header-compact .inline-title-shell:focus-within {
  border-bottom-color: var(--accent);
  border-bottom-style: solid;
}

.page-header-compact .inline-title-shell input {
  font-size: var(--fs-md);
  font-weight: 700;
  font-family: "Sora", "Manrope", sans-serif;
  letter-spacing: -0.03em;
}

.status-link {
  color: var(--accent);
  text-decoration: underline;
  margin-left: 0.4rem;
  font-weight: 600;
}

.status-link:hover {
  text-decoration: none;
}

.status-action-button {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  cursor: pointer;
}

/* ──────────────────────────────────────────────────────────────────
   Light-theme tone-text overrides — wherever a tone is used as TEXT
   colour on the bright canvas (legend chips, icon-badges, delta chips,
   signing-state icons, field validation copy, position-scale current
   readout, spark-inline strokes), swap to the --tone-text companion
   so AA contrast on white passes. Solid tone FILLS (bands, dots,
   icon backgrounds, network-badge dots, segmented active fills) keep
   the user's bright values. Scope-fenced to /design-system; consumer
   pages still use the global tokens.
   ────────────────────────────────────────────────────────────────── */
/* Phase C.1.fix — these /design-system-scoped light-theme tone-text
   overrides are now redundant: every rule they touched was rewritten
   in the global selector to use --mint-text / --amber-text /
   --rose-text / --cyan-text / --violet-text directly. The companions
   alias to the bright tone in dark and to the dark companion in light
   per :root + html[data-theme="dark"] in this same file, so AA
   contrast holds across themes globally. */

/* Thresholds rail (.guardrails-chart__strip) demo — the canonical
   primitive lives in 30-scenario-chart.css and cascades vars from
   .guardrails-chart parent. The /design-system demo is mounted
   without that parent, so we provide:
     a) --guardrails-chart-max so width: min(100%, var(...)) resolves
        (otherwise width collapses to auto and pills cram into a blob)
     b) --chart-* aliases pointing at our palette tokens, replacing
        the hardcoded #22e07c / #ff9a2e / #ff3b4d that sit outside
        the design-system palette per user feedback
     c) --guardrails-pill-text → var(--bg) for dark text on the
        bright tone pills (was #0b1120 hardcoded). */
body[data-page="design-system"] .guardrails-chart__strip {
  --guardrails-chart-max: 720px;
  --chart-mint:  var(--mint);
  --chart-amber: var(--amber);
  --chart-rose:  var(--rose);
  --chart-accent: var(--accent);
  --guardrails-pill-text: var(--on-tone-text-dark);
  width: 100%;
  max-width: 720px;
}
/* Track outline tightens to our --line-strong instead of the legacy
   --line fallback so it's visible against /design-system's brighter
   surface canvas. */
body[data-page="design-system"] .guardrails-chart__strip .guardrails-chart__strip-track {
  background: var(--surface-soft);
  border-color: var(--line-strong);
}
/* Light theme — --bg is cool-white #F4F7FB, so the pill-text token
   above ("var(--bg)") resolves to near-white on the bright mint /
   amber / rose pills (HIGH + REPAY become unreadable on yellow).
   Pin to a dark navy in light theme so all four pills carry dark
   text. Dark theme keeps the existing var(--bg) (dark text on bright
   pills) — user explicitly fenced this fix to light only. */
html[data-theme="light"] body[data-page="design-system"] .guardrails-chart__strip {
  --guardrails-pill-text: var(--on-tone-text-dark);
}

/* Click-to-copy on .section-micro-label that names a selector.
   JS binds the click listener via [data-copy-selector] which
   sectionShell auto-extracts from labels matching /^\.[a-z]/. The
   cursor + hover state hint that the chip is interactive; success
   state ("✓ Copied") is set via data-state="copied" for 1.2s. Per
   third-pass 2/3 consensus (UI U1 + frontend LIVE-9 family). */
body[data-page="design-system"] .section-micro-label[data-copy-selector] {
  cursor: copy;
  position: relative;
  padding-right: 1.2rem;
  transition: color 120ms ease, background 120ms ease;
  border-radius: var(--radius-xs);
}
body[data-page="design-system"] .section-micro-label[data-copy-selector]::after {
  content: "⧉";
  position: absolute;
  right: 0.3rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  opacity: 0.5;
  transition: opacity 120ms ease, color 120ms ease;
  font-size: 0.85em;
}
body[data-page="design-system"] .section-micro-label[data-copy-selector]:hover {
  color: var(--text-strong);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}
body[data-page="design-system"] .section-micro-label[data-copy-selector]:hover::after {
  opacity: 1;
  color: var(--accent);
}
body[data-page="design-system"] .section-micro-label[data-copy-selector]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
body[data-page="design-system"] .section-micro-label[data-copy-selector][data-state="copied"] {
  color: var(--mint);
  background: color-mix(in srgb, var(--mint) 14%, transparent);
}
body[data-page="design-system"] .section-micro-label[data-copy-selector][data-state="copied"]::after {
  content: "✓";
  color: var(--mint);
  opacity: 1;
}
html[data-theme="light"] body[data-page="design-system"] .section-micro-label[data-copy-selector][data-state="copied"] {
  color: var(--mint-text);
  background: color-mix(in srgb, var(--mint-text) 12%, transparent);
}
html[data-theme="light"] body[data-page="design-system"] .section-micro-label[data-copy-selector][data-state="copied"]::after {
  color: var(--mint-text);
}

/* ──────────────────────────────────────────────────────────────────
   RTL: directional icons need a horizontal mirror in RTL languages
   so chevrons / arrows / refresh / external-link point the right way
   for Arabic / Hebrew operators. Per i18n §25.

   Approach: tag directional .ds-icon variants with a data-dir-flip
   attribute on the SVG wrapper; under [dir="rtl"] they get a
   transform: scaleX(-1). Non-directional icons (anchor, archive,
   info, calendar etc.) stay as-is.

   Today the runtime doesn't emit data-dir-flip yet (icon() helper
   is opt-in-additive); this CSS hooks the future emission so a
   single helper change activates RTL across all directional uses.
   ────────────────────────────────────────────────────────────────── */
[dir="rtl"] .ds-icon[data-dir-flip="true"],
[dir="rtl"] .breadcrumb__sep .ds-icon,
[dir="rtl"] .pagination__btn .ds-icon,
[dir="rtl"] .select-trigger__icon .ds-icon {
  transform: scaleX(-1);
}

/* ──────────────────────────────────────────────────────────────────
   Forced-colors mode (Windows High Contrast). Per debug §2 +
   themes §9 + test §67-73: the system overrides custom colours
   with the OS theme. Several primitives lose their tone semantics
   silently — toasts, signing-states, hash-pills, sliders all flatten
   to a single system colour. This block restores semantic shape via
   system-color tokens (CanvasText, ButtonText, LinkText, etc.) and
   uses outlines instead of background fills where contrast matters.
   ────────────────────────────────────────────────────────────────── */
@media (forced-colors: active) {
  /* Tone-coded chips fall back to outlines + system text. */
  .toast,
  .signing-state,
  .icon-badge,
  .confirm-banner,
  .hash-pill,
  .network-badge,
  .crypto-pill,
  .balance-pill,
  .delta-chip,
  .empty-state {
    forced-color-adjust: none;
    border: 1px solid CanvasText;
    background: Canvas;
    color: CanvasText;
  }
  /* Buttons get a real button outline so they remain pressable in HC. */
  .button,
  .button-primary,
  .button-secondary,
  .stepper-input__btn,
  .pagination__btn,
  .toast__close,
  .hash-pill__btn,
  .composer__divider button,
  .tabs__option,
  .segmented__option,
  .select-trigger,
  .ds-toc__chip {
    forced-color-adjust: auto;
    border: 1px solid ButtonText;
  }
  /* Range slider track + thumb need explicit forced styling. */
  .range-slider input[type="range"] {
    background: Canvas;
    border: 1px solid CanvasText;
  }
  /* Brand mark stays branded — preserve the SVG colour. */
  .app-topbar__brand img,
  .tide-mark,
  .ds-icon,
  .spark-inline {
    forced-color-adjust: none;
  }
  /* Skip-link must stay visible against system canvas. */
  .skip-link {
    background: Canvas;
    color: LinkText;
    border: 2px solid LinkText;
  }
  /* Focus rings use system Highlight so they're guaranteed visible. */
  *:focus-visible {
    outline: 2px solid Highlight !important;
    outline-offset: 2px !important;
  }
}

/* ─────────────────────────────────────────────────────────────────
   Polish pass — DS polish appendix (additive)
   Date: 2026-04-29
   Source audits: public UI polish passes.

   Discipline: additive only · no class renames · no token deletions
   prefers-reduced-motion respected · no financial-numeral animation
   Skipped this round: B-18 scenario-ring stroke-dasharray draw-on
     (collides with inline attr set by renderer at app.js:3729-3732 —
     deferred to Product-surface polish once a non-conflicting strategy is chosen)
   ───────────────────────────────────────────────────────────────── */

/* A1 + B-01 — canonical motion + ease tokens */
:root {
  --motion-instant: 80ms;
  --motion-fast:    120ms;
  --motion-base:    150ms;
  --motion-slow:    240ms;
  --motion-entry:   450ms;
  --ease-out:       cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:        cubic-bezier(0.7, 0, 0.84, 0);
  --ease-spring:    cubic-bezier(0.34, 1.56, 0.64, 1);
}
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-instant: 0.01ms;
    --motion-fast:    0.01ms;
    --motion-base:    0.01ms;
    --motion-slow:    0.01ms;
    --motion-entry:   0.01ms;
  }
}

/* A2 — .num-tabular opt-in for ad-hoc numeric runs */
.num-tabular,
.num-tabular * {
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: "tnum" 1, "zero" 1;
}

/* A3 — display-tier optical letter-spacing */
.fs-display-tracked,
body[data-page="design-system"] .ds-shelf__title {
  letter-spacing: -0.012em;
}

/* A4 — tone-swatch hairline + single-tick luminance pulse on hover */
.ds-swatch {
  transition:
    border-color var(--motion-fast) var(--ease-out),
    background var(--motion-fast) var(--ease-out);
}
.ds-swatch:hover {
  border-color: color-mix(in srgb, var(--accent) 28%, var(--line-strong));
  background: color-mix(in srgb, var(--surface-tint) 60%, transparent);
}
.ds-swatch:hover .ds-swatch__chip {
  animation: ds-tone-pulse 200ms var(--ease-out) 1;
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent),
    inset 0 0 12px color-mix(in srgb, var(--surface) 35%, transparent);
}
@keyframes ds-tone-pulse {
  0%   { filter: brightness(1.00); }
  50%  { filter: brightness(1.12); }
  100% { filter: brightness(1.00); }
}
@media (prefers-reduced-motion: reduce) {
  .ds-swatch:hover .ds-swatch__chip { animation: none; }
}

/* A5 — swatch monogram re-tones on hover */
.ds-swatch:hover .ds-swatch__meta strong { color: var(--accent); }

/* A6 — radius tile hover */
.ds-radius {
  transition:
    border-color var(--motion-fast) var(--ease-out),
    transform var(--motion-fast) var(--ease-out);
}
.ds-radius:hover {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line-strong));
}
.ds-radius:hover .ds-radius__chip {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--line-strong));
  background: color-mix(in srgb, var(--accent) 30%, var(--surface));
}

/* A7 — type-row hover */
.ds-type-row { transition: border-color var(--motion-fast) var(--ease-out); }
.ds-type-row:hover { border-bottom-color: var(--line-strong); }
.ds-type-row:hover span {
  color: var(--accent);
  transition: color var(--motion-fast) var(--ease-out);
}

/* A8 — icon-cell hover with 1px glyph lift */
.ds-icon-cell {
  transition:
    border-color var(--motion-fast) var(--ease-out),
    background var(--motion-fast) var(--ease-out);
}
.ds-icon-cell > svg { transition: transform var(--motion-fast) var(--ease-out); }
.ds-icon-cell:hover {
  border-color: color-mix(in srgb, var(--accent) 32%, var(--line-strong));
  background: color-mix(in srgb, var(--surface-tint) 65%, transparent);
}
.ds-icon-cell:hover > svg { transform: translateY(-1px); color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .ds-icon-cell:hover > svg { transform: none; }
}

/* A9 — token-mark cell mirrors icon-cell */
.ds-token-mark-cell {
  transition:
    border-color var(--motion-fast) var(--ease-out),
    background var(--motion-fast) var(--ease-out);
}
.ds-token-mark-cell > :first-child { transition: transform var(--motion-fast) var(--ease-out); }
.ds-token-mark-cell:hover {
  border-color: color-mix(in srgb, var(--accent) 32%, var(--line-strong));
  background: color-mix(in srgb, var(--surface-tint) 65%, transparent);
}
.ds-token-mark-cell:hover > :first-child { transform: translateY(-1px); }
@media (prefers-reduced-motion: reduce) {
  .ds-token-mark-cell:hover > :first-child { transform: none; }
}

/* A10 — section-label introducer hairline */
body[data-page="design-system"] .ds-section .section-label::before {
  content: "";
  display: inline-block;
  width: 16px;
  height: 1px;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--accent) 70%, transparent) 0%,
    color-mix(in srgb, var(--accent) 12%, transparent) 100%
  );
  flex: 0 0 auto;
  margin-right: 0.05rem;
  transition: background var(--motion-fast) var(--ease-out);
}
body[data-page="design-system"] .ds-section:hover .section-label::before {
  background: linear-gradient(
    90deg,
    var(--accent) 0%,
    color-mix(in srgb, var(--accent) 20%, transparent) 100%
  );
}

/* A11 — kbd etched inset (additive over existing 2px bottom border) */
.kbd {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--surface-strong) 70%, transparent),
    inset 0 -1px 0 color-mix(in srgb, var(--line-strong) 50%, transparent);
  font-feature-settings: "calt" 1, "ss01" 1;
}
.kbd:hover {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--accent) 35%, transparent),
    inset 0 -1px 0 color-mix(in srgb, var(--accent) 22%, transparent);
}

/* A12 — discipline pilcrow + hover etch-deepen */
.ds-anti-list li {
  position: relative;
  transition: border-left-width var(--motion-fast) var(--ease-out);
}
.ds-anti-list li:hover {
  border-left-width: 4px;
  padding-left: calc(0.65rem - 1px);
  background: color-mix(in srgb, var(--rose) 7%, transparent);
}
.ds-anti-list li::before {
  content: "¶";
  position: absolute;
  left: -1.05rem;
  top: 0.4rem;
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: color-mix(in srgb, var(--rose) 60%, var(--muted));
  opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-out);
}
.ds-anti-list li:hover::before { opacity: 1; }

/* A13 — shelf header brand-gradient hairline */
body[data-page="design-system"] .ds-shelf__header {
  background-image: linear-gradient(
    90deg,
    color-mix(in srgb, var(--accent) 35%, transparent) 0%,
    color-mix(in srgb, var(--cyan) 25%, transparent) 50%,
    transparent 100%
  );
  background-size: 100% 1px;
  background-position: left bottom;
  background-repeat: no-repeat;
}

/* A14 — etched surface opt-in */
.surface-etched {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--surface-strong) 60%, transparent),
    inset 0 -1px 0 color-mix(in srgb, var(--line) 80%, transparent);
}
html[data-theme="dark"] .surface-etched {
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--text) 4%, transparent),
    inset 0 -1px 0 color-mix(in srgb, var(--bg) 40%, transparent);
}

/* A15 — glass surface opt-in */
.surface-glass {
  background: color-mix(in srgb, var(--surface) 70%, transparent);
}
@supports (backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px)) {
  .surface-glass {
    background: color-mix(in srgb, var(--surface) 50%, transparent);
    -webkit-backdrop-filter: blur(8px) saturate(140%);
    backdrop-filter: blur(8px) saturate(140%);
  }
}

/* A16 — focus-glow opt-in (flagship CTAs only — host must own background) */
@keyframes ds-focus-glow-rotate { to { transform: rotate(360deg); } }
.focus-glow { position: relative; }
.focus-glow:focus-visible::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  background: conic-gradient(
    from 0deg,
    var(--accent) 0%,
    var(--cyan) 25%,
    var(--accent) 50%,
    var(--cyan) 75%,
    var(--accent) 100%
  );
  opacity: 0.45;
  filter: blur(4px);
  z-index: -1;
  animation: ds-focus-glow-rotate 4s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .focus-glow:focus-visible::before { animation: none; }
}

/* A17 — section icon spring nod on hover */
body[data-page="design-system"] .ds-section__icon {
  transition:
    color var(--motion-fast) var(--ease-out),
    transform var(--motion-base) var(--ease-spring);
}
body[data-page="design-system"] .ds-section:hover .ds-section__icon {
  transform: rotate(-1.5deg) translateY(-0.5px);
}
@media (prefers-reduced-motion: reduce) {
  body[data-page="design-system"] .ds-section:hover .ds-section__icon { transform: none; }
}

/* A18 — icon-size-row hover mirrors type-row */
.ds-icon-size-row { transition: border-color var(--motion-fast) var(--ease-out); }
.ds-icon-size-row:hover { border-bottom-color: var(--line-strong); }
.ds-icon-size-row:hover span {
  color: var(--accent);
  transition: color var(--motion-fast) var(--ease-out);
}

/* B-02 — hash-pill paper-cut inset + ligatures + tabular-nums */
.hash-pill {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 8%, transparent);
  font-feature-settings: "calt" 1, "ss01" 1, "tnum" 1, "zero" 1;
  font-variant-numeric: tabular-nums slashed-zero;
}
html[data-theme="light"] .hash-pill {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 12%, transparent);
}

/* B-03 — hash-pill hover-reveal full payload (renderer opt-in: data-full) */
@media (hover: hover) and (pointer: fine) {
  .hash-pill[data-full] { position: relative; }
  .hash-pill[data-full]:hover::after,
  .hash-pill[data-full]:focus-within::after {
    content: attr(data-full);
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 50;
    padding: 0.32rem 0.55rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-xs);
    background: var(--surface);
    color: var(--text-strong);
    font-family: var(--ff-mono);
    font-size: var(--fs-2xs);
    font-variant-numeric: tabular-nums slashed-zero;
    letter-spacing: 0;
    white-space: nowrap;
    box-shadow: 0 4px 12px color-mix(in srgb, var(--bg-strong) 40%, transparent);
    pointer-events: none;
  }
}

/* B-04 — mainnet single-tick announce on entry */
@media (prefers-reduced-motion: no-preference) {
  .network-badge--mainnet .network-badge__dot {
    animation: networkPulse 1.2s ease-out 1 both;
  }
}

/* B-05 — crypto-pill label/value divider hairline */
.crypto-pill strong {
  padding-left: 0.5rem;
  margin-left: 0.1rem;
  border-left: 1px solid color-mix(in srgb, var(--muted) 18%, transparent);
}
html[data-theme="light"] .crypto-pill strong {
  border-left-color: color-mix(in srgb, var(--muted) 26%, transparent);
}

/* B-06 — signing-state active modifier (NEW) */
.signing-state--active { position: relative; z-index: 1; }
.signing-state--active::before {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: calc(var(--radius-sm) + 3px);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  z-index: -1;
  pointer-events: none;
}
.signing-state--pending.signing-state--active::before  { background: color-mix(in srgb, var(--muted)  14%, transparent); }
.signing-state--signing.signing-state--active::before  { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.signing-state--signed.signing-state--active::before   { background: color-mix(in srgb, var(--cyan)   14%, transparent); }
.signing-state--receipt.signing-state--active::before  { background: color-mix(in srgb, var(--mint)   14%, transparent); }
.signing-state--failed.signing-state--active::before   { background: color-mix(in srgb, var(--rose)   14%, transparent); }
@media (prefers-reduced-motion: no-preference) {
  .signing-state--active {
    animation: signing-state-active-pop 200ms var(--ease-out) both;
  }
}
@keyframes signing-state-active-pop {
  0%   { transform: scale(0.97); }
  60%  { transform: scale(1.03); }
  100% { transform: scale(1); }
}

/* B-07 — event-chart marker hover (renderer opt-in via data-event-line / data-event-marker) */
.event-chart [data-event-line] { transition: stroke-opacity 120ms ease; }
.event-chart [data-event-line]:hover,
.event-chart g:hover [data-event-line] { stroke-opacity: 1; }
.event-chart [data-event-marker] { transition: r 120ms ease, fill-opacity 120ms ease; }
.event-chart g:hover [data-event-marker] { r: 4.5; fill-opacity: 1; }

/* B-08 — spark-inline left-to-right draw-on (one-time) */
@media (prefers-reduced-motion: no-preference) {
  .spark-inline svg path {
    stroke-dasharray: 200;
    stroke-dashoffset: 200;
    animation: spark-inline-draw 300ms var(--ease-out) 0s 1 both;
  }
}
@keyframes spark-inline-draw { to { stroke-dashoffset: 0; } }

/* B-09 — delta-chip first-paint pulse (renderer opt-in: data-changed) */
@media (prefers-reduced-motion: no-preference) {
  .delta-chip[data-changed="true"] {
    animation: delta-chip-pulse 180ms var(--ease-out) 1 both;
  }
}
@keyframes delta-chip-pulse {
  0%   { transform: scale(1); }
  55%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}

/* B-10 — token-amount-row stack hairline (uses :has) */
.token-amount-row:has(+ .token-amount-row) {
  margin-bottom: 0;
  border-bottom-color: color-mix(in srgb, var(--muted) 14%, transparent);
}
.token-amount-row + .token-amount-row { margin-top: 0.25rem; }

/* B-11 — meta-line__value mono-hash treatment (renderer opt-in: data-mono-hash) */
.meta-line__value[data-mono-hash="true"] {
  display: inline-block;
  max-width: 18ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-break: normal;
  font-variant-numeric: tabular-nums slashed-zero;
  vertical-align: bottom;
  transition: max-width 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .meta-line__value[data-mono-hash="true"]:hover,
  .meta-line__value[data-mono-hash="true"]:focus-visible { max-width: 64ch; }
}

/* B-12 — fact-row tone left-edge stripe */
.fact-row[data-tone="success"],
.fact-row[data-tone="warn"],
.fact-row[data-tone="danger"] {
  padding-left: 0.85rem;
  border-left: 2px solid var(--line);
}
.fact-row[data-tone="success"] { border-left-color: color-mix(in srgb, var(--mint)  60%, transparent); }
.fact-row[data-tone="warn"]    { border-left-color: color-mix(in srgb, var(--amber) 60%, transparent); }
.fact-row[data-tone="danger"]  { border-left-color: color-mix(in srgb, var(--rose)  60%, transparent); }

/* B-13 — fact-row hover value bump */
.fact-row strong { transition: transform var(--motion-fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .fact-row:hover strong { transform: translateX(1px); }
}

/* B-14 — surface accent-edge opt-in (data-edge="accent") */
.surface[data-edge="accent"] {
  position: relative;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 8%, transparent);
}
.surface[data-edge="accent"]::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--radius-md);
  right: var(--radius-md);
  height: 1px;
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--accent) 60%, transparent) 35%,
    color-mix(in srgb, var(--accent) 60%, transparent) 65%,
    transparent 100%
  );
  pointer-events: none;
}

/* B-15 — neutral trust banners stay flat on app surfaces. */
.trust-banner--neutral { position: relative; overflow: hidden; }

/* B-16 — allocation-bar segment hairline divider */
.allocation-bar__seg {
  box-shadow: inset -1px 0 0 0 color-mix(in srgb, var(--bg-strong) 70%, transparent);
}
.allocation-bar__seg:last-child { box-shadow: none; }

/* B-17 — Polish pass reduced-motion register for new animations */
@media (prefers-reduced-motion: reduce) {
  .signing-state--active,
  .delta-chip[data-changed="true"],
  .spark-inline svg path,
  .stress-spark .stress-spark-bar,
  .network-badge--mainnet .network-badge__dot {
    animation: none !important;
  }
  .meta-line__value[data-mono-hash="true"],
  .fact-row strong,
  .event-chart [data-event-line],
  .event-chart [data-event-marker] {
    transition-duration: 0.01s !important;
  }
}

/* P-01 — composer row :focus-within accent halo */
.composer__row:focus-within {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--line-strong));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 32%, transparent),
    0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
  transition:
    border-color var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-fast) var(--ease-out);
}

/* P-02 — composer divider 90deg tilt (lighter than the prior 180deg flip) */
.composer__divider button {
  transition:
    transform var(--motion-fast) var(--ease-out),
    color var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-fast) var(--ease-out);
}
.composer__divider button:hover {
  transform: rotate(90deg);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent);
}
.composer__divider button:active {
  transform: rotate(90deg) translateY(1px);
  transition-duration: 80ms;
}

/* P-03 — token-picker chevron nudge */
.collateral-asset-trigger > svg:last-child,
.collateral-asset-trigger .collateral-asset-trigger-chevron {
  transition: transform var(--motion-fast) var(--ease-out);
}
.collateral-asset-trigger:hover > svg:last-child,
.collateral-asset-trigger:hover .collateral-asset-trigger-chevron {
  transform: translateY(1px);
}
.collateral-picker[open] .collateral-asset-trigger > svg:last-child,
.collateral-picker[open] .collateral-asset-trigger .collateral-asset-trigger-chevron {
  transform: rotate(180deg);
}

/* P-04 — segmented active accent ring */
.segmented__option {
  transition:
    background var(--motion-fast) var(--ease-out),
    color var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-fast) var(--ease-out);
}
.segmented__option[aria-pressed="true"],
.segmented__option.is-active,
.segmented--exclusive .segmented__option[aria-checked="true"],
.segmented--exclusive .segmented__option:has(input:checked) {
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, var(--line-strong)),
    0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .segmented__option { transition: none; }
}

/* P-05 — button press 1px translate (additive over existing scale rule) */
.button:active:not(:disabled) {
  transform: translateY(1px);
  transition-duration: 80ms;
}
@media (prefers-reduced-motion: reduce) {
  .button:active:not(:disabled) { transform: none; }
}

/* P-06 — primary CTA hover lift + accent shadow */
.button-primary {
  transition:
    background-color var(--motion-base) var(--ease-out),
    transform var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-base) var(--ease-out);
}
.button-primary:not(:disabled):hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px -4px color-mix(in srgb, var(--accent) 45%, transparent);
}
.button-primary:not(:disabled):active {
  transform: translateY(0);
  box-shadow: 0 1px 3px -1px color-mix(in srgb, var(--accent) 35%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .button-primary:not(:disabled):hover,
  .button-primary:not(:disabled):active { transform: none; }
}

/* P-07 — explicit disabled paint for primary */
.button-primary:disabled,
.button-primary[aria-disabled="true"] {
  background: color-mix(in srgb, var(--muted) 22%, var(--surface-soft));
  color: var(--muted);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}
.button:disabled,
.button[aria-disabled="true"] { cursor: not-allowed; }

/* P-08 — narrow gradient modifier (one anchor CTA per surface) */
.button-primary--gradient {
  background: linear-gradient(102deg, var(--accent-strong) 0%, color-mix(in srgb, var(--accent) 92%, var(--accent-strong)) 100%);
}
.button-primary--gradient:not(:disabled):hover {
  background: linear-gradient(102deg, var(--accent) 0%, color-mix(in srgb, var(--accent) 88%, var(--accent-strong)) 100%);
}

/* P-09 — status-timeline current-step halo */
.status-timeline__dot {
  transition:
    background-color 200ms ease,
    border-color 200ms ease,
    box-shadow 200ms ease;
}
.status-timeline__step--current .status-timeline__dot {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent);
}
.status-timeline__step--failed .status-timeline__dot {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--rose) 18%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .status-timeline__dot { transition: none; }
}

/* P-10 — signing-state--signing static accent halo */
.signing-state--signing {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 12%, transparent);
}

/* P-11 — banner first-paint slide-in via @starting-style */
@media (prefers-reduced-motion: no-preference) {
  .confirm-banner,
  .trust-banner {
    transition: opacity 200ms ease, transform 200ms ease;
  }
  @supports (transition-behavior: allow-discrete) {
    @starting-style {
      .confirm-banner,
      .trust-banner {
        opacity: 0;
        transform: translateY(-4px);
      }
    }
  }
}

/* P-13 — dialog.modal entry via @starting-style (native dialog focus trap intact) */
@media (prefers-reduced-motion: no-preference) {
  @supports (transition-behavior: allow-discrete) {
    dialog.modal {
      transition:
        opacity 220ms ease,
        transform 220ms ease,
        overlay 220ms ease allow-discrete,
        display 220ms ease allow-discrete;
    }
    @starting-style {
      dialog.modal[open] {
        opacity: 0;
        transform: translateY(4px);
      }
    }
    dialog.modal::backdrop {
      transition:
        background 220ms ease,
        backdrop-filter 220ms ease,
        overlay 220ms ease allow-discrete,
        display 220ms ease allow-discrete;
    }
    @starting-style {
      dialog.modal[open]::backdrop {
        background: transparent;
        backdrop-filter: blur(0);
      }
    }
  }
}

/* P-15 — composer row invalid state (rose halo) */
.composer__row:has(input:invalid:not(:placeholder-shown)),
.composer__row.has-error {
  border-color: color-mix(in srgb, var(--rose) 55%, var(--line-strong));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--rose) 32%, transparent),
    0 0 0 3px color-mix(in srgb, var(--rose) 12%, transparent);
}

/* P-16 — runtime-polish skeleton: pause shimmer under reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .scenario-workbench-host:empty::before,
  #readout-hero:empty::before,
  #results-market-forecast:empty::before,
  #results-scenarios:empty::before,
  #action-log:empty::before {
    animation: none !important;
    background:
      linear-gradient(color-mix(in srgb, var(--muted) 22%, transparent), color-mix(in srgb, var(--muted) 22%, transparent)) 1rem 1rem / 32% 0.8rem no-repeat,
      linear-gradient(color-mix(in srgb, var(--muted) 22%, transparent), color-mix(in srgb, var(--muted) 22%, transparent)) 1rem 2.6rem / 68% 0.7rem no-repeat,
      linear-gradient(color-mix(in srgb, var(--muted) 22%, transparent), color-mix(in srgb, var(--muted) 22%, transparent)) 1rem 4.1rem / calc(100% - 2rem) 7rem no-repeat,
      var(--surface);
  }
}

/* P-17 — kbd press-flash unscoped from /design-system (was page-locked) */
.kbd--pressed {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

/* P-18 — kbd hover lift (1px translate-y up + accent border tint) */
.kbd {
  transition:
    background var(--motion-instant) var(--ease-out),
    border-color var(--motion-instant) var(--ease-out),
    color var(--motion-instant) var(--ease-out),
    transform var(--motion-fast) var(--ease-out);
}
.kbd:hover {
  transform: translateY(-1px);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-strong));
  color: var(--accent);
}
@media (prefers-reduced-motion: reduce) {
  .kbd:hover { transform: none; }
}
/* ── End Polish pass polish appendix ───────────────────────────── */

/* ─────────────────────────────────────────────────────────────────
   Product-surface polish — product-surface polish (additive)
   Date: 2026-04-29
   Source: public UI polish pass D
   Scope: actual product surfaces — /setup, /results, /live —
   plus cross-cutting (network badge, trust banner, paired scales).
   Discipline: same as D.34 — additive, no class renames, no token
   deletions, prefers-reduced-motion respected, no financial-numeral
   animation, color-mix() never raw rgba/hex.
   ───────────────────────────────────────────────────────────────── */

/* D-11 — tx-row hover row-tint (single-row hover signal, no zebra) */
.tx-row {
  border-radius: var(--radius-xs);
  transition: background-color var(--motion-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .tx-row:hover {
    background: color-mix(in srgb, var(--surface-tint) 50%, transparent);
  }
}
@media (prefers-reduced-motion: reduce) {
  .tx-row { transition: none; }
}

/* D-12 — trust-banner top-edge tone gradient hairline (composes B-14 pattern) */
.trust-banner {
  position: relative;
  overflow: hidden;
}
.trust-banner::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--radius-md);
  right: var(--radius-md);
  height: 1px;
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--accent) 50%, transparent) 35%,
    color-mix(in srgb, var(--accent) 50%, transparent) 65%,
    transparent 100%
  );
  pointer-events: none;
}
.trust-banner--warn::before {
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--amber) 60%, transparent) 35%,
    color-mix(in srgb, var(--amber) 60%, transparent) 65%,
    transparent 100%
  );
}
.trust-banner--danger::before {
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--rose) 60%, transparent) 35%,
    color-mix(in srgb, var(--rose) 60%, transparent) 65%,
    transparent 100%
  );
}
.trust-banner--neutral::before {
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--accent) 60%, transparent) 35%,
    color-mix(in srgb, var(--accent) 60%, transparent) 65%,
    transparent 100%
  );
}

/* D-14 — paired-scales needle constant glow (only inside .scale-pair) */
.scale-pair > .position-scale .position-scale__needle-dot,
.scale-pair > .price-scale .price-scale__needle-dot {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--cyan) 80%, transparent),
    0 0 6px color-mix(in srgb, var(--cyan) 38%, transparent),
    0 0 14px color-mix(in srgb, var(--cyan) 22%, transparent);
}
.scale-pair > .position-scale .position-scale__needle[data-tone="warn"] .position-scale__needle-dot,
.scale-pair > .price-scale .price-scale__needle[data-tone="warn"] .price-scale__needle-dot {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--amber) 80%, transparent),
    0 0 8px color-mix(in srgb, var(--amber) 45%, transparent),
    0 0 16px color-mix(in srgb, var(--amber) 24%, transparent);
}
.scale-pair > .position-scale .position-scale__needle[data-tone="danger"] .position-scale__needle-dot,
.scale-pair > .price-scale .price-scale__needle[data-tone="danger"] .price-scale__needle-dot {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--rose) 80%, transparent),
    0 0 8px color-mix(in srgb, var(--rose) 45%, transparent),
    0 0 16px color-mix(in srgb, var(--rose) 24%, transparent);
}
/* ── End Product-surface polish foundation appendix ─────────────────────────── */

/* ─────────────────────────────────────────────────────────────────
   Phase D.36 — defensive UX fixes (additive)
   Date: 2026-04-29
   - Token-mark proportional sizing in stat-style rows (icon was
     dominating small amount-text below large $-headline).
   - Guardrails chip-row wraps so Polymarket / Kalshi can't get
     clipped past the right edge of the segmented container.
   ───────────────────────────────────────────────────────────────── */

/* D-36-1 — token-mark proportional in stat rows. Pattern: large $-amount
   on top, small "0.500 [icon] wBTC" detail row below. Default visual-mark
   is 24-28px which dominates --fs-xs detail text. Cap to 16px in any
   stat-style row + force baseline-friendly alignment. */
.ws-position-metrics .visual-mark,
.ws-position-metrics .token-mark,
.ws-position-metrics .entity-inline .visual-mark,
.entity-copy .visual-mark,
.entity-copy .token-mark,
.fact-list .visual-mark,
.fact-list-compact .visual-mark,
.metric .visual-mark,
.metric .token-mark,
.policy-stats .visual-mark,
.policy-stats .token-mark,
.kpi-row .visual-mark,
.kpi-row .token-mark {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
}
.ws-position-metrics .entity-inline,
.entity-inline {
  align-items: center;
  gap: 0.35rem;
}

/* D-36-2 — guardrails chips wrap so Polymarket + Kalshi never get
   clipped past the right edge. Default .segmented is inline-flex
   without wrap; this override is scoped to the chart's chip row only,
   so other segmented instances (mode card, network selector) stay
   single-line as designed. */
.guardrails-chart__chips,
.guardrails-chart__chips.segmented {
  flex-wrap: wrap;
  row-gap: 4px;
}

/* D-36-3 — soften P-04 segmented active outer halo. 3px halo could
   overlap neighbor chips in tight rows (guardrails chip row). Drop
   to 2px so neighbors stay readable while the active state still
   reads as elevated. */
.segmented__option[aria-pressed="true"],
.segmented__option.is-active,
.segmented--exclusive .segmented__option[aria-checked="true"],
.segmented--exclusive .segmented__option:has(input:checked) {
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, var(--line-strong)),
    0 0 0 2px color-mix(in srgb, var(--accent) 12%, transparent);
}
/* ── End Phase D.36 defensive fixes ─────────────────────────────── */

/* ─────────────────────────────────────────────────────────────────
   Fit-and-finish pass — fancy details + deadweight removal (additive)
   Date: 2026-04-29
   Source: public UI polish pass E
   Reference: 7k / NAVI / Momentum / Magma / Hyperliquid / Backpack
   Discipline: same as D.34-D.36 — additive, no class renames, no
   token deletions, prefers-reduced-motion respected, no
   financial-numeral animation, color-mix() only.
   ───────────────────────────────────────────────────────────────── */

/* E-01 removed — setup/results/live use functional surfaces only. */

/* E-02 — topbar brand-mark hover/focus micro-glow */
.app-topbar__brand img {
  transition: filter var(--motion-base) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .app-topbar__brand:hover img,
  .app-topbar__brand:focus-visible img {
    filter:
      drop-shadow(0 0 4px color-mix(in srgb, var(--accent) 38%, transparent))
      drop-shadow(0 0 1px color-mix(in srgb, var(--cyan) 28%, transparent));
  }
}
@media (prefers-reduced-motion: reduce) {
  .app-topbar__brand img { transition: none; }
}

/* E-04 — system-critical banners opt into surface-glass (composes A15) */
.trust-banner[data-forecast-stale-banner],
.setup-primer.setup-primer--judge {
  background: color-mix(in srgb, var(--surface) 70%, transparent);
}
@supports (backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px)) {
  .trust-banner[data-forecast-stale-banner],
  .setup-primer.setup-primer--judge {
    background: color-mix(in srgb, var(--surface) 55%, transparent);
    -webkit-backdrop-filter: blur(8px) saturate(140%);
    backdrop-filter: blur(8px) saturate(140%);
  }
}

/* E-05 — wallet-connect ready-to-sign top-edge hairline (renderer-opt-in) */
.wallet-connect-btn[data-connected="true"],
.wallet-pill__trigger[data-connected="true"] {
  position: relative;
  overflow: hidden;
}
.wallet-connect-btn[data-connected="true"]::before,
.wallet-pill__trigger[data-connected="true"]::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--radius-xs);
  right: var(--radius-xs);
  height: 1px;
  background: linear-gradient(
    to right,
    transparent 0%,
    color-mix(in srgb, var(--mint) 70%, transparent) 35%,
    color-mix(in srgb, var(--mint) 70%, transparent) 65%,
    transparent 100%
  );
  pointer-events: none;
}

/* E-06 — active scope mode 2px accent left-bar (composes P-04 inset) */
.mode-card__opt.segmented__option[aria-pressed="true"],
.mode-card__opt.segmented__option:has(input:checked) {
  position: relative;
}
.mode-card__opt.segmented__option[aria-pressed="true"]::after,
.mode-card__opt.segmented__option:has(input:checked)::after {
  content: "";
  position: absolute;
  left: 0;
  top: 18%;
  bottom: 18%;
  width: 2px;
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--accent) 75%, transparent);
  pointer-events: none;
}
.mode-card__opt.segmented__option[aria-pressed="true"][data-scope="live"]::after,
.mode-card__opt.segmented__option:has(input:checked)[data-scope="live"]::after {
  background: color-mix(in srgb, var(--mint) 80%, transparent);
}

/* E-07 — trust-strip in-header lighter container (chips dominate) */
.trust-labels.trust-strip--in-header {
  background: color-mix(in srgb, var(--surface-soft) 28%, transparent);
}

/* E-08 — paired-scales live-state breathing halo (renderer-opt-in) */
@keyframes ds-needle-breathe {
  0%, 100% { box-shadow:
    0 0 0 1px color-mix(in srgb, var(--cyan) 80%, transparent),
    0 0 6px  color-mix(in srgb, var(--cyan) 38%, transparent),
    0 0 12px color-mix(in srgb, var(--cyan) 18%, transparent); }
  50%      { box-shadow:
    0 0 0 1px color-mix(in srgb, var(--cyan) 80%, transparent),
    0 0 10px color-mix(in srgb, var(--cyan) 50%, transparent),
    0 0 20px color-mix(in srgb, var(--cyan) 28%, transparent); }
}
.position-scale[data-live="true"] .position-scale__needle-dot,
.price-scale[data-live="true"] .price-scale__needle-dot {
  animation: ds-needle-breathe 2.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .position-scale[data-live="true"] .position-scale__needle-dot,
  .price-scale[data-live="true"] .price-scale__needle-dot { animation: none; }
}
/* ── End Fit-and-finish pass foundation appendix ─────────────────────────── */

/* >>> 10-results-workspace.css >>> */
.rg-cell {
  display: flex;
  flex-direction: column;
  /* Phase D.31 — was 0.1rem (~1.6px) — same sub-pixel fusion class as
     the chip+sub gaps fixed in D.30.0. Aligned to var(--space-1). */
  gap: var(--space-1);
  min-width: 0;
}

.rg-label {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.rg-cell strong {
  font-size: var(--fs-md);
  font-variant-numeric: tabular-nums;
}

.judge-demo-frame[hidden] {
  display: none;
}

.judge-compare-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.judge-compare-card {
  min-width: 0;
  border: 1px solid color-mix(in srgb, var(--line) 68%, transparent);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  background: color-mix(in srgb, var(--surface-soft) 58%, transparent);
}

.judge-compare-card span,
.decision-atlas__item span {
  display: block;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.judge-compare-card h3 {
  margin: 0.35rem 0 0.75rem;
  font-size: var(--fs-lg);
}

.judge-compare-card ul {
  margin: 0;
  padding-left: 1rem;
  color: var(--muted);
}

.judge-compare-card li + li {
  margin-top: 0.35rem;
}

.judge-compare-card--tide {
  border-color: color-mix(in srgb, var(--mint) 34%, var(--line));
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--mint) 12%, transparent),
    color-mix(in srgb, var(--surface-soft) 68%, transparent)
  );
}

.decision-atlas {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.decision-atlas__item {
  min-width: 0;
  border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
  padding-top: var(--space-3);
}

.decision-atlas__item strong {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--fs-md);
}

.decision-atlas__item p {
  margin: 0.35rem 0 0;
  color: var(--muted);
}

.decision-atlas__share {
  margin-top: var(--space-1);
}

@media (max-width: 760px) {
  .judge-compare-grid,
  .decision-atlas {
    grid-template-columns: 1fr;
  }
}

.rg-sub {
  color: var(--muted);
  font-size: var(--fs-2xs);
}

.stress-ladder {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-bottom: 0.15rem;
  scrollbar-color: color-mix(in srgb, var(--accent) 72%, transparent) transparent;
  scrollbar-width: thin;
  position: relative;
  scroll-snap-type: x proximity;
}

.stress-ladder__track {
  min-width: max(100%, calc(var(--scenario-count, 6) * 6.1rem));
}

@media (max-width: 760px) {
  .stress-ladder {
    margin-inline: calc(var(--space-2) * -1);
    padding-inline: var(--space-2);
    -webkit-overflow-scrolling: touch;
  }

  .stress-ladder::after {
    content: "";
    position: sticky;
    right: calc(var(--space-2) * -1);
    bottom: 0.15rem;
    display: block;
    width: 2.25rem;
    height: 0.25rem;
    margin-left: auto;
    border-radius: var(--radius-pill);
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 78%, transparent));
    pointer-events: none;
  }

  .stress-ladder__track {
    min-width: max(100%, calc(var(--scenario-count, 6) * 4.75rem));
  }
}

@media (max-width: 560px) {
  .stress-ladder {
    margin-inline: 0;
    padding-inline: 0;
    overflow-x: visible;
  }

  .stress-ladder::after {
    display: none;
  }

  .stress-ladder__track {
    min-width: 0;
  }

  .stress-ladder-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2);
    padding-inline: 0;
  }

  .stress-ladder-cell {
    min-width: 0;
    border: 1px solid color-mix(in srgb, var(--ladder-tone) 28%, var(--line));
    border-top-width: 2px;
    border-radius: var(--radius-sm);
    padding: 0.5rem;
  }
}

.stress-spark {
  display: flex;
  align-items: flex-end;
  /* Phase D.31 — was 3px (sub-token, fused spark bars at squint). */
  gap: var(--space-1);
  height: 48px;
  padding: 0.6rem 0.5rem;
}

.stress-ladder .spark-detail-popup {
  margin: 0.55rem 0.25rem 0;
}

.stress-spark-bar {
  flex: 1;
  min-width: 0;
  border-radius: var(--radius-pill) var(--radius-pill) 0 0;
  background: var(--accent);
  opacity: 0.85;
  transition: opacity 200ms, background 200ms;
  position: relative;
}

.stress-spark-bar:hover {
  opacity: 1;
}

/* Phase D.30.3 — was raw --cyan/--mint/--amber/--violet/--rose which
   over-shouted on the surface-soft track. The sibling .scenario-card
   stripes (~650 lines below) already use the color-mix(... 72%,
   transparent) recipe; these spark bars now match per §9.8. */
.stress-spark-bar[data-spark-state="Observe"]        { background: color-mix(in srgb, var(--cyan)   72%, transparent); }
.stress-spark-bar[data-spark-state="Maintain"]       { background: color-mix(in srgb, var(--mint)   72%, transparent); }
.stress-spark-bar[data-spark-state="BuildBuffer"]    { background: color-mix(in srgb, var(--amber)  72%, transparent); }
.stress-spark-bar[data-spark-state="DeRisk"]         { background: color-mix(in srgb, var(--violet) 72%, transparent); }
.stress-spark-bar[data-spark-state="StressLockdown"] { background: color-mix(in srgb, var(--rose)   72%, transparent); }

.stress-spark-bar.is-selected {
  opacity: 1;

  border-radius: var(--radius-pill) var(--radius-pill) 0 0;
}

.stress-ladder-strip {
  display: grid;
  grid-template-columns: repeat(var(--scenario-count, 6), minmax(0, 1fr));
  gap: var(--space-1);
  padding: 0 0.5rem 0.1rem;
}

.stress-ladder-cell {
  --ladder-tone: var(--line-strong);
  min-width: 0;
  appearance: none;
  border: 0;
  border-top: 2px solid color-mix(in srgb, var(--ladder-tone) 78%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--line) 62%, transparent);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
  scroll-snap-align: start;
  cursor: pointer;
  display: grid;
  gap: 0.16rem;
  padding: 0.42rem 0.38rem 0.5rem;
  transition: background 0.16s ease, border-color 0.16s ease;
}

.stress-ladder-cell:hover,
.stress-ladder-cell:focus-visible,
.stress-ladder-cell.is-selected {
  background: color-mix(in srgb, var(--ladder-tone) 8%, transparent);
  border-bottom-color: color-mix(in srgb, var(--ladder-tone) 32%, var(--line));
}

.stress-ladder-cell:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--ladder-tone) 62%, transparent);
  outline-offset: 2px;
}

.stress-ladder-cell[data-state="Observe"]        { --ladder-tone: var(--cyan); }
.stress-ladder-cell[data-state="Maintain"]       { --ladder-tone: var(--mint); }
.stress-ladder-cell[data-state="BuildBuffer"]    { --ladder-tone: var(--amber); }
.stress-ladder-cell[data-state="DeRisk"]         { --ladder-tone: var(--violet); }
.stress-ladder-cell[data-state="StressLockdown"] { --ladder-tone: var(--rose); }

.stress-ladder-cell__kicker,
.stress-ladder-cell__meta {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-2xs);
  color: var(--muted);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.stress-ladder-cell__kicker {
  text-transform: uppercase;
}

.stress-ladder-cell__main {
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
}

.stress-ladder-cell__main strong {
  color: var(--text-strong);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

.stress-ladder-cell__main span,
.stress-ladder-cell__meta span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.stress-ladder-cell__main span {
  color: var(--text);
  font-size: var(--fs-xs);
  font-weight: 700;
}

.stress-ladder-cell__meta {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.35rem;
}

.spark-detail-popup {
  padding: 0.65rem 0.85rem;
  border-radius: var(--radius-sm);
  background: var(--surface-strong);
  border: 1px solid var(--line-strong);

  animation: fadeSlideIn 0.15s ease;
}

.spark-detail-popup[hidden] { display: none; }

.spark-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

.spark-detail-head strong {
  font-size: var(--fs-base);
}

.spark-detail-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.3rem 0.6rem;
}

.spark-detail-grid div {
  display: flex;
  flex-direction: column;
  /* Phase D.31 — was 0.1rem (~1.6px). Same sub-pixel fusion class as
     .rg-cell. Aligned to var(--space-1). */
  gap: var(--space-1);
}

.spark-detail-grid span {
  font-size: var(--fs-2xs);
  color: var(--muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.spark-detail-grid strong {
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}

.spark-detail-explain {
  margin: 0.4rem 0 0;
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.5;
}

@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

.payout-range-bar {
  position: relative;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-soft);
  overflow: hidden;
  margin: 0.4rem 0;
}

.payout-range-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: var(--radius-pill);
  /* T21 fix — was var(--surface) which made the fill invisible
     against the surface-coloured card. The bar visualises payout
     range, so the fill should read in accent. */
  background: var(--accent);
  transition: width var(--motion-slow) ease;
}


@media (max-width: 1080px) {
.page-header, .page-tools, .section-head, .route-card-head, .saved-card-head, .log-card-head {
    flex-direction: column;
    align-items: stretch;
  }

.content-grid-main, .fact-list-compact, .operator-grid, .operator-facts {
    grid-template-columns: 1fr;
  }

.page-tools {
    justify-items: start;
  }

.route-metrics {
    grid-template-columns: 1fr;
  }

.form-grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

.review-item {
    grid-template-columns: auto minmax(0, 1fr);
  }

.review-item .review-flag {
    grid-column: 2;
    justify-self: start;
  }

}

@media (max-width: 1024px) {
body[data-page="results"] .content-grid-main {
    grid-template-columns: 1fr;
  }

.operator-grid {
    grid-template-columns: 1fr;
  }

}

.app-main--topbar .page-stack {
  min-width: 0;
}

@media (max-width: 760px) {
h1 {
    font-size: 1.35rem;
    max-width: none;
  }

.form-grid-2, .form-grid-3, .operator-form-grid {
    grid-template-columns: 1fr;
  }

.action-cluster {
    width: 100%;
  }

.review-item {
    grid-template-columns: auto minmax(0, 1fr);
  }

.review-item .review-flag {
    grid-column: 2;
    justify-self: start;
  }

.button {
    width: 100%;
  }

}

@keyframes pulseGlow {
  0%,
  100% {
    opacity: 0.62;
    text-shadow: 0 0 0 color-mix(in srgb, var(--cyan-soft, var(--accent)) 0%, transparent);
  }
  50% {
    opacity: 1;
    text-shadow: 0 0 12px color-mix(in srgb, var(--cyan-soft, var(--accent)) 70%, transparent);
  }
}

.metric-card {
  transition: transform 0.15s ease;
}

.button-primary:active {
  transform: scale(0.97);
}

.button-secondary:active {
  transform: scale(0.97);
}

.button[disabled] {
  opacity: 0.6;
  pointer-events: none;
}

.saved-card {
  transition: background-color 0.2s ease;
}

.status-line[data-status="running"] {
  animation: pulseGlow 1.5s ease-in-out infinite;
}

.btn-spinner {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  /* C.2.4 R7 — was hardcoded white (#fff + rgba(255,255,255,…));
     fails on light theme. currentColor inherits the parent button's
     text colour (white on .button-primary, --text-strong on ghost),
     so the spinner reads in both contexts + both themes. */
  border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: btnSpin 0.6s linear infinite;
  vertical-align: middle;
}

.button.is-running {
  pointer-events: none;
}

@keyframes btnSpin {
  to { transform: rotate(360deg); }
}

/* Phase D.28 — .ws-step-list-compact removed; consumed only inside
   the dead `renderLiveGettingStarted` (purged in D.28.2). DS rule §9.10. */
.ws-dash-label {
  display: block;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 0.55rem;
}

.ws-dash-sub {
  color: var(--muted);
  font-size: var(--fs-xs);
}

/* Phase D.2 — semantic tone classes for ws-position-metrics values
   so the markup stops carrying inline color:var(--*-text) style attrs.
   Mint = healthy/payout, cyan = live/LTV. */
.ws-dash-strong--mint { color: var(--mint-text); }
.ws-dash-strong--cyan { color: var(--cyan-text); }

/* Phase D.28 — .ws-step-list, .ws-step, .ws-step-num, .ws-step strong,
   .ws-step p removed. Consumed only inside the dead
   `renderLiveGettingStarted` (purged in D.28.2). DS rule §9.10. */

/* Workspace filter is a toolbar, not a third dashboard card. The
   portfolio hero already carries totals; filters should sit lightly
   between portfolio and list. */
.workspace-head {
  display: grid;
  gap: var(--space-3);
  position: relative;
  padding: clamp(1.1rem, 1.8vw, 1.8rem);
}

.workspace-head__top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "label controls";
  align-items: center;
  column-gap: var(--space-3);
  row-gap: var(--space-1);
  min-width: 0;
}

.workspace-head__top-actions {
  grid-area: controls;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  max-width: 100%;
}

.workspace-head__top > .section-label {
  grid-area: label;
  margin: 0;
  align-self: center;
  white-space: nowrap;
}

.workspace-head__visual {
  display: grid;
  align-content: end;
  justify-items: end;
  gap: var(--space-2);
  min-width: 0;
  text-align: right;
}

.workspace-head__visual .ds-hero__chart {
  justify-content: flex-end;
  min-width: 0;
  max-width: 100%;
}

.workspace-head__visual .ds-hero__chart .spark-inline {
  width: min(20rem, 100%);
  max-width: 100%;
  padding-inline: 0.12rem;
}

.workspace-head__visual .ds-hero__chart .spark-inline svg path {
  animation: none;
  stroke-dasharray: none;
  stroke-dashoffset: 0;
}

.workspace-head__visual .status-line {
  justify-self: end;
  max-width: 42ch;
  color: var(--muted);
  text-align: right;
  font-size: var(--fs-xs);
}

.workspace-head .trust-labels.trust-strip--workspace {
  align-self: center;
  justify-content: flex-start;
  flex-wrap: nowrap;
  margin-top: 0;
  padding: 0;
  border: 0;
  background: transparent;
  max-width: 100%;
  max-height: 2.35rem;
  min-width: 0;
  overflow: hidden;
  width: 100%;
}

.workspace-head__main {
  display: grid;
  grid-template-columns: minmax(20rem, 1fr) minmax(20rem, 0.78fr);
  gap: var(--space-5);
  align-items: end;
  min-width: 0;
}

.workspace-head__anchor {
  min-width: 0;
}

.workspace-head__sub-delta--down {
  color: var(--rose-text);
}

.workspace-head__metrics {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-4);
  margin: 0;
  min-width: 0;
  padding-top: var(--space-3);
  border-top: 1px dashed var(--line);
}

.workspace-head__metrics div {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
}

.workspace-head__metrics dt {
  color: var(--muted);
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.workspace-head__metrics dd {
  margin: 0;
  color: var(--text-strong);
  font-family: var(--ff-mono);
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1.25;
}

.workspace-head__metrics a {
  color: inherit;
  text-decoration: none;
}

.workspace-head__metrics a:hover {
  color: var(--accent);
}

.workspace-head__actions {
  align-self: start;
  justify-self: end;
  flex: 0 0 auto;
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.workspace-head__actions .ws-id-chip {
  flex-direction: row;
  align-items: center;
}

.workspace-filter-toolbar {
  padding-top: var(--space-2);
  border-top: 1px dashed var(--line);
}

.workspace-filter-toolbar:empty {
  display: none;
}

.ws-filter-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.ws-filter-btn {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--muted);
  padding: 0.35rem 0.75rem;
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.ws-filter-btn:hover {
  background: var(--surface-tint);
  color: var(--text);
}

.ws-filter-btn.is-active {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: var(--accent);
  color: var(--accent);
}

.ws-filter-count {
  font-size: var(--fs-2xs);
  opacity: 0.7;
}

.ws-filter-refresh {
  margin-left: auto;
}

@media (max-width: 720px) {
  .workspace-head__top {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-areas:
      "label"
      "controls";
  }
  .workspace-head__top-actions,
  .workspace-head__visual {
    justify-content: flex-start;
    text-align: left;
  }
  .workspace-head__top-actions {
    grid-template-columns: 1fr;
    align-items: flex-start;
    gap: var(--space-2);
    width: 100%;
  }
  .workspace-head__visual .status-line {
    justify-self: start;
    text-align: left;
  }
  .workspace-head__visual .ds-hero__chart,
  .workspace-head__visual .ds-hero__chart .spark-inline {
    width: 100%;
  }
  .workspace-head .trust-labels.trust-strip--workspace {
    justify-content: flex-start;
    flex-wrap: nowrap;
    order: 2;
    width: 100%;
  }
  .workspace-head__main {
    grid-template-columns: 1fr;
  }
  .workspace-head__metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .workspace-head__actions {
    order: 1;
    justify-self: stretch;
    flex-wrap: wrap;
    justify-content: flex-start;
    width: 100%;
    min-width: 0;
  }
  .ws-filter-refresh {
    margin-left: 0;
  }
}

.ws-position-card {
  display: grid;
  gap: 0.75rem;
  padding: 1rem 1.15rem;
}

.ws-position-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.ws-position-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.ws-position-title strong {
  font-size: var(--fs-base);
  letter-spacing: -0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ws-position-meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.ws-position-date {
  font-size: var(--fs-2xs);
  color: var(--muted);
}

.ws-route-chip {
  display: inline-flex;
  align-items: center;
  min-width: 0;
}

.ws-route-chip .entity-inline {
  width: auto;
  gap: 0.44rem;
}

.ws-route-chip .visual-mark {
  width: 24px !important;
  height: 24px !important;
  flex: 0 0 24px !important;
}

.ws-route-chip .entity-copy strong {
  font-size: var(--fs-xs);
  color: var(--muted-strong);
}

/* C.12 / D.35 — `.ws-badge-*` and bespoke `.ws-source-chip*` chrome
   deleted. Icon-bearing source/status chips compose `.icon-badge`;
   `.state-badge` remains for neutral counters only. */

/* Workspace entries are one list. Draft, simulation, and live rows
   keep the same card chrome; type and posture are expressed by the
   chip row and CTA set, not by changing density or background. */

.readout-decision-rationale {
  display: grid;
  gap: 0.18rem;
  max-width: 58rem;
  padding-top: 0.48rem;
  border-top: 1px dashed color-mix(in srgb, var(--line) 68%, transparent);
}

.readout-decision-rationale > span {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.readout-decision-rationale > strong {
  color: var(--text-strong);
  font-size: var(--fs-sm);
  letter-spacing: -0.01em;
}

.readout-decision-rationale > p {
  margin: 0;
  color: var(--muted);
  line-height: 1.42;
}

.ws-position-metrics {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.6rem 1rem;
  align-items: start;
}

.ws-position-metrics > div {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
  overflow: hidden;
}

.ws-position-metrics .entity-inline {
  width: auto;
  max-width: 100%;
  min-width: 0;
}
.ws-position-metrics .visual-mark {
  width: 18px !important;
  height: 18px !important;
  flex: 0 0 18px !important;
}

.ws-position-metrics .token-chip {
  font-size: var(--fs-sm);
}

.ws-position-metrics strong {
  font-size: var(--fs-sm);
  letter-spacing: -0.02em;
}

.ws-dash-protocol {
  display: block;
  min-width: 0;
}

.ws-dash-protocol .entity-inline {
  width: auto;
  max-width: 100%;
  min-width: 0;
  gap: 0.38rem;
}

.ws-dash-protocol .visual-mark {
  width: 20px !important;
  height: 20px !important;
  flex: 0 0 20px !important;
}

.ws-dash-protocol .entity-copy {
  min-width: 0;
}

.ws-dash-protocol .entity-copy strong {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-strong);
  font-size: var(--fs-sm);
}

.ws-token-sub {
  display: inline-flex;
  align-items: center;
  gap: 0.38rem;
  min-width: 0;
  max-width: 100%;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.05;
}

.ws-token-sub .token-mark {
  width: 28px !important;
  height: 28px !important;
  flex: 0 0 28px !important;
}

.ws-token-sub .token-mark img {
  width: 100%;
  height: 100%;
}

.ws-token-sub span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ws-dash-asset-line {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.05rem;
  color: var(--muted-strong);
  font-size: var(--fs-sm);
  font-weight: 700;
  line-height: 1.15;
}

.ws-dash-asset-line .ws-token-sub {
  color: inherit;
  font-size: inherit;
}

.ws-dash-asset-line .ws-token-sub .token-mark {
  width: 34px !important;
  height: 34px !important;
  flex-basis: 34px !important;
}

.ws-dash-asset-line .ws-dash-asset-amount {
  color: var(--muted);
  font-weight: 600;
}

.ws-dash-empty {
  color: var(--muted);
  opacity: 1;
}

.ws-position-actions {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.4rem;
  /* Phase D.27 — was padding-top: 0.2rem; the button row visibly
     touched the metric row above with only ~3 px of separation,
     reading as overflow rather than as a deliberate action zone
     ("кнопки прилипли к плашкам" — user). Lifted to 0.85rem so
     the border-top hairline + breathing room frame the actions
     as the card footer. Margin-top mirrors so the card-internal
     stack reads with consistent rhythm. */
  margin-top: 0.6rem;
  padding-top: 0.85rem;
  border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
}

.ws-position-actions > .button {
  min-width: 0;
}

@media (max-width: 760px) {
.ws-filter-row {
    flex-wrap: wrap;
  }

.ws-position-actions {
    display: grid;
    grid-template-columns: 1fr;
  }

.ws-position-metrics {
    grid-template-columns: repeat(3, 1fr);
  }

}

/* Stress-scenario card grid — six historical scenarios always emit,
   so the grid is locked at 3 columns × 2 rows to avoid the orphan
   row remainder that auto-fit produces at typical viewport widths
   (was 5 + 1 sad-orphan on /results). Phase D.30.2 — the renderer
   contract is exactly six scenarios from HISTORICAL_REFERENCE_SCENARIOS,
   so a 3×2 grid is intentional and balanced. Two breakpoints below
   degrade to 2-col then 1-col on narrow viewports. */
/* Phase D.32 (F-5) — was repeat(3, ...) which produced a 3×2 grid for
   the canonical 6-scenario stress ladder. The .stress-spark bar above
   uses `display: flex` with `flex: 1` per bar — meaning the bar always
   renders 6 segments in a single row. The 3×2 card grid did not align
   with the 6×1 bar, so cards visually "broke" away from their stress
   segment. User flagged: "каждый квадратик должен быть под своим
   отрезком шкалы а не в 2 ряда". The renderer emits
   `style="--scenario-count: ${N}"` on the .scenario-grid root, so the
   grid can resolve its column count dynamically. At wide viewport we
   match the bar 1:1; at narrow we collapse to 3 / 2 / 1 column tiers
   (the bar's flex-1 segments shrink correspondingly thin, accepted
   as the responsive degradation). */
.scenario-grid {
  display: grid;
  grid-template-columns: repeat(var(--scenario-count, 6), minmax(0, 1fr));
  gap: 0.55rem;
  margin-top: 0.55rem;
}
@media (max-width: 1280px) {
  .scenario-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 860px) {
  .scenario-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 540px) {
  .scenario-grid {
    grid-template-columns: 1fr;
  }
}
.scenario-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.65rem 0.8rem 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--surface-soft) 32%, transparent);
  transition: border-color 0.15s ease, background 0.15s ease;
  min-width: 0;
}
.scenario-card:hover {
  border-color: color-mix(in srgb, var(--accent) 32%, var(--line-strong));
  background: color-mix(in srgb, var(--surface-soft) 50%, transparent);
}
/* C.2.4 R2 — was hardcoded pre-Phase-C cyan/mint/amber/violet/rose
   rgba; now tracks the lifted tone palette via tokens. */
.scenario-card[data-state="Observe"]        { border-left-color: color-mix(in srgb, var(--cyan) 72%, transparent); }
.scenario-card[data-state="Maintain"]       { border-left-color: color-mix(in srgb, var(--mint) 72%, transparent); }
.scenario-card[data-state="BuildBuffer"]    { border-left-color: color-mix(in srgb, var(--amber) 72%, transparent); }
.scenario-card[data-state="DeRisk"]         { border-left-color: color-mix(in srgb, var(--violet) 72%, transparent); }
.scenario-card[data-state="StressLockdown"] { border-left-color: color-mix(in srgb, var(--rose) 72%, transparent); }

.scenario-card__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.6rem;
}
.scenario-ring {
  flex: 0 0 auto;
}
.scenario-card__title {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.scenario-card__index {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--muted);
  text-transform: uppercase;
}
.scenario-card__title strong {
  font-size: var(--fs-sm);
  color: var(--text-strong);
  font-weight: 700;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.scenario-card__state {
  font-size: var(--fs-2xs);
  color: var(--muted);
  font-weight: 600;
}
.scenario-card__metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.4rem 0.55rem;
  padding-top: 0.45rem;
  border-top: 1px dashed color-mix(in srgb, var(--line) 70%, transparent);
  font-variant-numeric: tabular-nums;
}
.scenario-card__metrics > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.scenario-card__metrics > div > span {
  font-size: var(--fs-2xs);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.scenario-card__metrics > div > strong {
  font-size: var(--fs-xs);
  color: var(--text-strong);
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 640px) {
  .scenario-row__metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.log-card {
  position: relative;
  overflow: hidden;
  padding-left: 1.3rem;
}

.log-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  border-radius: var(--radius-pill);
  background: var(--line-strong);
}

/* C.2.4 R3 — log-card state stripes track the lifted tone palette,
   matching the .scenario-card rules above (R2). */
.log-card[data-state="Observe"]::before { background: color-mix(in srgb, var(--cyan) 72%, transparent); }

.log-card[data-state="Maintain"]::before { background: color-mix(in srgb, var(--mint) 72%, transparent); }

.log-card[data-state="BuildBuffer"]::before { background: color-mix(in srgb, var(--amber) 72%, transparent); }

.log-card[data-state="DeRisk"]::before { background: color-mix(in srgb, var(--violet) 72%, transparent); }

.log-card[data-state="StressLockdown"]::before { background: color-mix(in srgb, var(--rose) 72%, transparent); }

.note-card {
  position: relative;
  padding-left: 1.1rem;
  border-left: 3px solid var(--line);
}

.disclosure {
  transition: box-shadow 0.2s ease;
}

.disclosure-head {
  cursor: pointer;
  list-style: none;
  user-select: none;
  position: relative;
  padding-right: 2rem;
}

.disclosure-head::-webkit-details-marker {
  display: none;
}

.disclosure-head::after {
  content: "";
  position: absolute;
  right: 0.5rem;
  top: 50%;
  width: 0.55rem;
  height: 0.55rem;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: translateY(-65%) rotate(45deg);
  transition: transform 0.2s ease;
}

.disclosure[open] > .disclosure-head::after {
  transform: translateY(-35%) rotate(-135deg);
}

.empty-panel {
  text-align: center;
  padding: 1.5rem 1rem;
}

.empty-panel h3 {
  font-size: var(--fs-md);
  margin: 0 0 0.3rem;
}

.empty-panel p {
  max-width: 38ch;
  margin: 0 auto;
  font-size: var(--fs-sm);
}

.empty-results-hero {
  display: grid;
  justify-items: center;
  gap: 0.6rem;
  padding: 1.5rem 1rem;
  text-align: center;
}

.empty-results-hero h2 {
  font-size: var(--fs-lg);
}

.empty-results-hero .surface-copy {
  max-width: 40ch;
  margin: 0;
  font-size: var(--fs-sm);
}

.empty-results-icon {
  opacity: 0.5;
  margin-bottom: 0.15rem;
}

.form-grid-1 {
  grid-template-columns: 1fr;
}

.segmented-control {
  display: grid;
  gap: 0;
  background: var(--bg-strong);
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
  padding: 3px;
  position: relative;
}

.toggle-stack {
  display: grid;
  gap: 0.35rem;
  margin-top: 1rem;
}

@media (max-width: 960px) {
.position-row {
    grid-template-columns: repeat(2, 1fr);
  }

}


@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }

}

html[data-theme="dark"] {
  scrollbar-color: var(--line-strong) transparent;
}

html[data-theme="dark"] ::-webkit-scrollbar { width: 6px; height: 6px; }

html[data-theme="dark"] ::-webkit-scrollbar-track { background: transparent; }

html[data-theme="dark"] ::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--radius-pill); }

html[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--muted) 35%, transparent); }

html[data-theme="dark"] .review-check:checked, html[data-theme="dark"] .review-item.is-done .review-check {
  background:
    center / 0.7rem 0.7rem no-repeat
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.2 8.4 6.4 11.4 12.6 4.8' fill='none' stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2.2'/%3E%3C/svg%3E"),
    var(--accent);
}

/* =======================================================================
   Workspace (index.html) — identity strip, on-chain policies, receipts.
   These sections sit above the existing workspace hero/filter/list,
   which already has styles earlier in this file.
   ======================================================================= */

/* Phase D.27 — .ws-identity wrapper rule removed. After D.19 the
   workspace identity slot composes the canonical .ds-hero pattern
   directly, with no wrapping .ws-identity div. Zero refs in markup. */

/* Phase D.27 — .ws-identity__primary, .ws-identity__wallet (+ :hover,
   --empty), and .ws-id-label class definitions removed. They were
   the chrome of the OLD flat 3-column workspace identity layout
   that D.19 replaced with the canonical .ds-hero pattern. Zero
   refs in app.js. */

.ws-id-chip {
  display: inline-flex;
  flex-direction: column;
  /* Phase D.30.0 — was 0.1rem (~1.6px) which fused the two text rows.
     var(--space-1) is the canonical minimum visual-fusion break. */
  gap: var(--space-1);
  padding: 0.4rem 0.7rem;
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--line-strong) 80%, transparent);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  color: var(--text-strong);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
}

.ws-id-chip strong {
  font-size: var(--fs-sm);
  font-weight: 700;
}

a.ws-id-chip:hover { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }

.ws-id-chip--env {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.35rem 0.7rem;
  align-self: center;
  font-size: var(--fs-2xs);
}

/* C.2.2 W6 — was hardcoded amber + cobalt hex. Tracks tokens. */
.ws-id-chip--testnet { color: var(--amber-text); border-color: color-mix(in srgb, var(--amber) 40%, var(--line-strong)); }
.ws-id-chip--mainnet { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, var(--line-strong)); }
.ws-id-chip--muted { color: var(--muted); }

/* Phase D.27 — .ws-identity__counts, .ws-count-tile (+ strong), and
   .ws-identity__cta definitions removed. Old workspace identity
   chrome that D.19 superseded with the canonical .ds-hero pattern.
   Only .ws-identity__cta-hint kept — still emitted for the
   "Wallet is optional for simulation" copy under the CTA. */
.ws-identity__cta-hint {
  font-size: var(--fs-2xs);
  line-height: 1.35;
  color: var(--muted);
  max-width: 19rem;
}

/* Lifecycle microfact line — used by the orphan-receipts live card
   to explain state in one row without a separate panel. */
.ws-policy-lifecycle-line {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
  line-height: 1.5;
}

/* Orphan receipts history (receipts whose parent policy is detached
   from this wallet). Kept compact so the card doesn't balloon. */
.ws-orphan-history {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.3rem;
}
.ws-orphan-more {
  justify-self: start;
  font-size: var(--fs-xs);
  color: var(--muted);
  text-decoration: none;
}
.ws-orphan-more:hover { color: var(--accent); }

.ws-live-panel {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4) 0 0;
  border-top: 1px dashed var(--line);
  border-radius: 0;
  border-inline: 0;
  border-bottom: 0;
  background: transparent;
}

.ws-live-panel--compact {
  gap: var(--space-2);
  padding-top: var(--space-3);
}

.ws-live-panel__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.ws-live-panel__head > div {
  display: grid;
  gap: var(--space-1);
}

.ws-live-panel__head > div > span {
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.ws-live-panel__head strong {
  color: var(--text-strong);
  font-size: var(--fs-md);
}

.ws-live-panel__copy {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.55;
}

.ws-live-panel__note {
  margin: 0;
  color: var(--amber-text);
  font-size: var(--fs-2xs);
  line-height: 1.55;
}

.ws-exit-brief-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.ws-exit-brief-head > div {
  display: grid;
  gap: var(--space-1);
  max-width: 880px;
}

.ws-exit-brief-head span,
.ws-exit-checklist-head span,
.ws-exit-next > span,
.ws-exit-verify span {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.ws-exit-brief-head strong {
  color: var(--text-strong);
  font-size: var(--fs-md);
}

.ws-exit-brief-head p,
.ws-exit-next p,
.ws-exit-verify p,
.ws-exit-boundary p {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.5;
}

.ws-exit-brief-grid {
  display: grid;
  grid-template-columns: minmax(300px, 0.82fr) minmax(360px, 1.18fr);
  gap: var(--space-3);
  align-items: stretch;
}

.ws-exit-next,
.ws-exit-verify {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-soft) 28%, transparent);
}

.ws-exit-next {
  display: grid;
  align-content: center;
  gap: var(--space-1);
  padding: var(--space-3);
  border-left: 3px solid color-mix(in srgb, var(--accent) 72%, var(--line));
}

.ws-exit-next[data-tone="amber"] {
  border-left-color: var(--amber);
  background: color-mix(in srgb, var(--amber) 5%, transparent);
}

.ws-exit-next[data-tone="success"] {
  border-left-color: var(--mint);
  background: color-mix(in srgb, var(--mint) 5%, transparent);
}

.ws-exit-next strong {
  color: var(--text-strong);
  font-size: var(--fs-lg);
  line-height: 1.12;
}

.ws-exit-verify {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  overflow: hidden;
}

.ws-exit-verify > div {
  display: grid;
  align-content: center;
  gap: 0.2rem;
  min-width: 0;
  padding: var(--space-3);
}

.ws-exit-verify > div + div {
  border-left: 1px solid var(--line);
}

.ws-exit-verify strong {
  color: var(--text-strong);
  font-size: var(--fs-lg);
  line-height: 1.1;
}

.ws-exit-boundary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2);
  align-items: start;
  padding: var(--space-2) 0 var(--space-3);
  border-bottom: 1px solid var(--line);
}

.ws-exit-mainnet-evidence {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(280px, 1.1fr);
  gap: var(--space-3);
  align-items: end;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--surface-soft) 24%, transparent);
}

.ws-exit-mainnet-evidence[data-state="success"] {
  border-color: color-mix(in srgb, var(--mint) 34%, var(--line));
  background: color-mix(in srgb, var(--mint) 5%, transparent);
}

.ws-exit-mainnet-evidence[data-state="error"] {
  border-color: color-mix(in srgb, var(--rose) 38%, var(--line));
  background: color-mix(in srgb, var(--rose) 5%, transparent);
}

.ws-exit-mainnet-evidence__copy {
  display: grid;
  gap: var(--space-1);
  min-width: 0;
}

.ws-exit-mainnet-evidence__copy span {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.ws-exit-mainnet-evidence__copy strong {
  color: var(--text-strong);
  font-size: var(--fs-md);
  line-height: 1.15;
}

.ws-exit-mainnet-evidence__copy p,
.ws-exit-mainnet-evidence__status {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.45;
}

.ws-exit-mainnet-evidence__form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: var(--space-2);
  align-items: center;
  min-width: 0;
}

.ws-exit-mainnet-evidence__form .input {
  min-width: 0;
}

.ws-exit-mainnet-evidence__fallback {
  display: grid;
  grid-template-columns: minmax(180px, 1fr) auto;
  gap: var(--space-2);
  align-items: center;
  min-width: 0;
}

.ws-exit-mainnet-evidence__fallback summary {
  grid-column: 1 / -1;
  color: var(--muted);
  cursor: pointer;
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.ws-exit-mainnet-evidence__status {
  grid-column: 1 / -1;
  display: flex;
  gap: var(--space-2);
  align-items: center;
  flex-wrap: wrap;
  min-width: 0;
  overflow-wrap: anywhere;
}

.ws-exit-mainnet-evidence__status span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.ws-exit-mainnet-evidence__status a {
  margin-left: var(--space-2);
  color: var(--accent);
  font-weight: 800;
  text-decoration: none;
}

.ws-exit-checklist-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.ws-exit-checklist-head > div {
  display: grid;
  gap: var(--space-1);
}

.ws-exit-checklist-head strong {
  color: var(--text-strong);
  font-size: var(--fs-md);
}

.ws-live-step-list--exit {
  margin-top: calc(var(--space-1) * -1);
}

.ws-live-step__main {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: var(--space-2);
  align-items: start;
  min-width: 0;
}

.ws-live-step__index {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  color: var(--muted-strong);
  background: color-mix(in srgb, var(--surface-soft) 42%, transparent);
  font-family: var(--ff-mono);
  font-size: var(--fs-xs);
  font-weight: 800;
  line-height: 1;
}

.ws-live-step.is-complete .ws-live-step__index {
  color: var(--mint-text);
  border-color: color-mix(in srgb, var(--mint) 40%, var(--line-strong));
  background: color-mix(in srgb, var(--mint) 10%, transparent);
}

.ws-exit-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding-top: var(--space-1);
}

.ws-exit-actions__primary,
.ws-exit-actions__secondary {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
}

.ws-exit-actions__reason {
  flex-basis: 100%;
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.4;
  text-align: right;
}

.ws-exit-actions__primary {
  margin-left: auto;
  order: 2;
}

.ws-exit-actions__secondary {
  order: 1;
}

.ws-live-control-group,
.ws-live-handoff {
  display: grid;
  gap: var(--space-2);
}

.ws-live-control-label {
  width: fit-content;
  font-size: var(--fs-2xs);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.ws-live-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.ws-live-panel--compact .ws-live-actions {
  padding: 0;
  border-top: 0;
}

.ws-live-panel--compact .ws-live-handoff {
  margin-top: var(--space-1);
  padding-top: var(--space-3);
  border-top: 1px dashed color-mix(in srgb, var(--line) 70%, transparent);
}

.ws-live-control-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.45rem;
}

.ws-live-panel--compact .ws-live-control-actions {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.ws-live-step-list {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}

.ws-live-step {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) 0;
  border-radius: 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
}

.ws-live-step strong {
  color: var(--text-strong);
  font-size: var(--fs-sm);
}

.ws-live-step__main > div > span {
  color: var(--muted);
  font-size: var(--fs-xs);
  line-height: 1.5;
}

.ws-live-step--checklist.is-complete {
  border-color: var(--line);
}

.ws-live-step__actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 0;
  grid-row: 1 / span 2;
  grid-column: 2;
}

.ws-live-step__status {
  color: var(--muted);
  font-size: var(--fs-2xs);
}

.ws-live-receipt {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.45rem 0;
  border-radius: 0;
  border: 0;
  border-top: 1px dashed var(--line);
  background: transparent;
}

.ws-live-receipt__main { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.ws-live-receipt__main strong { color: var(--text-strong); font-size: var(--fs-sm); }
.ws-live-receipt__sub { font-size: var(--fs-2xs); color: var(--muted); }

.ws-live-receipt__link {
  font-family: var(--ff-mono);
  font-size: var(--fs-2xs);
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
}
.ws-live-receipt__link:hover { color: var(--accent); }

@media (max-width: 760px) {
  .ws-exit-brief-grid,
  .ws-exit-mainnet-evidence,
  .ws-exit-verify {
    grid-template-columns: minmax(0, 1fr);
  }

  .ws-exit-mainnet-evidence__form {
    grid-template-columns: minmax(0, 1fr);
  }

  .ws-exit-mainnet-evidence__fallback {
    grid-template-columns: minmax(0, 1fr);
  }

  .ws-exit-verify > div + div {
    border-left: 0;
    border-top: 1px solid var(--line);
  }

  .ws-exit-boundary,
  .ws-live-step {
    grid-template-columns: minmax(0, 1fr);
  }

  .ws-live-step__actions {
    grid-row: auto;
    grid-column: auto;
  }

  .ws-exit-actions__primary {
    margin-left: 0;
    order: 1;
  }

  .ws-exit-actions__reason {
    text-align: left;
  }

  .ws-exit-actions__secondary {
    order: 2;
  }

  .ws-live-control-actions {
    grid-template-columns: minmax(0, 1fr);
  }
  .ws-live-panel--compact .ws-live-control-actions {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── Badge row — source/status chips compose DS .icon-badge ─────── */

.ws-badge-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 0.2rem;
}

/* ── Filter refresh button ──────────────────────────────────────── */

.ws-filter-refresh {
  margin-left: auto;
  font-size: var(--fs-xs);
}

/* Readout oracle posture — intentionally not a card. It is a thin trust row
   that qualifies the chart inputs without adding another pancake surface. */
.oracle-readback-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem 0.85rem;
  margin: 0.95rem 0 0.35rem;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.oracle-readback-strip strong {
  color: var(--text-strong);
  font-weight: 700;
}

.oracle-readback-strip__note {
  flex: 1 1 24rem;
  min-width: 16rem;
  color: color-mix(in srgb, var(--muted) 82%, transparent);
}

/* ─────────────────────────────────────────────────────────────────
   Polish pass — DS polish appendix (results/workspace slice, additive)
   Date: 2026-04-29
   Source: public UI polish pass B
   B-18 (scenario-ring stroke-dasharray draw-on) deferred — collides
   with inline stroke-dasharray attribute set by renderMiniHealthRing
   at app.js:3729-3732. Will revisit with a transform-only variant.
   ───────────────────────────────────────────────────────────────── */

/* B-18b — stress-spark first-paint stagger (one-time, ≤500ms total) */
@media (prefers-reduced-motion: no-preference) {
  .stress-spark .stress-spark-bar {
    transform-origin: bottom;
    animation: stress-spark-bar-rise 200ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  .stress-spark .stress-spark-bar:nth-child(1) { animation-delay:   0ms; }
  .stress-spark .stress-spark-bar:nth-child(2) { animation-delay:  30ms; }
  .stress-spark .stress-spark-bar:nth-child(3) { animation-delay:  60ms; }
  .stress-spark .stress-spark-bar:nth-child(4) { animation-delay:  90ms; }
  .stress-spark .stress-spark-bar:nth-child(5) { animation-delay: 120ms; }
  .stress-spark .stress-spark-bar:nth-child(6) { animation-delay: 150ms; }
}
@keyframes stress-spark-bar-rise {
  0%   { transform: scaleY(0.05); opacity: 0; }
  100% { transform: scaleY(1);    opacity: 0.85; }
}
@media (prefers-reduced-motion: reduce) {
  .stress-spark .stress-spark-bar { animation: none !important; }
}
/* ── End Polish pass results/workspace appendix ──────────────────── */

/* ─────────────────────────────────────────────────────────────────
   Product-surface polish — product-surface polish (results/workspace slice)
   ───────────────────────────────────────────────────────────────── */

/* D-04 — scenario-card hover lift + state-tinted shadow */
.scenario-card {
  transition:
    border-color var(--motion-fast) var(--ease-out),
    background var(--motion-fast) var(--ease-out),
    box-shadow var(--motion-fast) var(--ease-out),
    transform var(--motion-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .scenario-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--accent) 35%, transparent);
  }
  .scenario-card[data-state="Observe"]:hover {
    box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--cyan) 38%, transparent);
  }
  .scenario-card[data-state="Maintain"]:hover {
    box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--mint) 38%, transparent);
  }
  .scenario-card[data-state="BuildBuffer"]:hover {
    box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--amber) 38%, transparent);
  }
  .scenario-card[data-state="DeRisk"]:hover {
    box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--violet) 38%, transparent);
  }
  .scenario-card[data-state="StressLockdown"]:hover {
    box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--rose) 38%, transparent);
  }
}
@media (prefers-reduced-motion: reduce) {
  .scenario-card:hover { transform: none; }
}

/* D-05 + E-09 — readout-action hero numeric brand-gradient hairline
   (static underline) + one-time shimmer wipe on first paint (≤450ms).
   Two-layer background: (1) shimmer band crosses left→right ONCE on
   first paint; (2) accent→cyan underline stays static. The numeric
   value never animates — the wipe is a paint-overlay over static
   text (financial-numeral rule honored). */
@keyframes ds-hero-shimmer-wipe {
  from { background-position: -120% 0, left bottom; }
  to   { background-position:  220% 0, left bottom; }
}
body[data-page="results"] .readout-action-line strong,
body[data-page="live"]    .readout-action-line strong {
  display: inline-block;
  padding-bottom: 0.18rem;
  background-image:
    linear-gradient(
      100deg,
      transparent 0%,
      transparent 35%,
      color-mix(in srgb, var(--text) 28%, transparent) 50%,
      transparent 65%,
      transparent 100%
    ),
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--accent) 60%, transparent) 0%,
      color-mix(in srgb, var(--cyan) 35%, transparent) 60%,
      transparent 100%
    );
  background-size: 280% 100%, 100% 1px;
  background-position: 220% 0, left bottom;
  background-repeat: no-repeat;
}

body[data-page="results"] #readout-action[data-shimmer="first-paint"] .readout-action-line strong,
body[data-page="live"]    #readout-action[data-shimmer="first-paint"] .readout-action-line strong {
  animation: ds-hero-shimmer-wipe 450ms cubic-bezier(0.16, 1, 0.3, 1) 1 both;
}
@media (prefers-reduced-motion: reduce) {
  body[data-page="results"] .readout-action-line strong,
  body[data-page="live"]    .readout-action-line strong {
    animation: none;
    background-position: 220% 0, left bottom;
  }
}

/* D-06 — scale-pair cross-axis hover illumination */
.scale-pair > .price-scale,
.scale-pair > .position-scale {
  transition: background-color var(--motion-fast) var(--ease-out);
  border-radius: var(--radius-xs);
}
@media (hover: hover) and (pointer: fine) {
  .scale-pair:hover > .price-scale,
  .scale-pair:hover > .position-scale {
    background-color: color-mix(in srgb, var(--accent) 4%, transparent);
  }
  .scale-pair:has(> .price-scale:hover) > .price-scale,
  .scale-pair:has(> .position-scale:hover) > .position-scale {
    background-color: color-mix(in srgb, var(--accent) 9%, transparent);
  }
}
@media (prefers-reduced-motion: reduce) {
  .scale-pair > .price-scale,
  .scale-pair > .position-scale { transition: none; }
}
/* ── End Product-surface polish results/workspace appendix ──────────────────── */

@media (max-width: 560px) {
  .stress-ladder {
    margin-inline: 0;
    padding-inline: 0;
    overflow-x: visible;
  }

  .stress-ladder::after {
    display: none;
  }

  .stress-ladder__track {
    min-width: 0;
  }

  .stress-ladder-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2);
    padding-inline: 0;
  }

  .stress-ladder-cell {
    min-width: 0;
    min-height: 4rem;
    border: 1px solid color-mix(in srgb, var(--ladder-tone) 28%, var(--line));
    border-top-width: 2px;
    border-radius: var(--radius-sm);
    padding: 0.55rem;
  }
}

/* >>> 90-runtime-polish.css >>> */
/* =======================================================================
   Runtime polish
   Keeps only shared runtime affordances that should survive across pages.
   Chart and setup-specific surfaces live in their own source files.
   ======================================================================= */

/* Phase D.29.1 — canonical app-wide focus-visible ring. Replaces the
   prior `outline: none !important; box-shadow: var(--ring) !important`
   block, which won the specificity war against the per-page outline
   restorations in 98-setup-rebuild.css and silently masked them.
   :where() keeps specificity at 0 so per-element overrides still win
   without needing !important. */
:where(
  a.button,
  button,
  input,
  select,
  textarea,
  summary,
  .strategy-preset
):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.scenario-workbench-host:empty,
#readout-hero:empty,
#results-market-forecast:empty,
#results-scenarios:empty,
#action-log:empty {
  position: relative;
  min-height: 11rem;
}

/* Phase D.13 — readout sections that the renderer fills conditionally
   should not render an empty bordered card when their data is absent.
   #live-position-center renders only in live mode; #readout-action,
   #readout-autopilot, #results-route, #health-notes, #results-review
   render only when their data exists. The :empty hide keeps the page
   stack tight without reaching for `hidden` attributes from the
   renderer. */
#live-position-center:empty,
#live-execution-panel:empty,
#readout-status:empty,
#readout-action:empty,
#readout-autopilot:empty,
#results-route:empty,
#health-notes:empty,
#results-review:empty {
  display: none;
}

body[data-page="live"] #results-market-forecast:empty,
body[data-page="live"] #results-scenarios:empty,
body[data-page="live"] #action-log:empty {
  display: none;
  min-height: 0;
}

/* Cold-route stability: /results and /live hydrate from local storage,
   chain readback, or query params after the first paint. Keep the
   expected readout slots reserved until renderCurrentPage() marks the
   app ready, then the normal :empty hide rules above take over. */
body[data-page="results"]:not([data-app-ready="true"]) #readout-status:empty,
body[data-page="live"]:not([data-app-ready="true"]) #readout-status:empty {
  display: flex;
  min-height: 2.75rem;
}

body[data-page="results"]:not([data-app-ready="true"]) #readout-action:empty,
body[data-page="live"]:not([data-app-ready="true"]) #readout-action:empty {
  display: block;
  min-height: 24.5rem;
}

body[data-page="results"]:not([data-app-ready="true"]) #readout-hero:empty {
  min-height: 16rem;
}

body[data-page="live"]:not([data-app-ready="true"]) #readout-hero:empty {
  min-height: 16rem;
}

body[data-page="results"]:not([data-app-ready="true"]) #results-scenarios:empty,
body[data-page="live"]:not([data-app-ready="true"]) #results-scenarios:empty {
  display: block;
  min-height: 23rem;
}

body[data-page="results"]:not([data-app-ready="true"]) #results-market-forecast:empty,
body[data-page="live"]:not([data-app-ready="true"]) #results-market-forecast:empty {
  display: block;
  min-height: 16rem;
}

body[data-page="live"]:not([data-app-ready="true"]) #live-position-center:empty {
  display: block;
  min-height: 30rem;
}

body[data-page="results"]:not([data-app-ready="true"]) #results-route:empty,
body[data-page="live"]:not([data-app-ready="true"]) #results-route:empty {
  display: block;
  min-height: 12rem;
}

body[data-page="results"]:not([data-app-ready="true"]) #health-notes:empty,
body[data-page="results"]:not([data-app-ready="true"]) #results-review:empty,
body[data-page="live"]:not([data-app-ready="true"]) #health-notes:empty,
body[data-page="live"]:not([data-app-ready="true"]) #results-review:empty {
  display: block;
  min-height: 15rem;
}

body[data-page="workspace"]:not([data-app-ready="true"]) #workspace-identity {
  min-height: 22rem;
}

body[data-page="workspace"]:not([data-app-ready="true"]) #workspace-list {
  min-height: 34rem;
}

body:not([data-app-ready="true"]) .app-main::after {
  content: "";
  display: block;
  min-height: 8rem;
}

@media (max-width: 760px) {
  body[data-page="results"]:not([data-app-ready="true"]) #readout-action:empty,
  body[data-page="live"]:not([data-app-ready="true"]) #readout-action:empty {
    min-height: 42rem;
  }

  body[data-page="results"]:not([data-app-ready="true"]) #readout-hero:empty,
  body[data-page="live"]:not([data-app-ready="true"]) #readout-hero:empty {
    min-height: 31.5rem;
  }

  body[data-page="results"]:not([data-app-ready="true"]) #results-scenarios:empty,
  body[data-page="live"]:not([data-app-ready="true"]) #results-scenarios:empty {
    min-height: 53rem;
  }

  body[data-page="workspace"]:not([data-app-ready="true"]) #workspace-identity {
    min-height: 30rem;
  }

  body[data-page="workspace"]:not([data-app-ready="true"]) #workspace-list {
    min-height: 42rem;
  }
}

body[data-page="live"] #results-market-forecast:empty::before,
body[data-page="live"] #results-scenarios:empty::before,
body[data-page="live"] #action-log:empty::before {
  content: none;
}

.scenario-workbench-host:empty::before,
#readout-hero:empty::before,
#results-market-forecast:empty::before,
#results-scenarios:empty::before,
#action-log:empty::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Phase D.23 — was --radius-md (18 px); the filled .surface around
     it uses --radius-lg (22 px), so a brief radius flash showed when
     skeleton placeholder loaded ahead of the content. Aligned to
     --radius-lg so the skeleton corners match the filled state. */
  border-radius: var(--radius-lg);
  background:
    linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--line) 28%, transparent) 12%, transparent 24%) 0 0 / 220% 100%,
    linear-gradient(var(--surface-soft), var(--surface-soft)) 1rem 1rem / 32% 0.8rem no-repeat,
    linear-gradient(var(--surface-soft), var(--surface-soft)) 1rem 2.6rem / 68% 0.7rem no-repeat,
    linear-gradient(var(--surface-soft), var(--surface-soft)) 1rem 4.1rem / calc(100% - 2rem) 7rem no-repeat;
  animation: createSkeletonShimmer 1.8s linear infinite;
}

/* App-level custody + no-wallet footer — visible at rest on every app page.
   Injected by ensureAppFooter(). */
.app-footer {
  margin-top: 2.4rem;
  padding: 1rem 1.2rem;
  border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  color: color-mix(in srgb, var(--text) 62%, transparent);
  font-size: var(--fs-base);
  line-height: 1.5;
  display: grid;
  gap: 0.35rem;
}

.app-footer__line {
  margin: 0;
}

.app-footer__line strong {
  color: color-mix(in srgb, var(--text) 85%, transparent);
  font-weight: 600;
  margin-right: 0.3rem;
}

.app-footer__line a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.15rem;
}
