/*
 * §11 `Deep Ledger` — the binding art-direction layer. Loaded on EVERY page, after components.css.
 *
 * §11.3 full-bleed lighting  ·  §11.4 surface/edge/elevation  ·  §11.5 typography and density
 * §11.6 layout grid + dead-space elimination  ·  §11.7 buttons/navigation/rails/icons
 * §11.8 table and dense-data  ·  §11.9 motion choreography
 *
 * Every value here comes from design/omniasset-brand.json via tokens.css. Nothing in this file introduces a
 * literal colour, radius or duration. No backdrop-filter, no glassmorphism, no gradient text, no animated
 * background: §11.21 makes each of those a build failure, and scripts/design/validate_authenticity.py +
 * scripts/design/validate_scene_contract.py enforce it.
 */

/* ══ §11.3 — FULL-BLEED LIGHTING ══════════════════════════════════════════════════════════════════
   Lighting is environmental paint behind real product/data content. It never becomes a decorative blob.
   Hard limits: max two radial sources per section, static only, brand-light opacity <= .22, no filter:blur,
   no star field / particle dust / mesh gradient / aurora / cursor light. The light originates near the
   product visual, never randomly behind copy. */

.oa-scene {
  position: relative;
  isolation: isolate;
  overflow: clip;
  background: var(--oa-bg-0);
}

.oa-scene::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 1;
  background: none;
}

/* Hero / product */
.oa-scene--cobalt {
  background: var(--oa-band-hero);
}
.oa-scene--cobalt::before {
  background: var(--oa-scene-cobalt);
}

/* Track chapter — the same cobalt vocabulary, held back so the hero stays the brightest scene. */
.oa-scene--track {
  background: var(--oa-band-track);
}
.oa-scene--track::before {
  background: var(--oa-scene-track);
}

/* Health / evidence */
.oa-scene--iris {
  background: var(--oa-band-understand);
}
.oa-scene--iris::before {
  background: var(--oa-scene-iris);
}

/* Research / data */
.oa-scene--research {
  background: var(--oa-band-research);
}
.oa-scene--research::before {
  background: var(--oa-scene-research);
}

/* No light */
.oa-scene--neutral {
  background: var(--oa-band-data);
}
.oa-scene--neutral::before {
  background: var(--oa-scene-neutral);
}

/* The deepest neutral band: pricing and the final CTA return to the hero ground. */
.oa-scene--deep {
  background: var(--oa-band-pricing);
}
.oa-scene--deep::before {
  background: none;
}

/* The final CTA returns to cobalt light, low and wide behind the product trace. */
.oa-scene--final {
  background: var(--oa-band-final);
}
.oa-scene--final::before {
  background: var(--oa-scene-final);
}

/* §11.3 — the ONE paper band, and the long-form reading surface. Full viewport width, no rounded outer
   container; the transition into it is a clean 1px boundary, never a floating white rectangle on a dark
   page. `.oa-paper` is the token set; `.oa-scene--paper` is the homepage band and `body.oa-paper-page main`
   is the Learn/Privacy/Terms reader. */
.oa-paper,
.oa-scene--paper,
body.oa-paper-page main {
  color-scheme: light;

  --page: var(--paper);
  --page-deep: var(--paper);
  --surface: var(--paper-surface);
  --surface-raised: var(--paper-surface);
  --surface-2: #EDF0F6;
  --surface-3: #E4E9F2;
  --ink: var(--paper-ink);
  --ink-2: #2C3547;
  --muted: var(--paper-muted);
  --faint: #5C6779;
  --line: var(--paper-line);
  --line-quiet: rgba(22, 34, 56, 0.07);
  --line-strong: rgba(22, 34, 56, 0.2);
  --brand-text: #284FD9;
  --brand-600: #315CF6;
  --iris-text: #5B49D6;
  --focus: #315CF6;
  --positive-text: #067049;
  --warning-text: #8A5100;
  --negative-text: #B4232D;
  --chip: rgba(49, 92, 246, 0.1);
  --shadow-sm: 0 1px 2px rgba(16, 20, 26, 0.06);
  --shadow-md: 0 1px 1px rgba(16, 20, 26, 0.06), 0 8px 24px rgba(16, 20, 26, 0.08);
  --shadow-lg: 0 1px 1px rgba(16, 20, 26, 0.08), 0 16px 38px rgba(16, 20, 26, 0.1);
  --oa-ink-0: var(--paper-ink);
  --oa-ink-1: #2C3547;
  --oa-ink-2: var(--paper-muted);
  --oa-ink-3: #566072;
  --oa-line-0: rgba(22, 34, 56, 0.07);
  --oa-line-1: rgba(22, 34, 56, 0.12);
  --oa-line-2: rgba(22, 34, 56, 0.2);
  --oa-surface-0: var(--paper-surface);
  --oa-surface-1: var(--paper-surface);
  --oa-surface-2: #EDF0F6;
  --oa-surface-3: #E4E9F2;
  --oa-bg-0: var(--paper);
  --oa-shadow-1: 0 1px 1px rgba(16, 20, 26, 0.06), 0 8px 24px rgba(16, 20, 26, 0.07);
  --oa-shadow-2: 0 1px 1px rgba(16, 20, 26, 0.08), 0 16px 38px rgba(16, 20, 26, 0.1);
  --oa-shadow-table: 0 1px 1px rgba(16, 20, 26, 0.05), 0 18px 48px rgba(16, 20, 26, 0.07);

  background: var(--paper);
  color: var(--paper-ink);
}

.oa-scene--paper {
  border-top: 1px solid var(--oa-paper-edge);
  border-bottom: 1px solid var(--oa-paper-edge);
}
.oa-scene--paper::before {
  background: none;
}

/* ══ BAND EDGES — auditor §12 ════════════════════════════════════════════════════════════════════
   "Transition between dark scenes is primarily tonal, not a visible rectangle boundary. At a band edge:
   border-top: 1px solid rgba(205,214,236,.055). Nothing else." The site is one continuous environment;
   the ONE paper band is the single deliberate contrast, and it spans the full viewport width with no
   rounded outer container. */
.oa-scene + .oa-scene { border-top: 1px solid var(--oa-band-edge); }
.oa-scene + .oa-scene--paper,
.oa-scene--paper + .oa-scene { border-top: 1px solid var(--oa-paper-edge); }

/* ══ §11.4 — SURFACE, EDGE AND ELEVATION ═════════════════════════════════════════════════════════
   Hierarchy is solved with open canvas first, border/group second, elevation only when something floats.
   "If an implementer can satisfy a section by inserting another rounded rectangle with an icon and two
   lines of copy, the implementation is wrong." */

/* Open content group — feature explanations, lists, source facts, settings-like content. */
.oa-group {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--oa-line-1);
  border-radius: 0;
  box-shadow: none;
  padding-block: var(--sp-24);
}

/* Standard panel — only for an independently meaningful tool / result / control surface. */
.oa-panel {
  background: var(--oa-surface-1);
  border: 1px solid var(--oa-line-1);
  border-radius: var(--oa-r-surface);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.035),
    var(--oa-shadow-1);
}

/* Floating panel / compare tray. */
.oa-panel--floating {
  background: var(--oa-surface-2);
  border: 1px solid var(--oa-line-2);
  border-radius: var(--oa-r-surface);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.045),
    var(--oa-shadow-2);
}

/* Product device / flagship tool. Auditor: the hero visual is NOT a standalone black rectangle — the
   cobalt illumination originates BEHIND the product and the frame emerges from the dark scene. The 1px
   rim below is the ONLY edge glow on the site. */
.oa-device {
  position: relative;
  background: var(--stage-device);
  border: 1px solid var(--stage-bezel);
  border-radius: var(--oa-r-hero);
  box-shadow: var(--oa-shadow-hero);
  overflow: hidden;
}

.oa-device::before {
  content: "";
  position: absolute;
  inset: 0 14% auto 14%;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(135, 151, 255, 0.18),
    rgba(255, 255, 255, 0.16),
    rgba(120, 103, 242, 0.18),
    transparent
  );
  pointer-events: none;
  z-index: 2;
}

/* Hoverable surface. No scale-on-hover, no 3D tilt. */
@media (hover: hover) and (pointer: fine) {
  .oa-interactive {
    transition:
      transform var(--oa-ui) var(--ease-out),
      border-color var(--oa-ui) var(--ease-out),
      background-color var(--oa-ui) var(--ease-out),
      box-shadow var(--oa-ui) var(--ease-out);
  }

  .oa-interactive:hover {
    transform: translateY(-2px);
    border-color: rgba(143, 159, 255, 0.3);
    background: color-mix(in srgb, var(--oa-surface-1) 94%, var(--oa-cobalt));
  }
}

/* ══ §11.5 — TYPOGRAPHY AND DENSITY ══════════════════════════════════════════════════════════════ */

.oa-display {
  font-family: var(--ff-display);
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  color: var(--oa-ink-0);
  margin: 0;
  text-wrap: balance;
}

.oa-h1 {
  font-family: var(--ff-display);
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: var(--fw-h1);
  letter-spacing: var(--ls-h1);
  color: var(--oa-ink-0);
  margin: 0;
  text-wrap: balance;
}

.oa-h2 {
  font-family: var(--ff-display);
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: var(--fw-h2);
  letter-spacing: var(--ls-h2);
  color: var(--oa-ink-0);
  margin: 0;
  max-width: 18em;
  text-wrap: balance;
}

.oa-h3 {
  font-family: var(--ff-display);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: var(--fw-h3);
  letter-spacing: var(--ls-h3);
  color: var(--oa-ink-0);
  margin: 0;
}

/* §11.5 — headline → lead gap 24px; lead → actions 28px. Never a tiny paragraph 80px under a huge heading. */
.oa-lead {
  margin: var(--sp-24) 0 0;
  font-size: var(--fs-body-l);
  line-height: var(--lh-lead);
  font-weight: var(--fw-lead);
  letter-spacing: var(--ls-lead);
  color: var(--oa-ink-1);
  /* §11.6 hard QA: "no marketing copy column wider than 560px". 48ch of 18px Manrope measured 567px, so the
     ch measure is capped by the pixel rule rather than the other way round. */
  max-width: min(48ch, 560px);
}

.oa-body {
  font-size: var(--fs-16);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  color: var(--oa-ink-1);
  max-width: var(--measure-marketing);
}

.oa-meta {
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  font-weight: var(--fw-meta);
  letter-spacing: var(--ls-meta);
  color: var(--oa-ink-2);
  margin: 0;
}

/* §11.5 — a section label exists only where it identifies a REAL mode/category (HEALTH, RESEARCH,
   DATA SOURCE). It is never a decorative eyebrow above every section; max two words. */
.oa-label {
  display: block;
  font-family: var(--ff-display);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  font-weight: var(--fw-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--oa-ink-2);
  margin: 0 0 var(--sp-16);
}

.oa-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-12);
  margin-top: 28px;
}

/* Financial numerals. */
.oa-num,
.tnum {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: var(--fv-tabular);
}

/* §11.5 — no line of marketing body copy longer than 52ch, and §11.6's hard cap of 560px on a marketing
   copy column. 52ch of 18px Manrope measures 567px, so the pixel rule is the binding one; `min()` keeps
   whichever is narrower at the current type size. */
.oa-scene p {
  max-width: min(var(--measure-marketing), 560px);
}
.oa-scene .oa-panel p,
.oa-scene .oa-device p {
  font-size: var(--fs-14);
}

/* ══ §11.6 — LAYOUT GRID AND DEAD-SPACE ELIMINATION ══════════════════════════════════════════════ */

.oa-wrap {
  width: min(var(--content-max), calc(100% - 64px));
  margin-inline: auto;
}

.oa-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--grid-gap);
}

/* Desktop composition: hero copy 1/span 5, hero visual 6/-1; chapters 5+7 or 7+5, never 50/50 by habit. */
.oa-col-5 { grid-column: 1 / span 5; }
.oa-col-7 { grid-column: 6 / -1; }
.oa-col-7-first { grid-column: 1 / span 7; }
.oa-col-5-last { grid-column: 8 / -1; }
.oa-col-stage { grid-column: 2 / 12; }
.oa-col-full { grid-column: 1 / -1; }

@media (max-width: 1100px) {
  .oa-wrap { width: min(100% - 48px, 1120px); }
  .oa-grid { grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 20px; }
  .oa-col-5,
  .oa-col-7,
  .oa-col-7-first,
  .oa-col-5-last,
  .oa-col-stage,
  .oa-col-full { grid-column: 1 / -1; }
}

@media (max-width: 720px) {
  .oa-wrap { width: calc(100% - 36px); }
  .oa-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
}

/* Vertical rhythm (§11.6). Chapter padding is authored, never "whitespace to look premium". */
.oa-chapter {
  padding-block: var(--section-gap);
}
.oa-chapter--secondary {
  padding-block: var(--section-gap-2);
}
.oa-chapter--hero {
  padding-block: var(--hero-pad-top) var(--hero-pad-bottom);
}
.oa-chapter--feature-hero {
  padding-block: var(--feature-hero-pad-top) var(--hero-pad-bottom);
}

@media (max-width: 720px) {
  .oa-chapter { padding-block: var(--section-gap-mobile); }
  .oa-chapter--secondary { padding-block: var(--section-gap-mobile-2); }
  .oa-chapter--hero,
  .oa-chapter--feature-hero { padding-block: var(--section-gap-mobile-2) var(--section-gap-mobile); }
}

/* §11.6 hard QA — a hero media never drops below 420px when desktop has the room, and a product box is
   never centred inside an empty column. */
.oa-stage-media {
  min-width: 0;
  width: 100%;
}
@media (min-width: 1101px) {
  .oa-stage-media { min-width: 420px; }
}

/* No marketing copy column wider than 560px. */
.oa-copy {
  max-width: 560px;
}

/* Article measures. */
.oa-article { max-width: var(--article-max); }
.oa-article-visual { max-width: var(--article-visual-max); }
.oa-tool { max-width: var(--tool-max); margin-inline: auto; }

/* ══ §11.7 — BUTTONS, NAVIGATION, RAILS, ICONS ═══════════════════════════════════════════════════ */

.btn {
  min-height: 48px;
  border-radius: var(--oa-r-control);
  padding-inline: 20px;
  font-size: var(--fs-14);
  font-weight: 600;
  letter-spacing: 0;
}

.btn--primary {
  background: var(--oa-cobalt);
  border-color: var(--oa-cobalt);
  color: #FFFFFF;
}
.btn--primary:hover {
  background: var(--oa-cobalt-hover);
  border-color: var(--oa-cobalt-hover);
  color: #FFFFFF;
}
.btn--primary:active {
  background: var(--oa-cobalt-pressed);
  border-color: var(--oa-cobalt-pressed);
}

.btn--ghost {
  background: var(--oa-surface-2);
  border: 1px solid var(--oa-line-2);
  color: var(--oa-ink-0);
}
.btn--ghost:hover {
  background: var(--oa-surface-3);
  border-color: rgba(143, 159, 255, 0.35);
  color: var(--oa-ink-0);
}

/* §11.7 — focus is a 2px page gap plus a 3px ring. */
.btn:focus-visible,
.oa-interactive:focus-visible,
.contextnav__item:focus-visible,
.nav__link:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* Header: a solid 68px bar. No floating rounded capsule, no blur/glass. One filled control (Get app). */
.nav {
  height: var(--nav-h);
  background: var(--oa-band-hero);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck {
  background: var(--oa-band-header-stuck);
  border-bottom-color: var(--oa-line-1);
  box-shadow: none;
}
.nav__inner {
  height: var(--nav-h);
}
.nav__link {
  color: var(--oa-ink-1);
}
.nav__link:hover,
.nav__link.is-current {
  color: var(--oa-ink-0);
}
.nav__link::after {
  height: 2px;
  background: var(--oa-cobalt);
}

/* §11.7 family rail — the accessibility/overflow behaviour of W-02/W-38 is untouched; only the look
   changes. Desktop items are quiet text tabs with a cobalt bottom indicator, not a row of floating pills. */
@media (min-width: 721px) {
  .contextnav__item {
    height: 44px;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    background: transparent;
    color: var(--oa-ink-2);
    padding-inline: var(--sp-12);
  }
  .contextnav__item:hover {
    background: transparent;
    color: var(--oa-ink-0);
    border-bottom-color: var(--oa-line-2);
  }
  .contextnav__item[aria-current="page"] {
    background: transparent;
    color: var(--oa-ink-0);
    border-bottom-color: var(--oa-cobalt);
  }
  .contextnav__item[aria-current="page"]::before {
    display: none;
  }
}

/* Mobile keeps compact bordered chips, because horizontal discovery matters there. */
@media (max-width: 720px) {
  .contextnav__item {
    border: 1px solid var(--oa-line-1);
    background: var(--oa-surface-1);
    color: var(--oa-ink-1);
  }
  .contextnav__item[aria-current="page"] {
    border-color: var(--oa-cobalt);
    color: var(--oa-ink-0);
  }
}

/* §11.7 icons — NO default lavender square behind every icon. A background is allowed only for a selected
   state, a warning/success status, or a real device/provider tile. */
.oa-icon {
  color: var(--oa-ink-2);
  flex: none;
}
.oa-icon--brand { color: var(--brand-text); }
.oa-row-icon {
  width: 20px;
  height: 20px;
  color: var(--oa-ink-2);
  flex: none;
}

/* ══ DATA SURFACES — ONE OWNER, ONE MODEL ════════════════════════════════════════════════════════
   Auditor: "White Excel table floating on lavender -> integrated dark DataPlane / CompareMatrix".
   Every table on this site (Compare, Data sources, Security, Pricing, generated fund pages, Learn
   worked examples) resolves through the surfaces below. `components.css` owns the W-38 SCROLL
   behaviour of the region and nothing about how a cell looks — two stylesheets owning one component
   is what produced the colliding columns and the spreadsheet frame that shipped. */

/* ── The data plane: a table's ground, integrated into the band, never a white rectangle on it. */
.oa-table-shell {
  overflow: hidden;
  background: var(--oa-chart-ledger);
  border: 1px solid var(--oa-line-1);
  border-radius: var(--oa-r-chart);
  box-shadow: var(--oa-shadow-table);
}

.oa-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}

/* ── The cell model. Horizontal padding sits BETWEEN columns and is zeroed on the two outer edges,
      so a right-aligned numeric column always clears the next column. The live defect
      (`11,16,950Official price / rate`) was a right-aligned cell with padding-right:0 hard against
      its neighbour, and a first column with padding-left:0 clipped by the shell's overflow. */
.oa-table thead th,
.oa-table tbody th,
.oa-table tbody td {
  padding-inline: 12px;
  text-align: left;
}
.oa-table thead th:first-child,
.oa-table tbody th:first-child,
.oa-table tbody td:first-child { padding-inline-start: 20px; }
.oa-table thead th:last-child,
.oa-table tbody th:last-child,
.oa-table tbody td:last-child { padding-inline-end: 20px; }

.oa-table thead th {
  height: 44px;
  padding-block: 0;
  background: var(--oa-surface-1);
  color: var(--oa-ink-2);
  border-bottom: 1px solid var(--oa-line-1);
  font-family: var(--ff-display);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  white-space: nowrap;
}

.oa-table tbody td,
.oa-table tbody th {
  height: 60px;
  padding-block: 14px;
  color: var(--oa-ink-1);
  border-bottom: 1px solid var(--oa-chart-rule);
  font-size: var(--fs-14);
  font-weight: 450;
  line-height: 1.45;
}

.oa-table tbody tr:last-child td,
.oa-table tbody tr:last-child th { border-bottom: 0; }

/* The identity column and the primary metric carry the weight; metadata stays 13px and quiet, and is
   never crammed into a numeric column. */
.oa-table tbody th[scope="row"] {
  color: var(--oa-ink-0);
  font-weight: 640;
}
.oa-table .is-primary {
  font-weight: 650;
  color: var(--oa-ink-0);
}
.oa-table .is-meta {
  display: block;
  font-size: var(--fs-meta);
  font-weight: 450;
  color: var(--oa-chart-desc);
}

@media (hover: hover) {
  .oa-table tbody tr:hover td,
  .oa-table tbody tr:hover th { background: var(--oa-chart-row-hover); }
}

/* First column left, every NUMERIC metric right. No vertical grid lines: a full cell grid is what
   makes a data table read as a spreadsheet. */
.oa-table .num,
.oa-table td.num,
.oa-table th.num {
  text-align: right;
  font-variant-numeric: tabular-nums lining-nums;
}
.oa-table td.txt,
.oa-table th.txt { text-align: left; }

/* One deliberate frozen/metric-group boundary is the ONLY permitted vertical rule (§11.8). */
.oa-table .is-boundary { border-inline-start: 1px solid var(--oa-chart-vrule); }

.oa-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.oa-sort:hover { color: var(--oa-ink-0); }
.oa-sort[aria-sort="ascending"]::after { content: "\2191"; }
.oa-sort[aria-sort="descending"]::after { content: "\2193"; }

/* ══ SOURCE LEDGER — the Data Sources dense surface ══════════════════════════════════════════════
   Auditor: dark, open rows, horizontal separators only, no vertical lines, 64-72px rows, source name
   15px/650, description 14px muted, cadence plain text with a 5px status dot (not a giant pill), and
   an expandable provenance row rather than a modal. */
.source-ledger {
  background: var(--oa-chart-ledger);
  border: 1px solid var(--oa-line-1);
  border-radius: var(--oa-r-chart);
  overflow: hidden;
  box-shadow: var(--oa-shadow-table);
}
.source-ledger .oa-table thead th { background: var(--oa-surface-1); }
.source-ledger .oa-table tbody td,
.source-ledger .oa-table tbody th { height: 68px; }
.sl__name {
  color: var(--oa-ink-0);
  font-size: 15px;
  font-weight: 650;
}
.sl__desc {
  display: block;
  color: var(--oa-chart-desc);
  font-size: var(--fs-14);
  font-weight: 430;
}
.sl__cadence {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  color: var(--oa-ink-1);
  font-size: var(--fs-14);
  white-space: nowrap;
}
.sl__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--positive);
  flex: none;
}
.sl__dot--partial { background: var(--warning); }
/* Colour is never the sole signal — the state is written out beside the dot as well. */
.sl__state { color: var(--oa-ink-2); }
.sl__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--brand-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.sl__toggle::after {
  content: "";
  width: 7px;
  height: 7px;
  border-inline-end: 1.6px solid currentColor;
  border-block-end: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform var(--oa-ui) var(--ease-out);
}
.sl__toggle[aria-expanded="true"]::after { transform: rotate(225deg) translate(-2px, -2px); }
.sl__toggle:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.source-ledger tr.sl__detail > td {
  height: auto;
  padding-block: 0 20px;
  border-bottom: 1px solid var(--oa-chart-rule);
  background: var(--oa-surface-0);
}
.sl__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-16) var(--sp-32);
  padding-block-start: 4px;
}
.sl__cell { display: flex; flex-direction: column; gap: 3px; }
.sl__k {
  font-family: var(--ff-display);
  font-size: var(--fs-label);
  font-weight: 650;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--oa-ink-3);
}
.sl__v { color: var(--oa-ink-1); font-size: var(--fs-14); }

/* ══ SOURCE PIPELINE — the Data Sources hero. NOT another table. ═════════════════════════════════
   Open rows on the band, each feeding a thin common vertical spine that resolves into the signed
   snapshot. No surrounding white box. */
.src-pipe {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 44px;
}
.src-pipe__rows { display: flex; flex-direction: column; }
.src-pipe__row {
  display: grid;
  grid-template-columns: minmax(96px, 0.55fr) minmax(0, 1.45fr) auto;
  align-items: center;
  gap: var(--sp-16);
  min-height: 52px;
  padding-block: var(--sp-8);
  border-top: 1px solid var(--oa-line-0);
}
.src-pipe__row:first-child { border-top: 0; }
.src-pipe__src { color: var(--oa-ink-0); font-weight: 620; font-size: var(--fs-14); }
.src-pipe__gives { color: var(--oa-chart-desc); font-size: var(--fs-14); }
.src-pipe__spine {
  position: relative;
  border-inline-start: 1px solid var(--oa-line-1);
  margin-inline-start: 21px;
}
.src-pipe__out {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-block-start: var(--sp-16);
  border-top: 1px solid var(--oa-line-1);
  margin-block-start: var(--sp-16);
}
.src-pipe__out .oa-fig__label { color: var(--brand-text); }
@media (max-width: 720px) {
  .src-pipe { grid-template-columns: minmax(0, 1fr); }
  .src-pipe__spine { display: none; }
  .src-pipe__row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 2px; }
  .src-pipe__gives { grid-column: 1 / -1; }
}

/* ══ COMPARE MATRIX — semantic <table>, but it must not read as a spreadsheet ════════════════════
   Auditor: vertical column boundaries ONLY, no full cell grid; grouped metric sections on their own
   34px row; 58px data rows; hover tints the column and the row; the numerically largest result is
   NEVER auto-coloured green, because bigger is not universally better in finance. */
.compare-plane {
  background: var(--oa-chart-compare);
  border: 1px solid var(--oa-line-1);
  border-radius: var(--oa-r-plane);
  box-shadow: var(--oa-shadow-plane);
  overflow: hidden;
}
.compare-plane__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-12);
  padding: var(--sp-24) var(--sp-24) var(--sp-16);
  border-bottom: 1px solid var(--oa-line-1);
}
.compare-matrix { width: 100%; border-collapse: separate; border-spacing: 0; }
.compare-matrix th,
.compare-matrix td {
  padding-inline: 16px;
  text-align: left;
  vertical-align: middle;
}
.compare-matrix th:first-child,
.compare-matrix td:first-child { padding-inline-start: 24px; }
.compare-matrix th:last-child,
.compare-matrix td:last-child { padding-inline-end: 24px; }
/* The only rules are vertical column boundaries plus a quiet row separator. */
.compare-matrix thead th + th,
.compare-matrix tbody td + td { border-inline-start: 1px solid var(--oa-chart-vrule); }
.compare-matrix thead th {
  padding-block: var(--sp-16);
  background: transparent;
  border-bottom: 1px solid var(--oa-line-1);
  vertical-align: bottom;
}
.compare-matrix__fund {
  display: block;
  color: var(--oa-ink-0);
  font-family: var(--ff-display);
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
  text-transform: none;
}
.compare-matrix__cat {
  display: block;
  color: var(--oa-ink-3);
  font-size: var(--fs-meta);
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}
.compare-matrix__group th {
  height: 34px;
  padding-block: 0;
  background: var(--oa-surface-0);
  border-block: 1px solid var(--oa-chart-rule);
  color: var(--oa-chart-group);
  font-family: var(--ff-display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.compare-matrix tbody td,
.compare-matrix tbody th[scope="row"] {
  height: 58px;
  padding-block: 0;
  border-bottom: 1px solid var(--oa-chart-rule);
  font-size: var(--fs-14);
}
.compare-matrix tbody th[scope="row"] {
  color: var(--oa-ink-2);
  font-weight: 500;
}
.compare-matrix tbody td {
  color: var(--oa-ink-0);
  font-weight: 620;
  font-variant-numeric: tabular-nums lining-nums;
}
.compare-matrix tbody td .cm__sub {
  display: block;
  color: var(--oa-ink-3);
  font-size: var(--fs-meta);
  font-weight: 450;
}
@media (hover: hover) {
  .compare-matrix tbody tr:not(.compare-matrix__group):hover td,
  .compare-matrix tbody tr:not(.compare-matrix__group):hover th { background: var(--oa-chart-row-hover); }
  .compare-matrix.is-col-1 tbody td:nth-child(2),
  .compare-matrix.is-col-2 tbody td:nth-child(3),
  .compare-matrix.is-col-3 tbody td:nth-child(4) { background: var(--oa-chart-col-hover); }
}

/* ── Phone: stacked metric groups, not squeezed columns (§12.2). ────────────────────────────────── */
@media (max-width: 720px) {
  .compare-matrix,
  .compare-matrix tbody,
  .compare-matrix tr,
  .compare-matrix td,
  .compare-matrix tbody th[scope="row"] {
    display: block;
    width: auto;
  }
  /* Every cell restates its fund below, so the identity header is no longer carrying anything. */
  .compare-matrix thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

  .compare-matrix__group th {
    display: block;
    height: auto;
    padding: var(--sp-16) var(--sp-16) var(--sp-8);
    border-block: 1px solid var(--oa-chart-rule);
  }
  .compare-matrix tbody th[scope="row"] {
    height: auto;
    padding: var(--sp-16) var(--sp-16) var(--sp-4);
    border-bottom: 0;
    color: var(--oa-ink-0);
    font-family: var(--ff-display);
    font-weight: 640;
  }
  .compare-matrix tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-16);
    height: auto;
    min-height: 40px;
    padding: 6px var(--sp-16);
    border-inline-start: 0;
    border-bottom: 1px solid var(--oa-chart-rule);
    text-align: left;
  }
  /* The fund name comes from the cell's own data, which is why no duplicate markup is needed. */
  .compare-matrix tbody td::before {
    content: attr(data-fund);
    color: var(--oa-ink-2);
    font-family: var(--ff-body);
    font-size: var(--fs-meta);
    font-weight: 500;
  }
  .compare-matrix tbody tr:last-child td:last-child { border-bottom: 0; }
  /* Nothing scrolls horizontally at this width, so the frozen identity column is released. */
  .overflow--table[data-overflow-sticky-col] .compare-matrix th:first-child,
  .overflow--table[data-overflow-sticky-col] .compare-matrix td:first-child {
    position: static;
    background: transparent;
  }
}

/* Plain-language differences ABOVE the matrix — one horizontal insight rail, NOT three cards. */
.insight-rail {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
  gap: var(--sp-24) var(--sp-32);
  padding: var(--sp-24);
  border-bottom: 1px solid var(--oa-line-1);
}
.insight {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-inline-start: var(--sp-16);
  border-inline-start: 2px solid var(--oa-cobalt);
}
.insight__k {
  color: var(--oa-ink-0);
  font-family: var(--ff-display);
  font-size: var(--fs-14);
  font-weight: 650;
}
.insight__v { color: var(--oa-chart-desc); font-size: var(--fs-14); line-height: 1.45; }

/* ══ FINANCIAL CHART — the ONE chart system ══════════════════════════════════════════════════════
   Auditor: "The purple strokes are not charts. They are decorative SVG doodles." Every chart on the
   site — homepage canvas, fund X-ray, allocation trace, Learn worked examples, generated fund pages —
   renders through this frame: a real plot region with reserved gutters, horizontal grid only, labelled
   axes, an area fill, a hover crosshair with a real tooltip, and range controls inside the header. */
.fin-chart {
  position: relative;
  min-height: 320px;
  background:
    radial-gradient(70% 90% at 66% 0%, rgba(49, 92, 246, 0.10), transparent 68%),
    var(--oa-chart-plane);
  border: 1px solid var(--oa-line-1);
  border-radius: var(--oa-r-chart);
  box-shadow: var(--oa-shadow-chart);
  overflow: hidden;
}
/* A light page must not carry the cobalt wash — that reads as the old lavender fog. */
:root[data-theme="light"] .fin-chart,
.oa-paper .fin-chart,
body.oa-paper-page .fin-chart { background: var(--oa-chart-plane); }

/* Controls live INSIDE the chart header, next to the value they change. */
.fin-chart__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-12) var(--sp-24);
  padding: var(--sp-24) var(--sp-24) var(--sp-16);
}
.fin-chart__id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fin-chart__title {
  font-family: var(--ff-display);
  font-size: var(--fs-label);
  font-weight: 650;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--oa-ink-3);
}
.fin-chart__value {
  font-family: var(--ff-display);
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.1;
  color: var(--oa-ink-0);
  font-variant-numeric: tabular-nums lining-nums;
}
.fin-chart__delta {
  font-size: var(--fs-14);
  font-weight: 600;
  color: var(--oa-ink-2);
  font-variant-numeric: tabular-nums lining-nums;
}
.fin-chart__delta .is-pos { color: var(--positive-text); }
.fin-chart__delta .is-neg { color: var(--negative-text); }

/* Restrained 36px range control with a full 44px hit target (W-22), never a giant pill tab. */
.fin-range {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--oa-line-1);
  border-radius: 10px;
  background: var(--oa-surface-0);
}
.fin-range__btn {
  position: relative;
  height: 30px;
  padding-inline: 11px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--oa-ink-2);
  font-family: var(--ff-display);
  font-size: var(--fs-meta);
  font-weight: 620;
  cursor: pointer;
  transition: background-color var(--oa-ui) var(--ease-out), color var(--oa-ui) var(--ease-out);
}
.fin-range__btn::before {
  content: "";
  position: absolute;
  inset: -7px 0;
}
.fin-range__btn:hover { color: var(--oa-ink-0); }
.fin-range__btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.fin-range__btn[aria-pressed="true"] {
  background: var(--oa-surface-2);
  color: var(--oa-ink-0);
}

.fin-chart__plot { position: relative; padding: 0 var(--sp-8) var(--sp-8); }
.fin-chart__svg { display: block; width: 100%; height: auto; overflow: visible; }

/* Plot grammar — exact values. Horizontal grid only; a vertical rule appears only for a selection. */
.fin-grid { stroke: var(--oa-chart-grid); stroke-width: 1; }
.fin-axis { stroke: var(--oa-line-1); stroke-width: 1; }
.fin-tick {
  fill: var(--oa-chart-axis);
  font-family: var(--ff-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
}
.fin-line {
  fill: none;
  stroke: var(--oa-chart-line);
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.fin-line--cmp {
  stroke: var(--oa-chart-cmp);
  stroke-width: 1.5;
  stroke-dasharray: none;
}
.fin-area { fill: url(#oa-fin-area); }
.fin-cross {
  stroke: var(--oa-chart-cross);
  stroke-width: 1;
  opacity: 0;
  transition: opacity var(--oa-fast) linear;
}
.fin-chart.is-probing .fin-cross { opacity: 1; }
.fin-pt {
  r: 7;
  fill: var(--oa-chart-pt);
  stroke: var(--oa-chart-pt-ring);
  stroke-width: 3;
  opacity: 0;
  transition: opacity var(--oa-fast) linear;
}
.fin-chart.is-probing .fin-pt { opacity: 1; }
.fin-key {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-16) var(--sp-24);
  padding: 0 var(--sp-24) var(--sp-24);
}
.fin-key__item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  color: var(--oa-ink-2);
  font-size: var(--fs-meta);
}
.fin-key__item::before {
  content: "";
  width: 16px;
  height: 2px;
  border-radius: 1px;
  background: var(--oa-chart-cmp);
}
.fin-key__item--primary::before { background: var(--oa-chart-line); height: 3px; }
.fin-key__val {
  color: var(--oa-ink-0);
  font-weight: 650;
  font-variant-numeric: tabular-nums lining-nums;
}

/* The tooltip states every series and the difference — never a bare number. */
.fin-tip {
  position: absolute;
  z-index: 3;
  min-width: 178px;
  padding: 10px 12px;
  background: var(--oa-chart-tip);
  border: 1px solid var(--oa-chart-tip-line);
  border-radius: var(--oa-r-tip);
  box-shadow: var(--oa-chart-tip-shadow);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -12px);
  transition: opacity var(--oa-fast) linear;
}
.fin-chart.is-probing .fin-tip { opacity: 1; visibility: visible; }
.fin-tip__d {
  display: block;
  margin-bottom: 6px;
  color: var(--oa-ink-2);
  font-size: var(--fs-meta);
  font-weight: 600;
}
.fin-tip__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-16);
  font-size: var(--fs-meta);
  line-height: 1.7;
}
.fin-tip__k { color: var(--oa-ink-2); }
.fin-tip__v {
  color: var(--oa-ink-0);
  font-weight: 650;
  font-variant-numeric: tabular-nums lining-nums;
}
.fin-tip__row--diff {
  margin-top: 4px;
  padding-top: 5px;
  border-top: 1px solid var(--oa-chart-tip-line);
}

/* Chart motion: first reveal clips the plot open; a range change morphs geometry. Never a line that
   draws itself slowly across the screen, and never a replay on scroll. */
.js-on .fin-chart .fin-plot-clip rect { transform-origin: left center; }
@media (prefers-reduced-motion: no-preference) {
  .js-on .fin-chart.will-enter .fin-area,
  .js-on .fin-chart.will-enter .fin-line { opacity: 0; }
  .js-on .fin-chart.is-in .fin-line {
    animation: fin-reveal 520ms cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  .js-on .fin-chart.is-in .fin-area {
    animation: fin-area-in 420ms cubic-bezier(0.22, 1, 0.36, 1) 100ms both;
  }
  .js-on .fin-chart.is-in .fin-chart__value,
  .js-on .fin-chart.is-in .fin-chart__delta {
    animation: fin-metric-in 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  .fin-chart.is-morphing .fin-line,
  .fin-chart.is-morphing .fin-area { opacity: 0.25; transition: opacity 100ms linear; }
  .fin-chart .fin-line,
  .fin-chart .fin-area { transition: opacity 180ms linear; }
}
@keyframes fin-reveal {
  from { clip-path: inset(0 100% 0 0); opacity: 1; }
  to { clip-path: inset(0 0 0 0); opacity: 1; }
}
@keyframes fin-area-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fin-metric-in { from { opacity: 0; } to { opacity: 1; } }

/* ══ PRICING PLANE — a consumer product decision, not a spreadsheet ══════════════════════════════
   Auditor: one coherent dark plane; Free 40% / Premium 60% inside the SAME surface, divided by one
   1px rule; the allowance choice is a segmented control because it selects a real value; every tier
   value stays in semantic HTML for accessibility and SEO. */
.pricing-plane {
  display: grid;
  grid-template-columns: 40fr 60fr;
  background: var(--oa-chart-plane);
  border: 1px solid var(--oa-line-1);
  border-radius: var(--oa-r-plane);
  box-shadow: var(--oa-shadow-plane);
  overflow: hidden;
}
.pricing-plane__col {
  padding: var(--sp-32);
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: var(--sp-16);
}
/* The feature list takes the slack so both CTAs land on one baseline whatever the list length. */
.pricing-plane__list { flex: 1 1 auto; }
.pricing-plane__col > .btn { margin-block-start: var(--sp-8); }
.pricing-plane__col + .pricing-plane__col { border-inline-start: 1px solid var(--oa-chart-vrule); }
.pricing-plane__kind {
  font-family: var(--ff-display);
  font-size: var(--fs-label);
  font-weight: 650;
  letter-spacing: 0.105em;
  text-transform: uppercase;
  color: var(--oa-ink-3);
}
.pricing-plane__price {
  font-family: var(--ff-display);
  font-size: clamp(2.5rem, 2rem + 2.2vw, 3.5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--oa-ink-0);
  font-variant-numeric: tabular-nums lining-nums;
}
.pricing-plane__note { color: var(--oa-chart-desc); font-size: var(--fs-14); max-width: 46ch; }
.pricing-plane__list {
  list-style: none;
  margin: 0;
  padding: 0;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}
.pricing-plane__list li {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: var(--sp-12);
  align-items: start;
  color: var(--oa-ink-1);
  font-size: var(--fs-14);
  line-height: 1.5;
}
/* Check marks directly — no purple bullet squares. */
.pricing-plane__list li::before {
  content: "";
  width: 11px;
  height: 6px;
  margin-top: 6px;
  border-inline-start: 2px solid var(--brand-text);
  border-block-end: 2px solid var(--brand-text);
  transform: rotate(-45deg);
}
.allowance {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--oa-line-1);
  border-radius: 12px;
  background: var(--oa-surface-0);
  width: fit-content;
  max-width: 100%;
  flex-wrap: wrap;
}
.allowance__btn {
  position: relative;
  min-height: 40px;
  padding-inline: var(--sp-16);
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--oa-ink-1);
  font-family: var(--ff-display);
  font-size: var(--fs-14);
  font-weight: 640;
  cursor: pointer;
  font-variant-numeric: tabular-nums lining-nums;
  transition: background-color var(--oa-ui) var(--ease-out), color var(--oa-ui) var(--ease-out);
}
.allowance__btn::before { content: ""; position: absolute; inset: -2px 0; }
.allowance__btn:hover { color: var(--oa-ink-0); }
.allowance__btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.allowance__btn[aria-pressed="true"] { background: var(--oa-cobalt); color: var(--on-brand); }
.pricing-plane__byok {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-8) var(--sp-16);
  padding-block-start: var(--sp-24);
  color: var(--oa-ink-2);
  font-size: var(--fs-14);
}

/* W-35 `/pricing` — the dedicated route reuses the SAME plane; only the page-level rhythm is local.
   Owned here because `scenes.css` owns `.pricing-plane`, and `scenes.css` loads last (cascade order is
   load order), so an override written in `feature.css` would lose. */
.pricing-facts { row-gap: var(--sp-24, 24px); }
.pricing-facts .hub-rows { margin-block-start: 0; }

@media (max-width: 860px) {
  .pricing-plane { grid-template-columns: minmax(0, 1fr); }
  .pricing-plane__col + .pricing-plane__col {
    border-inline-start: 0;
    border-block-start: 1px solid var(--oa-chart-vrule);
  }
  .pricing-plane__col { padding: var(--sp-24); }
}

/* ══ §11.9 — MOTION CHOREOGRAPHY: only the product moves ═════════════════════════════════════════ */

/* 2. Scene entrance — 520ms, once per page visit, one dominant visual per chapter, max two sub-elements
   staggered 70ms. Driven by js/motion.js at IntersectionObserver threshold .18. */
/* Only an element the observer is ACTIVELY watching is hidden — js/motion.js adds `.will-enter` as it
   registers each one, and a hard timeout releases anything still hidden shortly after load. A bare
   `.oa-enter { opacity: 0 }` made every below-fold scene control an invisible, unreachable target until its
   observer happened to fire, which W-39's reachability suite correctly reads as a hover-only trap. An
   entrance animation must never be able to make content or a control unusable. */
.oa-enter {
  transition:
    opacity var(--oa-scene) var(--ease-out),
    transform var(--oa-scene) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.js-on .oa-enter.will-enter {
  opacity: 0;
  transform: translateY(18px) scale(0.985);
  will-change: opacity, transform;
}
/* A scene holding a control enters on travel alone — never from opacity 0, which would put an invisible
   link or button in the tab order for the length of the animation. */
.js-on .oa-enter.will-move {
  transform: translateY(18px);
  will-change: transform;
}
.js-on .oa-enter.will-enter.is-in,
.js-on .oa-enter.will-move.is-in,
.oa-enter.is-in {
  opacity: 1;
  transform: none;
}

/* 1. Financial-state morph — 320ms. Outgoing fades in the first 110ms, incoming translates 8px→0 over
   240ms, and the outer frame never moves: zero layout jump. */
.oa-morph {
  transition:
    opacity 240ms var(--ease-out),
    transform 240ms var(--ease-out);
}
.oa-morph.is-out {
  opacity: 0;
  transform: translateY(8px);
  transition-duration: 110ms;
}

/* 3. Trace / provenance draw — 560ms, once, cause → result/evidence. No infinite pulse. */
.oa-trace-path {
  stroke-dasharray: var(--trace-len, 1000);
  stroke-dashoffset: var(--trace-len, 1000);
}
.is-in .oa-trace-path,
:root:not(.js-on) .oa-trace-path {
  animation: oa-trace-draw var(--oa-trace) var(--ease-out) forwards;
}
@keyframes oa-trace-draw {
  to { stroke-dashoffset: 0; }
}

.oa-trace-node {
  opacity: 0;
}
.is-in .oa-trace-node,
:root:not(.js-on) .oa-trace-node {
  animation: oa-trace-node var(--oa-state) var(--ease-out) forwards;
  animation-delay: calc(220ms + var(--n, 0) * 110ms);
}
@keyframes oa-trace-node {
  to { opacity: 1; }
}

/* Progressive same-origin route transition. */
@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--oa-view-transition);
  animation-timing-function: var(--ease-out);
}

/* Reduced motion — all translate/scale/path drawing removed; direct opacity <=120ms; charts render their
   final state; NO loss of information. Never move legal prose, data-source rows or table values at all. */
@media (prefers-reduced-motion: reduce) {
  .oa-enter,
  .js-on .oa-enter.will-enter,
  .js-on .oa-enter.will-move,
  .oa-enter.is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .oa-morph,
  .oa-morph.is-out {
    opacity: 1;
    transform: none;
    transition: opacity 120ms linear;
  }
  .oa-trace-path,
  .is-in .oa-trace-path {
    stroke-dashoffset: 0;
    animation: none;
  }
  .oa-trace-node,
  .is-in .oa-trace-node {
    opacity: 1;
    animation: none;
  }
  @view-transition { navigation: none; }
}

/* ══ Page-level bindings ═════════════════════════════════════════════════════════════════════════ */

/* Long-form reading pages (Learn articles, Privacy, Terms) sit on the paper surface below the dark header,
   which is exactly the §11.10 direction: quieter than any marketing page, and extremely readable. The dark
   footer closes the page, so the reader is a deliberate band, not an inconsistent theme. */
body.oa-paper-page {
  background: var(--paper);
}
body.oa-paper-page main {
  border-bottom: 1px solid var(--oa-paper-edge);
}
/* The footer sits OUTSIDE main, so without its own ground it inherited the paper — and its muted ink, set
   for the dark ground, failed contrast on every reading page (Lighthouse a11y 92 on /learn/xirr-vs-cagr/,
   both themes, 2026-09-03). The footer paints the page ground it was designed for. */
body.oa-paper-page .footer {
  background: var(--page);
}


/* ══ The dark chrome strip inside a paper reading page ═══════════════════════════════════════════
   `body.oa-paper-page main` switches the reader onto the paper token set. The breadcrumb + family rail
   above it, and the dark article hero, still sit on the §11.3 hero band — so they keep the DARK roles.
   Without this the rail inherited paper ink on a near-black strip (measured 1.11:1 for the current item). */
:root:not([data-theme="light"]) body.oa-paper-page .feat-top,
:root:not([data-theme="light"]) body.oa-paper-page .oa-scene:not(.oa-scene--paper) {
  --ink: var(--oa-ink-0);
  --ink-2: #C3CAD9;
  --muted: #98A3B6;
  --faint: #8791A6;
  --line: rgba(205, 214, 236, 0.13);
  --line-quiet: rgba(205, 214, 236, 0.08);
  --line-strong: rgba(205, 214, 236, 0.22);
  --surface: #111827;
  --surface-2: #162034;
  --brand-text: #A7B5FF;
  --iris-text: #A79BF9;
  --oa-ink-0: #F4F6FC;
  --oa-ink-1: #C3CAD9;
  --oa-ink-2: #98A3B6;
  --oa-ink-3: #8791A6;
  --oa-line-0: rgba(205, 214, 236, 0.08);
  --oa-line-1: rgba(205, 214, 236, 0.13);
  --oa-line-2: rgba(205, 214, 236, 0.22);
  --oa-surface-0: #0D111A;
  --oa-surface-1: #101622;
  --oa-surface-2: #151C2B;
  --oa-surface-3: #1A2234;
  --chip: rgba(49, 92, 246, 0.2);
  color: var(--oa-ink-0);
}



/* ══ §11.19 — the product device keeps the APP's exact interior colours in both themes ═══════════ */
.oa-device,
.device2,
.home-canvas {
  --page: var(--stage-bg);
  --surface: var(--stage-device);
  --surface-raised: var(--stage-raised);
  --surface-2: var(--stage-raised);
  --ink: var(--stage-ink);
  --ink-2: #C3CAD9;
  --muted: var(--stage-ink-2);
  --faint: var(--stage-ink-3);
  --line: var(--stage-bezel);
  --line-quiet: rgba(205, 214, 236, 0.08);
  --line-strong: rgba(205, 214, 236, 0.22);
  /* Semantic colours are NOT overridden here: the canvas follows the theme, so it must use the theme's
     own AA-checked semantics. Hardcoding the dark values put dark-theme green on a white surface at
     1.81:1. Only the app SURFACE tokens are stage-specific. */
  --oa-ink-0: var(--stage-ink);
  --oa-ink-1: #C3CAD9;
  --oa-ink-2: var(--stage-ink-2);
  --oa-ink-3: var(--stage-ink-3);
  --oa-line-0: rgba(205, 214, 236, 0.08);
  --oa-line-1: rgba(205, 214, 236, 0.13);
  --oa-line-2: rgba(205, 214, 236, 0.22);
  --oa-surface-0: #0B0E16;
  --oa-surface-1: var(--stage-device);
  --oa-surface-2: var(--stage-raised);
  --oa-surface-3: #22304C;
  --oa-chart-plane: #0B0E16;
  --oa-chart-ledger: #0B0E16;
  --oa-chart-compare: #0B0E16;
  --oa-chart-line: #7D69FF;
  --oa-chart-cmp: #77839A;
  --oa-chart-grid: rgba(208, 216, 237, 0.07);
  --oa-chart-axis: #7E899E;
  --oa-chart-track: #20283A;
  --oa-chart-bar: #687CFF;
  --oa-chart-bar-sel: #9A71FF;
  --oa-chart-desc: #AAB3C4;
  --oa-chart-group: #78859A;
  --oa-chart-rule: rgba(255, 255, 255, 0.06);
  --oa-chart-vrule: rgba(255, 255, 255, 0.065);
  --oa-chart-row-hover: rgba(255, 255, 255, 0.025);
  --oa-chart-col-hover: rgba(49, 92, 246, 0.045);
  color: var(--stage-ink);
}

/* The unit sits in the header, set quieter than the label it qualifies, so a reader takes it in once and
   the cells below are pure digits that stack. */
.oa-table thead .oa-unit {
  margin-left: 0.35em;
  font-weight: 500;
  opacity: 0.75;
  text-transform: none;
  letter-spacing: 0;
}

/* ══ Panel depth — a border hierarchy on dark, a layered shadow on light ═════════════════════════
   A single flat 1px border with no depth is what reads as a 1998 box, and it is exactly what the pricing
   surfaces shipped as. Depth comes from one of two things, never from a heavier hairline:

     dark   — a BORDER HIERARCHY (barely visible / standard / prominent) plus a 1px inner top light, which
              is how a near-black surface reads as lifted; shadows are invisible on that ground.
     light  — a LAYERED shadow: one tight low-opacity layer close in, then wider, more diffuse layers. A
              single flat shadow reads as CGI; three stacked ones read as a real object.

   The panel's own ground also has to differ from the band it sits on. A white panel on a white page is a
   rectangle drawn with a line. */
.oa-panel,
.pricing__surface,
.pindex__view {
  background: var(--oa-surface-1);
  border: 1px solid var(--oa-line-1);
  border-radius: var(--oa-r-surface);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    var(--oa-shadow-1);
}

:root[data-theme="light"] .oa-panel,
:root[data-theme="light"] .pricing__surface,
:root[data-theme="light"] .pindex__view {
  background: var(--oa-surface-0);
  border-color: var(--oa-line-0);
  box-shadow: var(--shadow-md);
}

.pricing__surface--premium,
:root[data-theme="light"] .pricing__surface--premium {
  border-color: var(--oa-line-2);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    var(--oa-shadow-2);
}
:root[data-theme="light"] .pricing__surface--premium {
  box-shadow: var(--shadow-lg);
}

/* The table control group sits directly above its table and matches the scene controls above it. */
.oa-tablectl { margin-block-end: var(--sp-16); }
.oa-tablecount {
  margin-block-start: var(--sp-12);
  color: var(--oa-ink-2);
  font-size: var(--fs-meta);
}


/* ── W-10 — the LIVE Compare workspace ───────────────────────────────────────────────────────────────────────
   Same `.compare-plane` / `.compare-matrix` component the fixture scene renders; the live variant adds the
   2–4 fund picker, the selection chips and the omissions note. Nothing here restyles a matrix cell — the
   §11.8 cell model above stays the single owner. */
.compare-plane--live { display: flex; flex-direction: column; gap: var(--sp-16); }
.compare-plane__body { display: flex; flex-direction: column; gap: var(--sp-16); }

.cmp-picker { position: relative; display: flex; flex-direction: column; gap: var(--sp-12); }
.cmp-picker__form {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  min-height: 52px;
  padding-inline: var(--sp-16);
  background: var(--oa-surface-2);
  border: 1px solid var(--oa-line-2);
  border-radius: var(--oa-r-control);
}
.cmp-picker__form:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; border-color: var(--oa-cobalt); }
.cmp-picker__input {
  flex: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--oa-ink-0);
  font: inherit;
  font-size: var(--fs-body-l);
  appearance: none;
}
.cmp-picker__input::placeholder { color: var(--oa-ink-3); }
.cmp-picker__input:focus { outline: none; }

/* The suggestion list is a real list of buttons, not a hover menu: it is reachable by Tab and it stays open
   until something is chosen. */
.cmp-suggest {
  display: flex;
  flex-direction: column;
  max-height: 288px;
  overflow-y: auto;
  background: var(--oa-surface-1);
  border: 1px solid var(--oa-line-2);
  border-radius: var(--oa-r-surface);
}
.cmp-suggest__row {
  display: grid;
  gap: 2px;
  min-height: 56px;
  padding: var(--sp-8) var(--sp-16);
  border: 0;
  border-bottom: 1px solid var(--oa-line-0);
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.cmp-suggest__row:last-child { border-bottom: 0; }
.cmp-suggest__row:hover { background: var(--chip); }
.cmp-suggest__row:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; }
.cmp-suggest__nm { color: var(--oa-ink-0); font-weight: 620; font-size: var(--fs-14); }
.cmp-suggest__mt { color: var(--oa-ink-2); font-size: var(--fs-meta); }

.cmp-chips { display: flex; align-items: center; gap: var(--sp-8); flex-wrap: wrap; }
.cmp-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  padding: 6px 6px 6px var(--sp-12);
  background: var(--chip);
  border: 1px solid var(--oa-line-2);
  border-radius: var(--r-full);
}
.cmp-chip__nm { color: var(--oa-ink-0); font-size: var(--fs-meta); font-weight: 600; }
.cmp-chip__rm {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: var(--r-full);
  background: none;
  color: var(--oa-ink-2);
  font: inherit;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
/* A 28px control still needs a 44px hit area. */
.cmp-chip__rm::before { content: ""; position: absolute; inset: -8px; }
.cmp-chip__rm:hover { color: var(--oa-ink-0); background: var(--oa-surface-3); }
.cmp-chip__rm:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.cmp-chip__hint { color: var(--oa-ink-3); font-size: var(--fs-meta); }

.compare-plane__omitted {
  margin: 0;
  color: var(--oa-ink-3);
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
}
/* The notes under the matrix read as a measured column, not a 48ch rag beside 700px of nothing. */
.compare-plane__body > .compare-plane__omitted,
.compare-plane__body > .oa-fig__meta-line { max-width: 80ch; padding-inline: var(--sp-24); }
.compare-plane__body > .oa-fig__meta-line:last-child { padding-bottom: var(--sp-24); }

/* ── W-10b — the growth chart, the holdings panel, four distinguishable series, the light surface ──────────── */
.cmp-growth { margin: 0 var(--sp-24); }
.cmp-growth .fin-chart { min-height: 0; }
.fin-line--s2 { stroke: var(--oa-chart-s2); }
.fin-line--s3 { stroke: var(--oa-chart-s3); }
.fin-key__item--s2::before { background: var(--oa-chart-s2); }
.fin-key__item--s3::before { background: var(--oa-chart-s3); }

.cmp-holdings { padding: var(--sp-24); border-top: 1px solid var(--oa-line-1); }
.cmp-holdings__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-12);
  margin-bottom: var(--sp-16);
}
.cmp-holdings__legend { display: inline-flex; align-items: center; gap: 6px; margin-left: var(--sp-12); }
.cmp-holdings__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--oa-cobalt); }
.cmp-holdings__grid {
  display: grid;
  grid-template-columns: repeat(var(--n, 2), minmax(0, 1fr));
  gap: var(--sp-24) var(--sp-32);
}
.cmp-holdings__col { display: flex; flex-direction: column; gap: var(--sp-8); min-width: 0; }
.cmp-holdings__fund {
  color: var(--oa-ink-0);
  font-family: var(--ff-display);
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
}
.cmp-holdings__date { color: var(--oa-ink-3); font-size: var(--fs-meta); }
.cmp-holdings__list { margin: var(--sp-4) 0 0; padding: 0; list-style: none; counter-reset: h; }
.cmp-holdings__item {
  display: flex;
  align-items: baseline;
  gap: var(--sp-12);
  min-height: 34px;
  padding: 6px 0;
  border-bottom: 1px solid var(--oa-chart-rule);
  color: var(--oa-ink-1);
  font-size: var(--fs-14);
  counter-increment: h;
}
.cmp-holdings__item::before {
  content: counter(h);
  width: 18px;
  flex: none;
  color: var(--oa-ink-3);
  font-size: var(--fs-meta);
  font-variant-numeric: tabular-nums;
}
.cmp-holdings__nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-holdings__item.is-shared .cmp-holdings__nm::after {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-left: 8px;
  border-radius: 50%;
  background: var(--oa-cobalt);
  vertical-align: 1px;
}
.cmp-holdings__w { color: var(--oa-ink-0); font-weight: 620; font-variant-numeric: tabular-nums lining-nums; }
.cmp-holdings__sectors { display: flex; flex-direction: column; gap: 6px; margin-top: var(--sp-12); }
.cmp-holdings__sector {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(60px, 1.2fr) 52px;
  align-items: center;
  gap: var(--sp-12);
  color: var(--oa-ink-2);
  font-size: var(--fs-meta);
}
.cmp-holdings__sname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-holdings__bar { position: relative; height: 6px; border-radius: 3px; background: var(--oa-chart-track); overflow: hidden; }
.cmp-holdings__bar::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--w, 0%);
  border-radius: 3px;
  background: var(--oa-chart-bar);
}
.cmp-holdings__sector .cmp-holdings__w { text-align: right; }
@media (max-width: 720px) {
  .cmp-holdings__grid { grid-template-columns: minmax(0, 1fr); }
  .cmp-growth { margin: 0 var(--sp-16); }
}

/* Inside the Research sheet the plane sits in an already-elevated surface: no second shadow. */
.compare-plane--sheet { box-shadow: none; }

/* The growth chart is a SECTION of the plane, not a card inside a card: no second border, radius or ground
   of its own; a hairline below it like every other section. */
.compare-plane__body .cmp-growth { margin: 0; border-bottom: 1px solid var(--oa-line-1); }
.compare-plane__body .cmp-growth .fin-chart,
:root[data-theme="light"] .compare-plane__body .cmp-growth .fin-chart {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
/* The custom period: two bounded date fields and one sentence that says what the data can honour. */
.fin-custom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-12) var(--sp-16);
  padding: 0 var(--sp-24) var(--sp-12);
}
.fin-custom__field {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  color: var(--oa-ink-2);
  font-size: var(--fs-meta);
  font-weight: 600;
}
.fin-custom input[type="date"] {
  min-height: 36px;
  padding: 0 var(--sp-8);
  border: 1px solid var(--oa-line-2);
  border-radius: 8px;
  background: var(--oa-surface-0);
  color: var(--oa-ink-0);
  font: inherit;
  font-size: var(--fs-14);
  color-scheme: dark;
}
:root[data-theme="light"] .fin-custom input[type="date"] { color-scheme: light; }
.fin-custom input[type="date"]:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.fin-note { flex-basis: 100%; margin: 0; color: var(--oa-ink-2); font-size: var(--fs-meta); line-height: var(--lh-meta); }
.fin-note:empty { display: none; }
.fin-note.is-warn { color: var(--warning); }

/* The LIGHT theme plane. White-on-white with vertical rules crossing horizontal ones read as an Excel
   grid floating on a white page (the §12.1 hard failure this area was frozen on). Light gets the layered
   shadow every light panel gets, a tinted group row, and horizontal separators only. */
:root[data-theme="light"] .compare-plane {
  border-color: var(--oa-line-1);
  box-shadow: var(--shadow-lg);
}
:root[data-theme="light"] .compare-matrix thead th + th,
:root[data-theme="light"] .compare-matrix tbody td + td { border-inline-start-color: transparent; }
:root[data-theme="light"] .compare-matrix__group th { background: var(--oa-surface-2); }

/* Four funds is the documented maximum, so the column-context tint needs a fourth column. */
@media (hover: hover) {
  .compare-matrix.is-col-4 tbody td:nth-child(5) { background: var(--oa-chart-col-hover); }
}

/* A comparison whose selection has already changed is not the current answer. It keeps its geometry (so
   the page does not collapse and bounce back) but recedes and stops accepting input until the real result
   lands. Opacity only — no spinner, no fake progress; the StateRegion above says what is happening. */
.compare-plane__body.is-stale {
  opacity: .38;
  pointer-events: none;
  /* No transition. This is a CORRECTNESS signal, not decoration: the moment the selection changes, the
     matrix below it is answering a different question, and fading that in over 180ms means the reader
     spends 180ms looking at numbers presented as current. §4 reserves motion for the product itself. */
}
