/* ==========================================================================
   ds-home.css — Phase 5 (hero) + Phase 6 (homepage sections).

   Requires ds.css (tokens) and ds-components.css (buttons, nav, primitives).
   Everything is scoped under .ds so nothing leaks into the 86 pages that still
   load tokens.css / home.css.

   IDENTITY — "precision finance, in light"
   ---------------------------------------
   The material this product lives in is the ledger: ruled paper, column rules,
   tabular figures, debits and credits, a running balance that has to close.
   Three rules carry that through the whole page:

   1. THE COLUMN RULE is the structural device. A faint vertical hairline grid
      runs behind the page like ruled ledger stock. Sections sit on it; they do
      not float above it in identical cards.

   2. MONO MEANS EXTRACTED. JetBrains Mono is reserved, without exception, for
      values that came out of a statement — dates, amounts, counts, balances,
      field labels. Inter is us talking. So the typography itself tells you
      which half of the page is data and which half is copy.

   3. GREEN MEANS VALIDATED. The accent is never decoration. It marks a figure
      that has been read and checked. Nothing else gets it.

   Section compositions are deliberately all different — asymmetric hero, a
   full-bleed band, a horizontal sequence, a ruled vertical list, a bento, a
   lifecycle timeline, tabs, a scrubber, a comparison table, an accordion, and
   one dark band. No repeated card grid.
   ========================================================================== */

/* ==========================================================================
   PAGE FRAME
   ========================================================================== */

.ds body,
body.ds { margin: 0; }

/* The ledger rules. One element, drawn behind the content, so the grid is
   continuous down the whole page instead of restarting per section. */
.ds .rules {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--wrap-pad);
  /* Four interior rules on a 5-column reading grid. Faint enough to read as
     paper stock rather than as a visible grid overlay. */
  background:
    linear-gradient(to right, transparent calc(20% - .5px), rgba(10,20,16,.045) calc(20% - .5px),
      rgba(10,20,16,.045) calc(20% + .5px), transparent calc(20% + .5px)),
    linear-gradient(to right, transparent calc(40% - .5px), rgba(10,20,16,.045) calc(40% - .5px),
      rgba(10,20,16,.045) calc(40% + .5px), transparent calc(40% + .5px)),
    linear-gradient(to right, transparent calc(60% - .5px), rgba(10,20,16,.045) calc(60% - .5px),
      rgba(10,20,16,.045) calc(60% + .5px), transparent calc(60% + .5px)),
    linear-gradient(to right, transparent calc(80% - .5px), rgba(10,20,16,.045) calc(80% - .5px),
      rgba(10,20,16,.045) calc(80% + .5px), transparent calc(80% + .5px));
  background-clip: content-box;
}
@media (max-width: 900px) { .ds .rules { display: none; } }

.ds main { position: relative; z-index: 1; }

/* Section shell. Bands alternate ground colour rather than adding borders. */
.ds .hsec { position: relative; padding: clamp(64px, 9vw, 120px) 0; }
.ds .hsec-soft { background: var(--c-bg-soft); }
.ds .hsec-sunk { background: var(--c-bg-sunk); }

/* An eyebrow is a FIELD LABEL, not a decorative tag: mono, because it names
   a part of the product, and ruled, because everything here is ruled. */
.ds .eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--c-green-text);
  margin: 0 0 var(--s-4);
}
.ds .eyebrow::before {
  content: "";
  width: 22px;
  height: 1px;
  background: var(--c-green);
  flex: none;
}
.ds .eyebrow-c { justify-content: center; }

/* home.css hides `.reveal` at opacity 0 and relied on home.js to add `.in`.
   home.js is no longer loaded here and ds-motion.js only observes
   `[data-reveal]`, so any leftover `.reveal` would stay invisible forever —
   which is exactly what happened to the converter's heading. Nothing on this
   page should be able to fail closed like that again. */
.ds .reveal { opacity: 1; transform: none; }

.ds .hsec-head { max-width: 62ch; }
/* Section heads need to clear their content; the converter panel and the
   bento/tier grids that follow bring their own top margin, the converter
   does not. */
.ds .hsec-head + .dsc { margin-top: var(--s-8); }
.ds .hsec-head.center { margin-inline: auto; text-align: center; }
.ds .hsec-head h2 {
  font-size: var(--fs-h2);
  font-weight: var(--fw-strong);
  letter-spacing: var(--tr-head);
  line-height: var(--lh-head);
  margin: 0 0 var(--s-4);
  text-wrap: balance;
}
.ds .hsec-head p {
  font-size: var(--fs-body-l);
  color: var(--c-ink-2);
  margin: 0;
  max-width: 58ch;
}
.ds .hsec-head.center p { margin-inline: auto; }

/* Any figure that came out of a statement. Rule 2. */
.ds .val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

/* ==========================================================================
   NAV — extends ds-components.css .nav for this page
   ========================================================================== */

.ds .nav { z-index: 60; }
.ds .brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--c-ink);
  flex: none;
}
.ds .brand-name {
  font-size: 16.5px;
  font-weight: var(--fw-strong);
  letter-spacing: -.022em;
  white-space: nowrap;
}
.ds .brand-name i { font-style: normal; color: var(--c-ink-3); font-weight: var(--fw-medium); }

.ds .nav-toggle { display: none; }

/* Reading progress, hairline, sits on the nav's bottom border. */
.ds .nav-prog {
  position: absolute; left: 0; bottom: -1px; height: 2px; width: 100%;
  transform: scaleX(0); transform-origin: 0 50%;
  background: var(--c-green); opacity: 0;
  transition: opacity var(--t-normal) var(--ease-inout);
}
.ds .nav.is-scrolled .nav-prog { opacity: 1; }

@media (max-width: 960px) {
  .ds .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border: 1px solid var(--c-line-2);
    border-radius: var(--r-control); background: var(--c-surface);
    color: var(--c-ink); cursor: pointer; order: 3;
  }
  .ds .nav-toggle span,
  .ds .nav-toggle span::before,
  .ds .nav-toggle span::after {
    content: ""; display: block; width: 16px; height: 1.5px;
    background: currentColor; border-radius: 2px;
    transition: transform var(--t-fast) var(--ease-out), opacity var(--t-fast) linear;
  }
  .ds .nav-toggle span { position: relative; }
  .ds .nav-toggle span::before { position: absolute; top: -5px; }
  .ds .nav-toggle span::after  { position: absolute; top: 5px; }
  .ds .nav-toggle[aria-expanded="true"] span { background: transparent; }
  .ds .nav-toggle[aria-expanded="true"] span::before { transform: translateY(5px) rotate(45deg); }
  .ds .nav-toggle[aria-expanded="true"] span::after  { transform: translateY(-5px) rotate(-45deg); }

  .ds .nav-links {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--c-surface); border-bottom: 1px solid var(--c-line);
    box-shadow: var(--e-float);
    padding: var(--s-2) var(--wrap-pad) var(--s-4);
    display: none;
  }
  .ds .nav-links.is-open { display: flex; }
  .ds .nav-links a { padding: var(--s-3) 0; font-size: 16px; }
  .ds .nav-links a::after { display: none; }
  .ds .nav-cta .btn-ghost { display: none; }
}
/* Header fit on phones. At 375px the row wants roughly 205px of brand plus
   150px of CTA plus a 40px menu button inside ~343px, and the overflow pushed
   the menu button out of sight — which left the whole nav unreachable, since
   the links are collapsed at this width. The wordmark yields first: the mark
   still identifies the site, and the link keeps its aria-label. */
@media (max-width: 520px) {
  .ds .brand-name { font-size: 14.5px; }
  .ds .nav-cta { gap: var(--s-2); }
}
@media (max-width: 430px) {
  .ds .brand-name { display: none; }
  .ds .nav-cta .btn-sm .ico { display: none; }
}

/* ==========================================================================
   HERO — asymmetric. Type-led left, transformation right.
   Deliberately not centred, and no floating stat pills.
   ========================================================================== */

/* The hero currently sits as a .ds island inside a page that still loads
   home.css. Two of that stylesheet's rules have to be switched off explicitly
   rather than merely out-specified: the violet aurora, which is a ::before, and
   the centred action row. Both are removed in Phase 6 when home.css goes. */
.ds .hero::before { content: none !important; }
.ds .hero-actions { justify-content: flex-start; }

.ds .hero {
  position: relative;
  padding: clamp(48px, 7vw, 92px) 0 clamp(56px, 8vw, 104px);
  /* The 3D stack needs vertical room, so y stays visible. x does not: the
     orbit arcs are inset -12% on the right and between 1000px and 1280px that
     put them 25-45px past the viewport, giving the whole homepage a sideways
     scrollbar. `clip` (not `hidden`) trims that band without making the hero a
     scroll container, and unlike `hidden` it lets the two axes differ. */
  overflow-x: clip;
  overflow-y: visible;
}
.ds .hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
/* Grid items default to min-width:auto, which lets a nowrap descendant widen
   the track past the viewport. Both children opt out explicitly. */
.ds .hero-grid > * { min-width: 0; }

/* A statement period, set like one. This is the first thing that says
   "finance" before a single word of copy is read. */
.ds .hero-period {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-ink-3);
  border: 1px solid var(--c-line-2); border-radius: var(--r-pill);
  padding: 6px 14px 6px 10px; background: var(--c-surface);
}
.ds .hero-period .pip {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--c-green-bright);
  box-shadow: 0 0 0 3px rgba(22,163,74,.16);
}

.ds .hero h1 {
  font-size: var(--fs-display);
  font-weight: var(--fw-strong);
  letter-spacing: var(--tr-display);
  line-height: var(--lh-display);
  margin: var(--s-5) 0 var(--s-5);
  text-wrap: balance;
}
/* The one word that is the product. Underscored with a column rule, because
   that is what the accent means here. */
.ds .hero h1 em {
  font-style: normal;
  position: relative;
  white-space: nowrap;
}
.ds .hero h1 em::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: .06em; height: .09em;
  background: var(--c-green); border-radius: 2px;
  transform: scaleX(0); transform-origin: 0 50%;
  animation: heroRule .7s var(--ease-out) .35s forwards;
}
@keyframes heroRule { to { transform: scaleX(1); } }

.ds .hero-sub {
  font-size: clamp(16.5px, 1.5vw, 19px);
  color: var(--c-ink-2);
  max-width: 52ch;
  margin: 0 0 var(--s-6);
}
.ds .hero-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

/* Facts, ruled like a statement summary, not floated as pills. */
.ds .hero-facts {
  display: flex; flex-wrap: wrap; gap: 0;
  margin-top: var(--s-7);
  border-top: 1px solid var(--c-line);
  padding-top: var(--s-5);
}
.ds .hero-fact { padding-right: var(--s-6); margin-right: var(--s-6);
  border-right: 1px solid var(--c-line); }
.ds .hero-fact:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.ds .hero-fact b {
  display: block; font-family: var(--font-mono); font-size: 21px;
  font-weight: 500; color: var(--c-ink); letter-spacing: -.02em;
}
.ds .hero-fact span { font-size: 12.5px; color: var(--c-ink-3); }
/* Units ride close to the figure — a mono space is too wide to read as one value. */
.ds .hero-fact b .u { font-size: 14px; color: var(--c-ink-3); margin-left: 2px; }

/* ---- The signature: document → rows -----------------------------------
   Built in SVG + CSS 3D rather than WebGL. This is a 2D typographic and
   tabular transformation; keeping it as real DOM text means it stays sharp at
   any DPI, costs no dependency, and collapses to a static end-state under
   reduced motion with one rule instead of a parallel render path. */

.ds .hv {
  position: relative;
  perspective: 1400px;
  min-height: 440px;
  display: grid;
  place-items: center;
}
.ds .hv-inner {
  position: relative;
  width: 100%;
  max-width: 520px;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 6deg)) rotateY(var(--ry, -13deg));
  transition: transform 600ms var(--ease-out);
}

/* Back plate: the PDF page. */
.ds .hv-doc {
  position: relative;
  width: 62%;
  aspect-ratio: 17 / 17;
  background: var(--c-surface);
  border: 1px solid var(--c-line-2);
  border-radius: 6px;
  box-shadow: var(--e-float);
  padding: 26px 22px;
  transform: translateZ(-40px);
  overflow: hidden;
}
/* File-type badges. Original artwork: a document silhouette with a folded
   corner, red for the source PDF and green with a spreadsheet grid for the
   output. Deliberately NOT Adobe's or Microsoft's logo — using either on a
   marketing page would imply an affiliation this product does not have. */
.ds .hv-ftype { display: inline-flex; flex: none; }
.ds .hv-ftype svg { display: block; }
.ds .hv-ftype.pdf {
  position: absolute; top: 10px; right: 12px; z-index: 2;
  width: 22px; height: 25px;
  filter: drop-shadow(0 2px 4px rgba(15, 23, 42, .18));
}
.ds .hv-ftype.pdf svg { width: 22px; height: 25px; }
.ds .hv-ftype.xlsx { width: 15px; height: 17px; }
.ds .hv-ftype.xlsx svg { width: 15px; height: 17px; }
.ds .hv-doc-hd { border-bottom: 1px solid var(--c-line); padding-bottom: 9px; margin-bottom: 10px; }
.ds .hv-doc-hd b {
  display: block; font-size: 9px; font-weight: var(--fw-strong);
  letter-spacing: .12em; color: var(--c-ink); margin-bottom: 3px;
}
.ds .hv-doc-hd span {
  display: block; font-family: var(--font-mono); font-size: 7px;
  color: var(--c-ink-3); letter-spacing: .02em;
}
/* The statement's own text, unstructured: one run-on line per transaction with
   the amount and balance trailing. This is the "before" the sheet resolves. */
.ds .hv-doc-body { font-family: var(--font-mono); font-size: 7.2px; line-height: 2.05; color: var(--c-ink-3); }
.ds .hv-doc-body div { white-space: nowrap; overflow: hidden; text-overflow: clip; }
.ds .hv-doc-body .lit { color: var(--c-green-text); }
.ds .hv-doc-body .faint { color: var(--c-ink-faint); font-style: italic; }

/* The scan sweep. */
.ds .hv-beam {
  position: absolute; left: 0; right: 0; top: 0; height: 34%;
  background: linear-gradient(180deg, transparent, rgba(22,163,74,.13) 62%, rgba(22,163,74,0));
  border-bottom: 1px solid rgba(22,163,74,.5);
  animation: hvBeam 3.4s var(--ease-inout) infinite;
  pointer-events: none;
}
@keyframes hvBeam {
  0%   { transform: translateY(-40%); opacity: 0; }
  12%  { opacity: 1; }
  78%  { opacity: 1; }
  100% { transform: translateY(300%); opacity: 0; }
}

/* Front plate: the sheet. Overlaps the document, pulled forward in Z. */
.ds .hv-sheet {
  position: absolute;
  right: -8%;
  bottom: 2%;
  width: 84%;
  background: var(--c-surface);
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-card);
  box-shadow: 0 2px 6px rgba(10,20,16,.06), 0 36px 70px -34px rgba(10,20,16,.45);
  transform: translateZ(56px);
  overflow: hidden;
}
.ds .hv-sheet-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3);
  padding: 10px 14px;
  border-bottom: 1px solid var(--c-line);
  background: var(--c-bg-soft);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em;
  color: var(--c-ink-3);
}
.ds .hv-sheet-head b { color: var(--c-ink); font-weight: 500; }
.ds .hv-sheet-head .fn { display: inline-flex; align-items: center; gap: 7px;
  min-width: 0; overflow: hidden; }
.ds .hv-sheet-head .fn b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Labelled as an example, plainly. The figures are arithmetically real; the
   statement behind them is not anyone's. */
.ds .hv-tag {
  flex: none; font-size: 8.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--c-green-text); background: var(--c-green-soft);
  border: 1px solid var(--c-green-line); border-radius: var(--r-pill);
  padding: 2px 7px;
}

.ds .hv-cols,
.ds .hv-row {
  display: grid;
  /* Four columns, because a real statement carries a running balance and that
     balance is what the converter checks every row against. */
  grid-template-columns: 42px minmax(0, 1fr) 74px 72px;
  gap: 9px;
  align-items: center;
  padding: 0 13px;
}
.ds .hv-cols {
  height: 26px;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-ink-3);
  border-bottom: 1px solid var(--c-line);
  background: var(--c-surface-2);
}
.ds .hv-cols span:nth-child(3), .ds .hv-cols span:last-child { text-align: right; }
.ds .hv-row {
  height: 34px;
  font-size: 11.5px;
  border-bottom: 1px solid var(--c-line);
}
.ds .hv-row:last-child { border-bottom: 0; }
.ds .hv-row .d { font-family: var(--font-mono); color: var(--c-ink-3); font-size: 10.5px; }
.ds .hv-row .n { color: var(--c-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds .hv-row .a {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  text-align: right; font-size: 11.5px; font-weight: 500;
}
.ds .hv-row .a.pos { color: var(--c-green-text); }
.ds .hv-row .a.neg { color: var(--c-ink); }
.ds .hv-row .b {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  text-align: right; font-size: 11px; color: var(--c-ink-2);
}

/* A row arrives: it slides in from the document's side, then its amount cell
   is briefly washed green — the moment the figure is validated. */
.ds .hv-row.is-in { animation: hvRow .34s var(--ease-out) both; }
@keyframes hvRow {
  from { opacity: 0; transform: translateX(-14px); }
  to   { opacity: 1; transform: none; }
}
.ds .hv-row.is-in .a { animation: hvCell 1s var(--ease-out) both; }
@keyframes hvCell {
  0%, 22% { background: var(--c-green-soft); box-shadow: 0 0 0 3px var(--c-green-soft); }
  100%    { background: transparent; box-shadow: none; }
}

/* Running balance strip — the reconciliation payoff, in mono. */
.ds .hv-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 14px;
  border-top: 1px solid var(--c-line-2);
  background: var(--c-green-soft);
  font-family: var(--font-mono); font-size: 10.5px; color: var(--c-green-text);
  letter-spacing: .04em;
}
.ds .hv-foot b { font-weight: 500; font-size: 10.5px; white-space: nowrap; }

/* Orbit arcs behind the stack. Drawn, not rendered — two curves did not
   justify a raster asset, and as SVG the colour tracks the design tokens. */
.ds .hv-orbit {
  position: absolute;
  inset: -8% -12% -8% -6%;
  width: auto; height: auto;
  transform: translateZ(-90px);
  pointer-events: none;
  overflow: visible;
}
.ds .hv-orbit circle { filter: drop-shadow(0 0 6px rgba(34, 197, 94, .55)); }
@media (max-width: 640px) { .ds .hv-orbit { display: none; } }

/* Connector: a hairline that runs from the page to the sheet. */
.ds .hv-link {
  position: absolute; left: 46%; top: 42%;
  width: 16%; height: 1px;
  background: linear-gradient(90deg, var(--c-line-strong), var(--c-green));
  transform: translateZ(20px);
  pointer-events: none;
}
.ds .hv-link::after {
  content: ""; position: absolute; right: -3px; top: -2.5px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--c-green);
}
@media (max-width: 1080px) { .ds .hv-link { display: none; } }

@media (max-width: 980px) {
  .ds .hero-grid { grid-template-columns: minmax(0, 1fr); }
  .ds .hv { min-height: 380px; margin-top: var(--s-5); }
  .ds .hv-inner { transform: none; max-width: 560px; }
  .ds .hv-doc { transform: none; }
  .ds .hv-sheet { transform: none; }
}
/* ---- Narrow screens ---------------------------------------------------
   Below 640px the overlapped 3D stack is abandoned rather than shrunk. The
   sheet stops being absolutely positioned, so there are no negative offsets
   left to push anything past the viewport edge, and the two halves read as a
   plain vertical sequence: the page above, the rows it became below. */
@media (max-width: 640px) {
  .ds .hv { min-height: 0; display: block; }
  .ds .hv-inner { max-width: none; transform: none; }

  /* The page becomes a strip — enough to read as a statement, not so tall
     that it pushes the sheet below the fold. */
  .ds .hv-doc {
    position: static;
    width: 100%;
    aspect-ratio: auto;
    height: 132px;
    padding: 16px 18px;
    transform: none;
    border-radius: var(--r-control) var(--r-control) 0 0;
    border-bottom: 0;
  }
  .ds .hv-doc .h  { margin-bottom: 5px; }
  .ds .hv-doc .h2 { margin-bottom: 12px; }
  .ds .hv-doc .ln { margin-bottom: 7px; }

  .ds .hv-sheet {
    position: static;
    width: 100%;
    transform: none;
    border-radius: 0 0 var(--r-card) var(--r-card);
    box-shadow: var(--e-card);
  }
  /* Four columns will not fit a phone, and a 4th cell against a 3-column
     track would wrap onto its own row. The balance column is dropped instead —
     the closing balance is still stated in the footer. */
  .ds .hv-cols, .ds .hv-row { grid-template-columns: 52px minmax(0, 1fr) 78px; padding: 0 12px; }
  .ds .hv-cols span:last-child,
  .ds .hv-row .b { display: none; }
}

/* Metrics stop being a single ruled row: at this width the vertical rules
   have nothing left to separate, so they go and the facts wrap into a grid. */
@media (max-width: 620px) {
  .ds .hero-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); }
  .ds .hero-fact { padding: 0; margin: 0; border-right: 0; }
  .ds .hero-fact b { font-size: 19px; }
}
@media (max-width: 380px) {
  .ds .hero-facts { grid-template-columns: minmax(0, 1fr); gap: var(--s-3); }
}

/* Full-width actions below 420px: two nowrap buttons cannot share a 343px
   line, and a stretched target is easier to hit than a shrunken one. */
@media (max-width: 420px) {
  .ds .hero-actions { display: grid; gap: var(--s-3); }
  .ds .hero-actions .btn { width: 100%; }
}

/* ==========================================================================
   BANK COVERAGE — a full-bleed band. Bank names set as mono field values,
   because that is what they are: a value the extractor detected.
   ========================================================================== */

.ds .banks {
  background: var(--c-bg-sunk);
  border-block: 1px solid var(--c-line);
  padding: var(--s-6) 0;
  position: relative; z-index: 1;
}
.ds .banks-lead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap;
  margin-bottom: var(--s-5);
}
.ds .banks-lead p { margin: 0; font-size: 14.5px; color: var(--c-ink-2); }
.ds .banks-lead a { font-size: 13.5px; font-weight: var(--fw-semi); color: var(--c-green-text); text-decoration: none; }
.ds .banks-lead a:hover { text-decoration: underline; text-underline-offset: 3px; }

.ds .marq { overflow: hidden; position: relative; --fade: 64px; }
.ds .marq::before, .ds .marq::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: var(--fade); z-index: 2; pointer-events: none;
}
.ds .marq::before { left: 0;  background: linear-gradient(90deg, var(--c-bg-sunk), transparent); }
.ds .marq::after  { right: 0; background: linear-gradient(270deg, var(--c-bg-sunk), transparent); }
.ds .marq-track {
  display: flex; gap: var(--s-3); width: max-content;
  animation: marq 48s linear infinite;
}
.ds .marq:hover .marq-track { animation-play-state: paused; }
@keyframes marq { to { transform: translateX(-50%); } }
.ds .bchip {
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  padding: 8px 14px;
  background: var(--c-surface); border: 1px solid var(--c-line);
  border-radius: var(--r-control);
  font-family: var(--font-mono); font-size: 12.5px; color: var(--c-ink-2);
  white-space: nowrap;
}
.ds .bchip::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: var(--c-green-bright); flex: none;
}

/* ==========================================================================
   TRANSFORMATION STORY — a horizontal sequence, joined by one rule.
   Not cards: three states of the same line of text.
   ========================================================================== */

.ds .story { position: relative; }
.ds .story-track {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 3.5vw, 48px);
  margin-top: var(--s-8);
  position: relative;
}
/* The rule that runs through all three. */
.ds .story-track::before {
  content: ""; position: absolute; left: 8%; right: 8%; top: 92px; height: 1px;
  background: linear-gradient(90deg, var(--c-line-2) 0%, var(--c-green) 100%);
}
.ds .story-step { position: relative; }
.ds .story-mark {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--c-ink-3);
  background: var(--c-bg-soft); padding-right: 10px;
  margin-bottom: var(--s-4);
}
.ds .story-step:last-child .story-mark { color: var(--c-green-text); }

/* The specimen: the same transaction, at three stages of being understood. */
.ds .spec {
  min-height: 96px;
  background: var(--c-surface);
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-control);
  padding: var(--s-4);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.75;
  color: var(--c-ink-2);
  overflow: hidden;
}
/* Stage 1 — one undifferentiated run of characters. */
.ds .spec-raw { color: var(--c-ink-3); word-break: break-word; }
/* Stage 2 — the same run, split and named. */
.ds .spec-parsed { display: grid; gap: 5px; }
.ds .spec-field { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 8px; }
.ds .spec-field i {
  font-style: normal; font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--c-ink-faint);
}
.ds .spec-field b { font-weight: 500; color: var(--c-ink); }
/* Stage 3 — a validated row. */
.ds .spec-row {
  display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; gap: 10px;
  align-items: center;
  background: var(--c-green-soft); border: 1px solid var(--c-green-line);
  border-radius: 8px; padding: 10px var(--s-3); color: var(--c-ink);
}
.ds .spec-row .a { text-align: right; color: var(--c-green-text); font-weight: 500; }
.ds .spec-check {
  display: flex; align-items: center; gap: 7px; margin-top: 10px;
  font-size: 11px; color: var(--c-green-text); letter-spacing: .02em;
}
.ds .story-step p {
  margin: var(--s-4) 0 0; font-size: 14.5px; color: var(--c-ink-2);
}

@media (max-width: 860px) {
  .ds .story-track { grid-template-columns: minmax(0, 1fr); gap: var(--s-6); }
  .ds .story-track::before { display: none; }
  .ds .story-mark { background: transparent; }
}

/* ==========================================================================
   HOW IT WORKS — genuinely sequential, so it is numbered. Rendered as a
   ruled vertical list with a spine, alternating text and evidence.
   ========================================================================== */

.ds .how-list { margin-top: var(--s-8); position: relative; }
.ds .how-step {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr) minmax(0, .85fr);
  gap: clamp(16px, 3vw, 40px);
  align-items: start;
  padding: var(--s-6) 0;
  border-top: 1px solid var(--c-line);
}
.ds .how-step:last-child { border-bottom: 1px solid var(--c-line); }
.ds .how-n {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--c-ink-faint);
  letter-spacing: .06em;
  padding-top: 4px;
}
.ds .how-step h3 {
  font-size: 21px; font-weight: var(--fw-semi); letter-spacing: var(--tr-head);
  margin: 0 0 var(--s-3);
}
.ds .how-step p { margin: 0; color: var(--c-ink-2); font-size: 15.5px; max-width: 46ch; }
.ds .how-ev {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-control);
  padding: var(--s-4);
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--c-ink-2);
  display: grid;
  gap: 7px;
}
.ds .how-ev .k { color: var(--c-ink-faint); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; }
.ds .how-ev .v { color: var(--c-ink); }
.ds .how-ev .ok { color: var(--c-green-text); }

@media (max-width: 900px) {
  .ds .how-step { grid-template-columns: 42px minmax(0, 1fr); }
  .ds .how-ev { grid-column: 2; }
}

/* ==========================================================================
   BENTO — real size variation, each tile with its own micro-visual.
   ========================================================================== */

.ds .bento {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--s-4);
  margin-top: var(--s-8);
}
.ds .tile {
  position: relative;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  padding: var(--s-6);
  overflow: hidden;
  transition: border-color var(--t-normal) var(--ease-out),
              transform var(--t-normal) var(--ease-out),
              box-shadow var(--t-normal) var(--ease-out);
}
.ds .tile:hover { border-color: var(--c-line-2); transform: translateY(-2px); box-shadow: var(--e-card); }
.ds .tile h3 {
  font-size: 18px; font-weight: var(--fw-semi); letter-spacing: var(--tr-head);
  margin: 0 0 var(--s-3);
}
.ds .tile p { margin: 0; color: var(--c-ink-2); font-size: 14.5px; }
.ds .tile-xl { grid-column: span 4; }
.ds .tile-lg { grid-column: span 3; }
.ds .tile-md { grid-column: span 3; }
.ds .tile-sm { grid-column: span 2; }

/* Tile visual: column alignment. Rows snap from ragged to aligned on hover. */
.ds .viz-align { display: grid; gap: 6px; margin-bottom: var(--s-5); }
.ds .viz-align i {
  display: block; height: 6px; border-radius: 2px; background: var(--c-line-2);
  transition: width var(--t-slow) var(--ease-out), background-color var(--t-slow) var(--ease-out);
}
.ds .viz-align i:nth-child(1) { width: 82%; }
.ds .viz-align i:nth-child(2) { width: 47%; }
.ds .viz-align i:nth-child(3) { width: 69%; }
.ds .viz-align i:nth-child(4) { width: 38%; }
.ds .tile:hover .viz-align i { width: 100%; background: var(--c-green-line); }
.ds .tile:hover .viz-align i:nth-child(2) { transition-delay: 60ms; }
.ds .tile:hover .viz-align i:nth-child(3) { transition-delay: 120ms; }
.ds .tile:hover .viz-align i:nth-child(4) { transition-delay: 180ms; }

/* Tile visual: a small ledger fragment. */
.ds .viz-mini {
  border: 1px solid var(--c-line); border-radius: 8px; overflow: hidden;
  margin-bottom: var(--s-5); font-family: var(--font-mono); font-size: 11px;
}
.ds .viz-mini div {
  display: grid; grid-template-columns: 44px minmax(0,1fr) auto; gap: 8px;
  padding: 7px 10px; border-bottom: 1px solid var(--c-line); color: var(--c-ink-2);
}
.ds .viz-mini div:last-child { border-bottom: 0; }
.ds .viz-mini div span:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.ds .viz-mini .hd { background: var(--c-bg-soft); color: var(--c-ink-faint);
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; }
.ds .viz-mini .ok { color: var(--c-green-text); }

/* Tile visual: format chips. */
.ds .viz-fmt { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: var(--s-5); }
.ds .viz-fmt span {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
  padding: 6px 11px; border-radius: var(--r-pill);
  background: var(--c-bg-sunk); color: var(--c-ink-2); border: 1px solid var(--c-line);
}

/* Tile visual: a big mono figure. */
.ds .viz-num {
  font-family: var(--font-mono); font-size: 40px; font-weight: 500;
  letter-spacing: -.03em; color: var(--c-ink); line-height: 1;
  margin-bottom: var(--s-4);
}
.ds .viz-num small { font-size: 15px; color: var(--c-ink-3); margin-left: 4px; }

@media (max-width: 1000px) {
  .ds .bento { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ds .tile-xl, .ds .tile-lg, .ds .tile-md { grid-column: span 4; }
  .ds .tile-sm { grid-column: span 2; }
}
@media (max-width: 640px) {
  .ds .bento { grid-template-columns: minmax(0, 1fr); }
  .ds .tile-xl, .ds .tile-lg, .ds .tile-md, .ds .tile-sm { grid-column: span 1; }
  .ds .tile { padding: var(--s-5); }
}

/* Auth-state toggling: home.js/ds-home.js flip this on the nav links. */
.ds .hidden { display: none !important; }

/* ==========================================================================
   INTERIM — the header still belongs to home.css until Phase 6 replaces it.
   These rules are not .ds-scoped because the header is not inside the .ds
   island, and this stylesheet is loaded only by the homepage.

   At 375px the header row measures 174px logo + 20px toggle + 144px button
   + 36px page padding = 374px, which is why the CTA was clipping off the
   right edge. Shrinking the logo and the button brings the row back inside
   the viewport without hiding either control.
   ========================================================================== */
/* The `.home`-scoped mobile-nav overrides that used to sit here were removed
   on 2026-09-03 along with home.css: they targeted markup this page no longer
   has (.menu-toggle, .nav-links.open, .brand-logo) and read tokens.css
   variables that are no longer loaded. The live mobile nav is the `.ds`
   block near the top of this file. */

/* ==========================================================================
   FILE LIFECYCLE — a horizontal timeline of what happens to the file.
   Every stage below is a statement about code that exists.
   ========================================================================== */

.ds .life { margin-top: var(--s-8); }
.ds .life-track {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--c-surface);
}
.ds .life-stage {
  padding: var(--s-5);
  border-right: 1px solid var(--c-line);
  position: relative;
}
.ds .life-stage:last-child { border-right: 0; }
.ds .life-stage .t {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-ink-faint); margin-bottom: var(--s-3);
  display: flex; align-items: center; gap: 8px;
}
.ds .life-stage .t::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--c-line-strong); flex: none;
}
.ds .life-stage:last-child .t::before { background: var(--c-green); }
.ds .life-stage:last-child .t { color: var(--c-green-text); }
.ds .life-stage h3 { font-size: 15.5px; font-weight: var(--fw-semi); margin: 0 0 6px; }
.ds .life-stage p { margin: 0; font-size: 13.5px; color: var(--c-ink-2); }

/* The bar under the timeline: where the file exists, over time. */
.ds .life-bar {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  height: 6px; margin-top: var(--s-4);
  border-radius: 3px; overflow: hidden; background: var(--c-bg-sunk);
}
.ds .life-bar i { display: block; }
.ds .life-bar i:nth-child(1) { background: var(--c-green-bright); }
.ds .life-bar i:nth-child(2) { background: var(--c-green); }
.ds .life-bar i:nth-child(3) { background: var(--c-green-line); }
.ds .life-bar i:nth-child(4) { background: transparent; }
.ds .life-legend {
  display: flex; justify-content: space-between; margin-top: 8px;
  font-family: var(--font-mono); font-size: 10.5px; color: var(--c-ink-3);
}

.ds .life-notes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--s-4); margin-top: var(--s-6);
}
.ds .life-note {
  display: flex; gap: var(--s-3); font-size: 14px; color: var(--c-ink-2);
  padding: var(--s-4); background: var(--c-surface);
  border: 1px solid var(--c-line); border-radius: var(--r-control);
}
.ds .life-note svg { flex: none; color: var(--c-green); margin-top: 2px; }

@media (max-width: 900px) {
  .ds .life-track { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ds .life-stage:nth-child(2) { border-right: 0; }
  .ds .life-stage:nth-child(-n+2) { border-bottom: 1px solid var(--c-line); }
  .ds .life-bar, .ds .life-legend { display: none; }
}
@media (max-width: 520px) {
  .ds .life-track { grid-template-columns: minmax(0, 1fr); }
  .ds .life-stage { border-right: 0; border-bottom: 1px solid var(--c-line); }
  .ds .life-stage:last-child { border-bottom: 0; }
}

/* ==========================================================================
   USE CASES — tabs. The panel changes what it shows, not just the words.
   ========================================================================== */

.ds .use-grid {
  display: grid; grid-template-columns: minmax(0, 240px) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px); margin-top: var(--s-7); align-items: start;
}
.ds .use-tabs { display: grid; gap: 2px; }
.ds .use-tab {
  position: relative;
  display: block; width: 100%; text-align: left;
  padding: var(--s-4) var(--s-4) var(--s-4) var(--s-5);
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 15.5px; font-weight: var(--fw-medium);
  color: var(--c-ink-3);
  border-left: 2px solid var(--c-line);
  transition: color var(--t-fast) var(--ease-inout), border-color var(--t-fast) var(--ease-inout);
}
.ds .use-tab:hover { color: var(--c-ink-2); }
.ds .use-tab[aria-selected="true"] {
  color: var(--c-ink); font-weight: var(--fw-semi); border-left-color: var(--c-green);
}
.ds .use-tab small { display: block; font-size: 12px; font-weight: var(--fw-regular); color: var(--c-ink-faint); margin-top: 2px; }

.ds .use-panel {
  background: var(--c-surface); border: 1px solid var(--c-line-2);
  border-radius: var(--r-card); padding: clamp(24px, 3.5vw, 40px);
}
.ds .use-panel[hidden] { display: none; }
.ds .use-panel.is-in { animation: usePanel .34s var(--ease-out) both; }
@keyframes usePanel { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.ds .use-panel h3 { font-size: 22px; font-weight: var(--fw-semi); letter-spacing: var(--tr-head); margin: 0 0 var(--s-3); }
.ds .use-panel > p { margin: 0 0 var(--s-5); color: var(--c-ink-2); font-size: 15.5px; max-width: 54ch; }
.ds .use-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s-4); border-top: 1px solid var(--c-line); padding-top: var(--s-5); }
.ds .use-fact .k { font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-ink-faint); display: block; margin-bottom: 4px; }
.ds .use-fact .v { font-size: 14.5px; color: var(--c-ink); }

@media (max-width: 820px) {
  .ds .use-grid { grid-template-columns: minmax(0, 1fr); }
  .ds .use-tabs { display: flex; overflow-x: auto; gap: var(--s-2); padding-bottom: var(--s-2); }
  .ds .use-tab {
    flex: none; border-left: 0; border-bottom: 2px solid var(--c-line);
    padding: var(--s-3) var(--s-4); white-space: nowrap;
  }
  .ds .use-tab[aria-selected="true"] { border-left-color: transparent; border-bottom-color: var(--c-green); }
  .ds .use-tab small { display: none; }
}

/* ==========================================================================
   BEFORE / AFTER — a native range input drives a clip. Keyboard-operable
   for free, which a custom drag handle would not be.
   ========================================================================== */

.ds .ba { margin-top: var(--s-7); }
.ds .ba-stage {
  position: relative;
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--c-surface);
  --split: 50%;
}
.ds .ba-layer { display: grid; }
.ds .ba-after {
  position: absolute; inset: 0;
  clip-path: inset(0 0 0 var(--split));
  background: var(--c-surface);
}
.ds .ba-hd {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; border-bottom: 1px solid var(--c-line);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-ink-3); background: var(--c-bg-soft);
}
.ds .ba-after .ba-hd { color: var(--c-green-text); background: var(--c-green-soft); }
.ds .ba-body { padding: var(--s-4) var(--s-5) var(--s-5); }

/* Before: a wall of unbroken statement text. */
.ds .ba-before .ba-body {
  font-family: var(--font-mono); font-size: 11.5px; line-height: 2;
  color: var(--c-ink-3); white-space: pre-wrap; word-break: break-word;
}
/* After: the same content, as a ledger. */
.ds .ba-row {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) 88px; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--c-line);
  font-size: 12.5px; align-items: center;
}
.ds .ba-row:last-child { border-bottom: 0; }
.ds .ba-row .d, .ds .ba-row .a { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.ds .ba-row .d { color: var(--c-ink-3); font-size: 11.5px; }
.ds .ba-row .n { color: var(--c-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ds .ba-row .a { text-align: right; font-weight: 500; }
.ds .ba-row .a.pos { color: var(--c-green-text); }
.ds .ba-row.hd {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-ink-faint); border-bottom-color: var(--c-line-2);
}

/* The divider line, drawn at the split. */
.ds .ba-line {
  position: absolute; top: 0; bottom: 0; left: var(--split);
  width: 1px; background: var(--c-green); pointer-events: none; z-index: 3;
}
.ds .ba-line::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 26px; height: 26px; margin: -13px 0 0 -13px;
  border-radius: 50%; background: var(--c-green);
  box-shadow: 0 2px 10px rgba(14,124,63,.45);
}
.ds .ba-range {
  -webkit-appearance: none; appearance: none;
  position: absolute; inset: 0; width: 100%; height: 100%;
  background: transparent; margin: 0; cursor: ew-resize; z-index: 4;
}
.ds .ba-range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 32px; height: 100%; background: transparent; cursor: ew-resize;
}
.ds .ba-range::-moz-range-thumb { width: 32px; height: 200px; background: transparent; border: 0; cursor: ew-resize; }
.ds .ba-range:focus-visible { outline: 2px solid var(--c-green); outline-offset: 3px; }
.ds .ba-hint {
  margin: var(--s-3) 0 0; font-size: 12.5px; color: var(--c-ink-3); text-align: center;
}

@media (max-width: 560px) {
  .ds .ba-row { grid-template-columns: 52px minmax(0, 1fr) 76px; gap: 8px; font-size: 11.5px; }
  .ds .ba-before .ba-body { font-size: 10.5px; }
}

/* ==========================================================================
   PRICING — composed as a ruled comparison, not three floating cards.
   ========================================================================== */

.ds .billing {
  display: inline-flex; gap: 2px; padding: 4px; margin: 0 auto var(--s-7);
  background: var(--c-bg-sunk); border-radius: var(--r-control);
}
.ds .billing-opt {
  border: 0; background: none; cursor: pointer; font: inherit;
  font-size: var(--fs-label); font-weight: var(--fw-semi); color: var(--c-ink-3);
  padding: var(--s-2) var(--s-4); border-radius: 8px;
  transition: background-color var(--t-fast) var(--ease-inout), color var(--t-fast) var(--ease-inout);
}
.ds .billing-opt.active { background: var(--c-surface); color: var(--c-ink); box-shadow: var(--e-control); }
.ds .billing-opt .save {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--c-green-text);
  margin-left: 6px;
}
.ds .billing-wrap { text-align: center; }

/* home.css still styles .tiers/.tier while the page migrates, and its gap,
   radius, shadow and border shorthand survive unless they are reset here by
   name — a border-right alone just overrides one side of its border. */
.ds .tiers {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  border: 1px solid var(--c-line-2); border-radius: var(--r-card);
  background: var(--c-surface);
  align-items: stretch;
}
.ds .tier {
  display: flex; flex-direction: column;
  padding: clamp(24px, 3vw, 36px);
  border: 0; border-right: 1px solid var(--c-line);
  border-radius: 0; box-shadow: none; background: transparent;
  transform: none;
  position: relative;
}
.ds .tier:hover { transform: none; box-shadow: none; }
.ds .tier:last-child { border-right: 0; }
/* Nothing on this page sets box-sizing, so the whole document is content-box.
   A full-width button therefore renders 100% + 48px of padding and crosses the
   column divider. Scoped here rather than flipping box-sizing globally, which
   would quietly resize every padded container mid-migration. */
.ds .tier .btn { margin-top: auto; width: 100%; box-sizing: border-box; }
.ds .tier-pop { background: var(--c-bg-soft); }
/* The accent rule sits ON the container's top border, not under it.
   `inset: 0` put a 3px green bar immediately below the 1px hairline, so along
   the featured column the edge read as a hairline plus a thicker line a pixel
   lower — the step that looked like a stray margin. Pulling it up by the
   border width makes the green replace that segment of the border instead of
   doubling it, which needs the container to stop clipping (nothing else
   overflows it: the two outer columns have no background, and the featured one
   is the middle column, so it never meets a rounded corner). */
.ds .tier-pop::before {
  content: ""; position: absolute; inset: -1px 0 auto 0; height: 3px;
  background: var(--c-green);
}
.ds .tier-tag {
  position: absolute; top: var(--s-5); right: var(--s-5);
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--c-green-text); background: var(--c-green-soft);
  border: 1px solid var(--c-green-line); border-radius: var(--r-pill); padding: 4px 9px;
}
.ds .tier-name { font-size: 15px; font-weight: var(--fw-semi); letter-spacing: var(--tr-head); }
.ds .tier-desc { font-size: 13.5px; color: var(--c-ink-3); margin-top: 2px; min-height: 2.6em; }
.ds .tier-price {
  display: flex; align-items: baseline; gap: 2px; margin: var(--s-4) 0 2px;
  font-family: var(--font-mono); font-weight: 500; letter-spacing: -.03em;
}
.ds .tier-price .cur { font-size: 22px; color: var(--c-ink-3); }
/* home.css paints the amount with a violet gradient clipped to the text. A
   plain `color` cannot undo that: -webkit-text-fill-color wins over color, so
   both it and the background have to be reset explicitly. */
.ds .tier-price .pricing-amount {
  font-size: 46px; line-height: 1;
  background: none;
  color: var(--c-ink);
  -webkit-text-fill-color: var(--c-ink);
}
.ds .tier-pop .tier-price .pricing-amount {
  color: var(--c-green-text);
  -webkit-text-fill-color: var(--c-green-text);
}
.ds .tier-price .pricing-amount.swap { animation: swapIn .28s var(--ease-out); }
@keyframes swapIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.ds .tier-period { font-family: var(--font-mono); font-size: 11.5px; color: var(--c-ink-3); }

/* The quota, stated once, in mono, because it is the number that matters. */
.ds .tier-quota {
  margin: var(--s-5) 0; padding: var(--s-3) var(--s-4);
  background: var(--c-bg-sunk); border-radius: var(--r-control);
  font-family: var(--font-mono); font-size: 12.5px; color: var(--c-ink);
}
.ds .tier-quota small { display: block; font-size: 10.5px; color: var(--c-ink-3); margin-top: 2px; }
.ds .tier-pop .tier-quota { background: var(--c-green-soft); color: var(--c-green-text); }
.ds .tier-pop .tier-quota small { color: var(--c-green-text); opacity: .82; }

.ds .tier ul { list-style: none; margin: 0 0 var(--s-6); padding: 0; display: grid; gap: var(--s-3); }
/* home.css hides these outright — `.home .tier li{opacity:0}` — and only ever
   brings them back through `.tier.reveal.in li`. The rebuilt pricing markup has
   no `.reveal` class, so without this reset the plan features are invisible to
   everyone, not just under a headless capture. */
.ds .tier li {
  display: flex; gap: 10px; font-size: 14px; color: var(--c-ink-2);
  align-items: flex-start;
  opacity: 1; animation: none; transform: none;
}
.ds .tier li svg { flex: none; color: var(--c-green); margin-top: 3px; }
.ds .tier .btn { width: 100%; }

.ds .price-note {
  margin: var(--s-5) 0 0; text-align: center; font-size: 13px; color: var(--c-ink-3);
}
.ds #checkoutMsg { text-align: center; font-size: 14px; color: var(--c-ink-2); min-height: 1.4em; margin: var(--s-4) 0 0; }
.ds #checkoutMsg.error { color: var(--c-danger); }

@media (max-width: 900px) {
  .ds .tiers { grid-template-columns: minmax(0, 1fr); }
  .ds .tier { border-right: 0; border-bottom: 1px solid var(--c-line); }
  .ds .tier:last-child { border-bottom: 0; }
  .ds .tier-desc { min-height: 0; }
}

/* ==========================================================================
   FAQ — native <details>. Keyboard and screen-reader behaviour for free.
   ========================================================================== */

.ds .faq { margin-top: var(--s-7); border-top: 1px solid var(--c-line); }
.ds .faq details { border-bottom: 1px solid var(--c-line); }
.ds .faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  padding: var(--s-5) 0; cursor: pointer; list-style: none;
  font-size: 17px; font-weight: var(--fw-semi); letter-spacing: -.015em;
  color: var(--c-ink);
}
.ds .faq summary::-webkit-details-marker { display: none; }
.ds .faq summary::after {
  content: ""; flex: none; width: 11px; height: 11px;
  border-right: 1.5px solid var(--c-ink-3); border-bottom: 1.5px solid var(--c-ink-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--t-normal) var(--ease-out);
}
.ds .faq details[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.ds .faq summary:hover { color: var(--c-green-text); }
.ds .faq .ans { padding: 0 0 var(--s-5); max-width: 68ch; color: var(--c-ink-2); font-size: 15px; }
.ds .faq .ans p { margin: 0 0 var(--s-3); }
.ds .faq .ans p:last-child { margin-bottom: 0; }
.ds .faq details[open] .ans { animation: faqIn .28s var(--ease-out) both; }
@keyframes faqIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* ==========================================================================
   FINAL CTA — the page's only dark band, so it reads as an ending.
   ========================================================================== */

.ds .cta {
  background: var(--c-ink);
  color: #fff;
  padding: clamp(64px, 8vw, 104px) 0;
  position: relative; z-index: 1; overflow: hidden;
}
/* Ledger rules, inverted, running through the dark band. */
.ds .cta::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: repeating-linear-gradient(90deg,
    rgba(255,255,255,.06) 0 1px, transparent 1px 88px);
  mask-image: linear-gradient(180deg, transparent, #000 40%, #000 60%, transparent);
}
.ds .cta-inner { position: relative; display: grid; gap: var(--s-6); justify-items: center; text-align: center; }
.ds .cta h2 {
  font-size: clamp(30px, 4.4vw, 50px); font-weight: var(--fw-strong);
  letter-spacing: var(--tr-display); line-height: 1.08; margin: 0; max-width: 20ch;
  text-wrap: balance;
}
.ds .cta p { margin: 0; color: rgba(255,255,255,.72); font-size: var(--fs-body-l); max-width: 52ch; }
.ds .cta .eyebrow { color: var(--c-green-bright); justify-content: center; }
.ds .cta .eyebrow::before { background: var(--c-green-bright); }
.ds .cta .btn-secondary {
  background: transparent; color: #fff; border-color: rgba(255,255,255,.28); box-shadow: none;
}
.ds .cta .btn-secondary:hover:not(:disabled):not([data-state]) {
  border-color: rgba(255,255,255,.55); background: rgba(255,255,255,.06);
}
.ds .cta-actions { display: flex; gap: var(--s-3); flex-wrap: wrap; justify-content: center; }
.ds .cta-note { font-family: var(--font-mono); font-size: 11.5px; color: rgba(255,255,255,.5); letter-spacing: .04em; }

/* ==========================================================================
   FOOTER — deliberately absent.

   This file used to carry a second copy of the whole .foot block. ds-site.css
   already defines it, loads first on this page, and lost every tie at equal
   specificity — so the homepage kept the four-column grid after the shared
   footer moved to five, and only the homepage did. One definition, in
   ds-site.css, is the whole point of that file.
   ========================================================================== */

/* ==========================================================================
   REDUCED MOTION — every looping or entrance animation lands at its end state.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .ds .hv-beam { display: none; }
  .ds .marq-track { animation: none; transform: none; }
  .ds .hero h1 em::after { animation: none; transform: scaleX(1); }
  .ds .hv-row.is-in, .ds .hv-row.is-in .a,
  .ds .use-panel.is-in, .ds .faq details[open] .ans { animation: none; }
  .ds .tile:hover { transform: none; }
}

/* ==========================================================================
   RHYTHM PASS — 2026-09-03

   Every section head was reading as one dense block. The cause was a
   specificity tie: `.ds .eyebrow` sets `margin: 0 0 var(--s-4)`, but
   `.ds .hsec-head p { margin: 0 }` is the same weight and comes later in this
   file — and the eyebrow IS a <p>. So inside a section head the eyebrow lost
   its bottom margin entirely and sat flush against the headline. Measured:
   PRICING eyebrow 5271..5300, h2 top 5300. Zero gap.

   Section spacing is now declared once, here, instead of per section.
   ========================================================================== */

.ds .hsec { padding: clamp(80px, 10vw, 152px) 0; }

.ds .hsec-head .eyebrow { margin-bottom: var(--s-5); }
.ds .hsec-head h2 { margin-bottom: var(--s-5); }

/* One gap between a section head and whatever follows it, so the sections
   cannot drift apart from each other again. Anything that brought its own
   top margin gets zeroed rather than added to. */
.ds .hsec-head { margin-bottom: var(--s-8); }
.ds .hsec-head + * { margin-top: 0; }
.ds .hsec-head + .dsc { margin-top: 0; }

/* Pricing: the toggle keeps its space above (that comes from .hsec-head) but
   sits directly on the plan table below it — the 48px I had here read as a
   detached control rather than the header of the columns it switches. */
.ds .billing-wrap { margin-bottom: 0; }

/* The dark closing band carries more padding than a light one at the same
   value: the ground change already reads as a break. */
.ds .cta { padding: clamp(80px, 9vw, 136px) 0; }
.ds .cta-inner { gap: var(--s-5); }
.ds .cta-actions { margin-top: var(--s-3); }
.ds .cta-note { margin-top: var(--s-2); }
