/* =========================================================================
   ORBEVA · COMPONENTS — the canonical, token-built component library.
   Link AFTER tokens.css + base.css:
     <link rel="stylesheet" href="/styles/tokens.css">
     <link rel="stylesheet" href="/styles/base.css">
     <link rel="stylesheet" href="/styles/components.css">

   Naming: .block  .block__part  .block--variant ; state via data-/aria-.
   Every value references a token — zero magic numbers, one meaning per colour
   (--pos = gain only, --neg = loss/risk only, --warn = caution, --info/--accent
   = neutral data / action). This file is the single source these patterns
   collapse into; see /components.html for the living reference. Migration is
   additive — pages adopt these class names one component at a time.
   ========================================================================= */

/* ---- Buttons ----------------------------------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-1);
  min-height:var(--tap);padding:0 var(--sp-4);border-radius:var(--r-sm);
  font-size:var(--text-sm);font-weight:700;color:var(--ink);text-decoration:none;
  background:linear-gradient(180deg,var(--surface-2),var(--surface));
  /* --line-strong: an interactive control's edge conveys "this is a button" → AA non-text 3:1 */
  border:1px solid var(--line-strong);box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
  transition:transform var(--dur-base) var(--ease-out)}
.btn:active{transform:scale(.97);transition-duration:var(--dur-fast)}
.btn[disabled],.btn:disabled{opacity:.45;pointer-events:none}
.btn--primary{color:var(--accent-ink);border-color:transparent;
  background:linear-gradient(180deg,var(--violet),var(--accent));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 8px 22px -10px var(--accent)}
.btn--ghost{background:var(--surface-2);box-shadow:none}
.btn--block{display:flex;width:100%}

/* ---- Card -------------------------------------------------------------- */
.card{padding:var(--sp-5);border-radius:var(--r-xl);
  background:linear-gradient(180deg,color-mix(in srgb,var(--surface) 80%,#fff 4%),var(--surface));
  border:1px solid var(--line);
  /* Route through --shadow-2 (its dark value IS this exact literal → byte-identical on dark) so light
     mode gets the soft light-drop instead of this heavy black one. */
  box-shadow:var(--shadow-2)}
.card--inset{background:var(--surface-2);box-shadow:none}
/* The two commonest chrome overrides widgets were hand-rolling inline (the inline-style drift
   widget-style-golden ratchets). Self-sufficient — they re-declare the border so the variant is
   correct regardless of which page-level `.card` base applies (some pages still ship a legacy
   `.card` with a fainter border; these variants pin the canonical --line border). */
.card--outlined{border:1px solid var(--line)}
.card--toned{border:1px solid var(--line);background:linear-gradient(180deg,var(--surface-2),var(--surface))}
.card--accent{border-left:3px solid var(--accent);background:linear-gradient(180deg,var(--accent-tint),transparent 62%)}
.card--pos{border-left:3px solid var(--pos);background:linear-gradient(180deg,var(--pos-tint),transparent 62%)}
.card--warn{border-left:3px solid var(--warn);background:linear-gradient(180deg,var(--warn-tint),transparent 62%)}
.card--info{border-left:3px solid var(--info);background:linear-gradient(180deg,var(--info-tint),transparent 62%)}
.card--locked{filter:saturate(.6);position:relative;overflow:hidden}

/* ---- Eyebrow / section label ------------------------------------------ */
.eyebrow{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);
  font-size:var(--text-2xs);font-weight:850;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-dim);margin:var(--sp-5) 0 var(--sp-3)}
.eyebrow__action{font-weight:700;color:var(--accent);text-transform:none;letter-spacing:0}

/* ---- Metric (the money number) ---------------------------------------- */
.metric{font-weight:800;line-height:1.05;font-variant-numeric:tabular-nums slashed-zero;color:var(--ink)}
.metric--hero{font-size:var(--text-3xl)}
.metric--lg{font-size:var(--text-2xl)}
.metric--md{font-size:var(--text-xl)}
.metric--pos{color:var(--pos)} .metric--neg{color:var(--neg)}
.metric--warn{color:var(--warn)} .metric--info{color:var(--info)} .metric--accent{color:var(--accent)}
.metric__unit{font-size:var(--text-sm);font-weight:600;color:var(--ink-dim);margin-left:2px}

/* ---- Pills / badges / chips ------------------------------------------- */
.pill{display:inline-flex;align-items:center;gap:var(--sp-1);padding:3px var(--sp-2);
  border-radius:var(--r-pill);font-size:var(--text-2xs);font-weight:800;
  background:var(--surface-2);border:1px solid var(--line);color:var(--ink-dim)}
.pill--pos{color:var(--pos);background:var(--pos-tint);border-color:transparent}
.pill--warn{color:var(--warn);background:var(--warn-tint);border-color:transparent}
.pill--neg{color:var(--neg);background:var(--neg-tint);border-color:transparent}
.pill--accent{color:var(--accent);background:var(--accent-tint);border-color:transparent}
.chip{position:relative;display:inline-flex;align-items:center;gap:var(--sp-1);min-height:34px;padding:0 var(--sp-3);
  border-radius:var(--r-pill);font-size:var(--text-xs);font-weight:700;color:var(--ink-dim);
  background:var(--surface-2);border:1px solid var(--line);cursor:default}
button.chip,[role="button"].chip{cursor:pointer}
/* >=44px hit target without growing the 34px visual (out of flow, no overflow). */
.chip::before{content:"";position:absolute;inset:-5px}
.chip[aria-pressed=true]{color:var(--accent-ink);background:var(--accent);border-color:transparent}

/* ---- Bar / meter (the one progress bar to rule the six) --------------- */
/* The unfilled track is --surface-2 (barely distinct from the card it sits in). A 1px --line-strong
   edge gives the EMPTY track an AA non-text 3:1 boundary so the "remaining" portion stays visible to
   low-vision users even at 0% fill — without recolouring the fill semantics. */
.bar{position:relative;height:8px;border-radius:var(--r-pill);background:var(--surface-2);border:1px solid var(--line-strong);overflow:hidden}
.bar--lg{height:12px} .bar--sm{height:6px}
.bar__fill{position:absolute;inset:0 auto 0 0;border-radius:inherit;background:var(--accent)}
.bar--pos .bar__fill{background:var(--pos)} .bar--warn .bar__fill{background:var(--warn)}
.bar--neg .bar__fill{background:var(--neg)} .bar--info .bar__fill{background:var(--info)}
/* over-budget honesty: a fill > 100% shows the overflow segment in --neg */
.bar__over{position:absolute;top:0;bottom:0;right:0;background:var(--neg);border-radius:inherit}

/* ---- Row (label left, value right, hairline) -------------------------- */
.row{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-4) 0;border-top:1px solid var(--line)}
.row:first-child{border-top:0}
.row__body{flex:1;min-width:0}
.row__title{font-size:var(--text-md);font-weight:600;color:var(--ink)}
.row__sub{font-size:var(--text-xs);color:var(--ink-dim)}
.row__icon{flex:none;display:inline-flex;align-items:center}
.row__value{font-weight:800;font-variant-numeric:tabular-nums;flex:none}

/* ---- Note / callout (one component, four meanings) -------------------- */
.note{display:flex;gap:var(--sp-3);padding:var(--sp-4);border-radius:var(--r-md);
  font-size:var(--text-sm);line-height:1.5;color:var(--ink-dim);
  background:var(--surface-2);border:1px solid var(--line)}
.note--info{background:var(--info-tint);border-color:transparent}
.note--warn{background:var(--warn-tint);border-color:transparent;color:var(--ink)}
.note--pos{background:var(--pos-tint);border-color:transparent}
.note--accent{background:var(--accent-tint);border-color:transparent}

/* ---- Segmented control ------------------------------------------------ */
/* --line-strong on form-like control edges (segmented control, stepper, switch): the boundary
   communicates "this is an interactive control / its on-off state" → AA non-text 3:1. */
.seg{display:inline-flex;gap:2px;padding:3px;border-radius:var(--r-md);background:var(--surface-2);border:1px solid var(--line-strong)}
.seg button{position:relative;min-height:32px;padding:0 var(--sp-4);border:0;border-radius:var(--r-sm);background:transparent;
  color:var(--ink-dim);font-size:var(--text-xs);font-weight:700}
/* >=44px hit target (visual stays 32px; the 3px .seg padding means -6px reaches ~44px). */
.seg button::before{content:"";position:absolute;inset:-6px}
.seg button[aria-pressed=true]{background:var(--accent);color:var(--accent-ink)}

/* ---- Stepper (± value) ------------------------------------------------ */
.stepper{display:inline-flex;align-items:center;gap:var(--sp-2)}
.stepper button{width:var(--tap);height:var(--tap);border-radius:var(--r-sm);
  background:var(--surface-2);border:1px solid var(--line-strong);color:var(--ink);font-size:18px;font-weight:700}
.stepper__value{min-width:48px;text-align:center;font-weight:800;font-variant-numeric:tabular-nums}

/* ---- Switch ----------------------------------------------------------- */
.switch{width:46px;height:28px;border-radius:var(--r-pill);background:var(--surface-2);
  border:1px solid var(--line-strong);position:relative;flex:none;transition:background var(--dur-fast) ease}
.switch::after{content:"";position:absolute;top:2px;left:2px;width:22px;height:22px;border-radius:50%;
  background:var(--ink);transition:transform var(--dur-base) ease}
.switch[aria-checked=true]{background:var(--accent);border-color:transparent}
.switch[aria-checked=true]::after{transform:translateX(18px);background:var(--accent-ink)}

/* Scroll-Driven Animations: Parallax & Fade for horizontal scrollers */
@supports (animation-timeline: view()) {
  .carousel-item {
    animation: fade-shrink linear both;
    animation-timeline: view(inline);
  }
  @keyframes fade-shrink {
    0% {
      opacity: 0.3;
      transform: scale(0.85);
    }
    15% {
      opacity: 1;
      transform: scale(1);
    }
    85% {
      opacity: 1;
      transform: scale(1);
    }
    100% {
      opacity: 0.3;
      transform: scale(0.85);
    }
  }
}

/* ---- Widget primitives (unified-UI P4) ---------------------------------
   The render vocabulary for layout-driven widgets (sdui-renderer renderCard):
   every class consumes the COMPONENT-token tier (--w-*, tokens.css) only —
   zero raw values — so one manifest `theme` re-bind re-skins a whole widget
   coherently across every [data-theme]. UNLAYERED on purpose (like .btn/.pill
   above): Cascade-5 unlayered author styles beat ALL layered styles, so a
   layered .w-actions__link would LOSE to base.css's bare `a{color:inherit}`
   (#1275 audit F3). Unlayered, class specificity wins over element selectors
   and page CSS still overrides by order/specificity exactly like the rest of
   this file. Only the token TIERS stay in @layer (tokens.css). */
.w-stat{display:flex;flex-direction:column;gap:2px;min-width:0}
.w-stat__label{font-size:var(--w-label-size);font-weight:850;text-transform:uppercase;letter-spacing:.08em;color:var(--w-label-ink)}
/* Release One recon §6 (de-caps bill headlines): the Upcoming Bills lead stat label carries DATA —
   "PayPal Cashback Mastercard ••1474 · overdue by 1 day" — not a static label; forcing it uppercase
   read as shouting. Sentence-style here; the mask (••) and every other stat label stay as they are. */
[data-widget-type="UpcomingBills"] .w-stat__label{text-transform:none;letter-spacing:.01em}
[data-widget-type="DeadWeightSubscriptions"] .w-stat__label{text-transform:none;letter-spacing:.01em}
.w-stat__value{font-size:var(--w-stat-size);font-weight:850;color:var(--w-stat-ink);font-variant-numeric:tabular-nums;line-height:1.05;overflow-wrap:anywhere}
.w-stat__value--sm{font-size:var(--text-lg)}
/* Optional stat value TONE — an opportunity/gain/loss hero (IdleCash accent, momentum pos). Maps to an
   existing component token, never a raw color; the label + unit keep their default ink. */
.w-stat__value--accent{color:var(--w-accent-text)}
.w-stat__value--pos{color:var(--w-delta-pos)}
.w-stat__value--neg{color:var(--w-delta-neg)}
.w-stat__unit{font-size:var(--text-xs);font-weight:700;color:var(--w-stat-unit-ink);margin-left:4px}
.w-delta{font-size:var(--text-xs);font-weight:800;font-variant-numeric:tabular-nums}
.w-delta--pos{color:var(--w-delta-pos)}  .w-delta--neg{color:var(--w-delta-neg)}  .w-delta--flat{color:var(--ink-dim)}
.w-chips{display:flex;gap:6px;flex-wrap:wrap;min-width:0}
.w-chip{display:inline-flex;align-items:center;min-height:22px;padding:0 8px;border-radius:var(--r-pill);background:var(--w-chip-bg);color:var(--w-chip-ink);font-size:var(--text-3xs);font-weight:800;white-space:nowrap}
.w-progress{display:grid;gap:4px}
.w-progress__track{position:relative;height:6px;border-radius:var(--r-pill);background:color-mix(in oklch, var(--w-track) 32%, transparent);overflow:visible}
.w-progress__fill{display:block;height:100%;border-radius:inherit;background:var(--w-fill)}
.w-progress--warn .w-progress__fill{background:var(--warn)}
.w-progress--pos .w-progress__fill{background:var(--pos)}
.w-progress--neg .w-progress__fill{background:var(--neg)}
.w-progress__mark{position:absolute;top:-3px;bottom:-3px;width:2px;border-radius:1px;background:var(--line-strong)}
.w-donut{display:inline-flex;align-items:center;gap:8px;min-width:0}
.w-donut svg{flex:none}
.w-spark{display:inline-flex;align-items:center;gap:8px;min-width:0}
.w-spark svg{flex:none;overflow:visible}
.w-compare{display:grid;gap:7px;min-width:0}
/* Squeeze contract (cf .w-list): the label caps at half the row so a long fund name ellipsizes
   instead of crushing the 1fr BAR to 0px; the 64px floor on the label keeps short rows unchanged. */
.w-compare__row{display:grid;grid-template-columns:fit-content(50%) 1fr auto;align-items:center;gap:8px;min-width:0}
.w-compare__label{min-width:64px;font-size:var(--text-xs);font-weight:700;color:var(--w-row-sub-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.w-compare__track{height:8px;border-radius:var(--r-pill);background:color-mix(in oklch, var(--w-track) 32%, transparent);overflow:hidden}
.w-compare__fill{display:block;height:100%;border-radius:inherit;background:var(--w-accent)}
.w-compare__fill--warn{background:var(--warn)}
.w-compare__fill--pos{background:var(--pos)}
.w-compare__value{font-size:var(--text-xs);font-weight:800;color:var(--w-row-ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.w-contrib{display:grid;gap:7px;min-width:0}
.w-contrib__axis{display:grid;grid-template-columns:1fr auto 1fr;color:var(--ink-faint);font-size:var(--text-2xs);font-weight:750;text-align:center}.w-contrib__axis::first-letter{text-align:left}.w-contrib__axis span{padding:0 5px}
.w-contrib__row{display:grid;grid-template-columns:fit-content(50%) 1fr auto;align-items:center;gap:8px;min-width:0}  /* same contract as .w-compare__row */
.w-contrib__label{min-width:64px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--w-row-sub-ink);font-size:var(--text-xs);font-weight:700}
.w-contrib__track{position:relative;height:9px;border-radius:var(--r-pill);background:color-mix(in oklch,var(--w-track) 25%,transparent);overflow:hidden}
.w-contrib__zero{position:absolute;z-index:2;inset:0 auto 0 50%;border-left:1px dashed var(--line-strong)}
.w-contrib__fill{position:absolute;top:1px;bottom:1px;border-radius:var(--r-pill)}.w-contrib__fill--pos{background:var(--pos)}.w-contrib__fill--neg{background:var(--neg)}
.w-contrib__value{color:var(--w-row-ink);font-size:var(--text-xs);font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap}
/* stackBar — one stacked-composition bar + optional swatched legend / one-line caption (wealth mix, allocation). */
.w-stackbar{display:grid;gap:10px;min-width:0}
.w-stackbar__bar{display:flex;height:12px;border-radius:var(--r-pill);overflow:hidden;background:color-mix(in oklch, var(--w-track) 32%, transparent);gap:2px}
.w-stackbar__seg{display:block;height:100%}
.w-stackbar__legend{display:flex;flex-wrap:wrap;gap:8px 16px}
.w-stackbar__key{display:flex;align-items:center;gap:6px;font-size:var(--text-xs);color:var(--w-row-sub-ink)}
.w-stackbar__dot{width:9px;height:9px;border-radius:3px;flex:none}
.w-stackbar__keylabel{color:var(--w-row-ink);font-weight:650}
.w-stackbar__keyval{font-variant-numeric:tabular-nums}
.w-stackbar__cap{font-size:var(--text-xs);color:var(--w-row-sub-ink);font-variant-numeric:tabular-nums}
/* viz — wrapper for the B2 OrbevaViz-backed molecules (bulletBars/paretoBars/dumbbell/ring); the
   toolkit's own ov-* classes (orbeva-viz.css) carry all colour — this is geometry only. */
.w-viz{margin:8px 0;min-width:0}
.w-viz--ring{display:flex;justify-content:center}
.w-viz--ring svg{width:96px;height:96px}
/* group — side-by-side (default) or stacked composition of child primitives (ring beside bars, stat grid). */
.w-group{display:flex;gap:14px;align-items:center;min-width:0}
.w-group--col{flex-direction:column;align-items:stretch;gap:9px;flex:1;min-width:0}
/* titlePill — severity-toned eyebrow + title + optional status pill (risk widget headers). */
.w-titlepill{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;min-width:0}
.w-titlepill__main{min-width:0}
.w-titlepill__eyebrow{font-size:11px;font-weight:850;text-transform:uppercase;letter-spacing:.08em;overflow-wrap:anywhere}
.w-titlepill__src{margin-left:6px;font-size:11px;font-weight:700;color:var(--ink-dim);white-space:nowrap}
.w-titlepill__title{font-size:var(--text-lg);font-weight:850;color:var(--ink);margin-top:3px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;min-width:0}
.w-titlepill__title--big{font-size:28px}
.w-titlepill__sub{font-size:var(--text-sm);font-weight:800}
.w-titlepill__pill{font-size:11px;font-weight:850;border:1px solid;border-radius:999px;padding:3px 8px;white-space:nowrap;flex:none}
/* Window-tag pills only (bound to windowTag / *.window.tag): caps live here, never in source. State pills stay sentence case. */
.w-titlepill__pill--tag{text-transform:uppercase}
/* splitStat — C1 canon compressed face: left [eyebrow · money ink], right [context · caption]. */
.w-splitstat{display:flex;justify-content:space-between;align-items:baseline;gap:12px;min-width:0}
.w-splitstat__main{display:flex;flex-direction:column;gap:2px;min-width:0}
.w-splitstat__eyebrow{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.w-splitstat__value{font-size:24px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:-.02em;line-height:1.15;white-space:nowrap}
.w-splitstat__value--neg{color:var(--neg)}
.w-splitstat__aside{display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex:none;text-align:right}
.w-splitstat__context{font-size:12px;color:var(--ink-dim);font-variant-numeric:tabular-nums}
.w-splitstat__caption{font-size:11px;color:var(--ink-faint)}
/* faceLink — C1 whole-card tap: the card root IS the <a>; rows tighten to the canon rhythm. */
a.w-facelink{display:block;text-decoration:none;color:inherit;min-width:0}
.w-facelink .w-list__row{padding:6px 0}
/* inviteRow — C4 canon ritual invitation face: 34px icon tile · title · sub · (island pill). */
.w-invite{display:flex;align-items:center;gap:10px;min-width:0}
.w-invite__ico{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:16px;flex:none}
.w-invite__main{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.w-invite__title{font-size:15px;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.w-invite__sub{font-size:var(--text-2xs,11px);color:var(--ink-dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.w-invite__pill{min-height:34px;padding:6px 12px;border:0;border-radius:999px;background:var(--accent);color:var(--accent-ink);font:inherit;font-size:13px;font-weight:600;flex:none;cursor:pointer}
.w-invite__pill:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* riskProof — the 'Why surfaced' provenance block (manifest form of riskProofChip). */
.w-riskproof{margin-top:12px;padding:10px 11px;border-radius:12px;border:1px solid;display:grid;gap:4px}
.w-riskproof__head{display:flex;align-items:center;justify-content:space-between;gap:10px;min-width:0;font-size:11px;font-weight:850;text-transform:uppercase;letter-spacing:.06em;overflow-wrap:anywhere}
.w-riskproof__chips{display:flex;gap:6px;flex-wrap:wrap;min-width:0}
.w-riskproof__more{margin-top:4px}
.w-riskproof__more summary{cursor:pointer;color:var(--ink-dim);font-size:12px;font-weight:800}
/* PROOF-zone disclosure summaries are real controls (DESIGN-LANGUAGE L2 corollary): give every
   proof/riskProof summary the --tap floor + a pointer answer. Scoped to the widget proof zones
   only — page-local summaries own their metrics. */
[data-visual-proof] summary,.w-riskproof__more summary{display:flex;align-items:center;min-height:var(--tap,44px)}
@media (hover:hover){ [data-visual-proof] summary:hover,.w-riskproof__more summary:hover{color:var(--ink)} }
.w-list{display:grid;gap:0;min-width:0}
.w-list__row{display:flex;align-items:center;gap:10px;padding:8px 0;border-top:1px solid var(--w-row-line);min-width:0}
.w-list__row:first-child{border-top:0}
/* Row squeeze contract (re-ratified by founder ruling 2026-07-31): the SUB keeps its intrinsic text
   (flex-basis auto + no shrink) — it carries the glanceable safety fact ('Overdue by 12 days'), which
   a long bank-reported TITLE must never crush. The TITLE is the one shrinkable span and ellipsizes;
   full text stays in the DOM for AT. TWO caps now, one per side:
   • sub max-width 55% (was 70%): at 70% a long sub left the title just TWO characters —
     HoldingsLedger rendered "Ac…" for "Acme Index Fund" at 390px while its sub kept full width.
     A row whose identity is unreadable answers nothing; 55% still gives the safety fact the larger
     share of a 390px row while the title keeps a readable stem.
   • title min-width 8ch: the readable floor.
   • sub min-width min(120px, 33%): the sub's OWN readable floor — with the sub shrinkable, plain
     proportional flex shrink squeezed "Overdue by 12 days" (111px intrinsic) to 87px on a long-title
     row (render-check caught it). 120px seats the canonical safety fact whole; the 33% arm keeps
     narrow rows from over-constraining. The expression MIRRORS render-check's crushedSubs floor
     (min(120, row×0.33)) so the stylesheet and the gate agree by construction.
   With both floors and the 55% cap in place neither side can erase the other. */
.w-list__title{font-size:var(--text-sm);font-weight:700;color:var(--w-row-ink);min-width:8ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 1 auto}
.w-list__sub{font-size:var(--text-xs);color:var(--w-row-sub-ink);flex:0 1 auto;max-width:55%;min-width:min(120px,33%);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.w-list__value{font-size:var(--text-sm);font-weight:800;color:var(--w-row-ink);font-variant-numeric:tabular-nums;flex:none;margin-left:auto}
/* s10 W1 position rows: static row sparkline (period-direction color) + day-% stacked under the value */
.w-list__spark{flex:none;margin-left:auto;display:inline-flex;align-items:center}
.w-list__spark svg{width:56px;height:20px;display:block}
.w-list__spark+.w-list__value,.w-list__spark+.w-list__value--stacked{margin-left:10px}
.w-list__value--stacked{display:grid;justify-items:end;gap:0;line-height:1.2}
.w-list__delta{font-style:normal;font-size:var(--text-xs);font-weight:700;font-variant-numeric:tabular-nums}
.w-list__delta[data-tone="pos"]{color:var(--pos)}
.w-list__delta[data-tone="neg"]{color:var(--neg)}
/* SB5 signal-row hide (×): calm tertiary chrome with a full 44px touch target (founder ≥44px rule) —
   the glyph stays small; negative vertical margin keeps the row's 8px rhythm intact. With no value
   span the button's own margin-left:auto right-aligns it; when a value exists the value's auto margin
   wins and the button trails it by 2px. */
.w-list__hide{flex:none;width:44px;height:44px;margin:-10px -12px -10px auto;display:grid;place-items:center;background:none;border:0;border-radius:12px;color:var(--w-row-sub-ink);font-size:var(--text-lg);line-height:1;cursor:pointer;-webkit-tap-highlight-color:transparent}
.w-list__value+.w-list__hide{margin-left:2px}
@media (hover:hover){.w-list__hide:hover{color:var(--w-row-ink);background:var(--w-chip-bg,rgba(128,128,128,.12))}} /* N6: gated — sticky fill on touch otherwise */
.w-list__hide:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
/* noteList — the PROSE sibling of .w-list: a stacked {title, body} block that WRAPS instead of clipping
   (verbatim educational copy is a full sentence in both slots). Same hairline/rhythm as .w-list, but NO
   nowrap/ellipsis; overflow-wrap + min-width:0 keep a long unbroken token inside the card. */
.w-notelist{display:grid;gap:0;min-width:0}
.w-notelist__block{padding:10px 0;border-top:1px solid var(--w-row-line);min-width:0}
.w-notelist__block:first-child{border-top:0;padding-top:2px}
.w-notelist__title{display:block;font-size:var(--text-sm);font-weight:700;color:var(--w-row-ink);overflow-wrap:break-word;min-width:0}
.w-notelist__body{display:block;margin-top:3px;font-size:var(--text-xs);line-height:1.45;color:var(--w-row-sub-ink);overflow-wrap:break-word;min-width:0}
.w-actions{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-top:2px}
.w-actions__link{display:inline-flex;align-items:center;min-height:32px;padding:0 13px;border-radius:var(--r-pill);background:var(--w-accent);color:var(--w-accent-ink);text-decoration:none;font-size:var(--text-xs);font-weight:850}
@media (max-width:767px){.w-actions__link{min-height:44px}}
.w-actions__note{color:var(--ink-faint);font-size:var(--text-2xs);font-weight:700}

/* Shared proof disclosure used by fact owners that expose source receipts. */
.receipt-evidence{margin-top:5px}
.receipt-evidence summary{display:flex;align-items:center;min-height:var(--tap,44px);color:var(--accent-text);font-size:var(--text-2xs);font-weight:750;cursor:pointer}
.receipt-evidence ul{list-style:none;margin:0;padding:0}
.receipt-evidence li{display:flex;justify-content:space-between;gap:10px;padding:5px 0;font-size:var(--text-2xs);color:var(--ink-dim)}
.receipt-evidence li span{min-width:0;overflow-wrap:anywhere}
.receipt-evidence li b{color:var(--warn);flex:none;font-variant-numeric:tabular-nums}

/* P-A · Elevation tiers — the app-wide view-hierarchy engine. SSOT = Credit A2 (#1674) + the Wealth
   hardening note (docs/WEALTH-TAB-SPEC-2026-07.md §P-A). CSS CLASSES only (never a data-elev grammar);
   token-only → theme-safe. Gate: bin/hierarchy-golden.mjs (≤1 .elev-2 + ≤1 .is-primary per surface).
   .is-primary is NEUTRAL (size/tracking win on a hero; a money figure already carries pos/neg tone, so
   NO 2nd accent colour — A2's original accent bar was dropped at promotion per the Wealth note). */
.elev-1{background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-1)}
.elev-2{border-color:var(--line-strong);box-shadow:var(--shadow-pop)}
.inset{background:var(--surface-2);border:1px solid var(--line);border-radius:12px;box-shadow:none}
.is-primary{letter-spacing:-.02em}
.is-muted{color:var(--ink-faint);font-weight:750}
