/* ==========================================================================
   THE RECORD → PRICING — pinned, scroll-driven transition
   Markup: section#proof in index.html. Driver: the "Record → Pricing pin"
   script at the foot of index.html, which sets on <html>:

     data-pin="on" | "off"   pin only at 768px+, no reduced motion, tall enough
     --pin-t                 0 (Record) → 1 (Pricing), eased, from scroll
     --pin-nav-h             sticky nav height, px
     --pin-stick-h           viewport minus nav — the pinned frame's height
     --pin-dist              scroll distance the pin lasts (one viewport)
     --pin-scale             ≤ 1, shrinks the pinned content to fit short screens
     --pin-offset            top offset that centres the content (final height)

   Everything that moves reads --t, so the state is a pure function of the
   scroll position: fast wheels, trackpads and scrolling back all land on the
   right frame, and nothing is left mid-animation. Without the script (or with
   data-pin="off") the page shows the Record card, then the static Pricing
   card, in normal flow.

   The card's inline styles are re-serialised by dc-runtime on every render,
   so rules that must beat them use !important (see base.css).
   ========================================================================== */

/* Live card follows the scroll; the static copy is always the Pricing state. */
[data-live]   { --t: var(--pin-t, 0); }
[data-static] { --t: 1; }

/* ---- Crossfades ---------------------------------------------------------
   A hand-off, not a blend: Record text fades out over the first half and
   Pricing text fades in over the second, so two different headlines (or
   "31.2%" and "$0") are never legible on top of each other. */
[data-xf="record"]  { opacity: clamp(0, calc(1 - var(--t) * 2), 1); }
[data-xf="pricing"] { opacity: clamp(0, calc(var(--t) * 2 - 1), 1); }

/* Both header blocks sit in the same grid cell (grid-area 1/1), so the cell
   is always as tall as the taller of the two at the current width — no
   pixel height to maintain — and the crossfade never shifts the card below.
   The layers only fade; nothing in the header moves or resizes. */

/* ---- Fee column: the math appears beside the percentage ----------------
   Each row's value cell is a four-column grid — percentage | × base fee |
   = | result. The last three columns grow from zero width with --t, so the
   percentage (which never fades) is pushed left by the formula opening
   beside it, and at --t:0 the cell is exactly the percentage alone: the
   Record state's layout is untouched. Column widths are fixed so the three
   parts line up across every row, and set in ch of the (monospace) data
   font, so they fit "31%", "× $5,000" and "$1,250" exactly at every
   type size instead of reserving pixels the names need. */
[data-val] {
  --c-share: 4ch;               /* "31%" */
  --c-base: 11ch;               /* "× $5,000" with 1.5em either side of ×, at .85em */
  --c-eq: 4ch;                  /* "=" centred with room either side */
  --c-res: 8ch;
  grid-template-columns: var(--c-share) calc(var(--t) * var(--c-base)) calc(var(--t) * var(--c-eq)) calc(var(--t) * var(--c-res));
}
/* Every part has a fixed cell (row 1, its own column). Auto-placement would
   push "Never charged", which spans the empty base-fee slot, onto a second
   row, or give the empty slot an extra column of its own. */
[data-val] > span { grid-row: 1; white-space: nowrap; overflow: hidden; }
/* Below 1280px the card's two columns get narrow enough that the roomier
   spacing could wrap the longest source labels ("Studio 1 Library"); tighten
   it by two characters there so every row stays one line. */
@media (max-width: 1279px) {
  [data-val] { --c-eq: 3ch; --c-res: 7ch; }
}
[data-val-share] { grid-column: 1; text-align: right; }
[data-val-base]  { grid-column: 2; font-size: .85em; }   /* spacing is in the text: 1.5em, ×, 1.5em */
[data-val-eq]    { grid-column: 3; text-align: center; }
[data-val-fee]   { grid-column: 4; text-align: right; font-weight: 700; }
/* "Never charged" has no base fee, so it spans the base and "=" columns too. */
[data-val-fee].val-wide { grid-column: 2 / 5; }

/* Footnote. Pinned, its space is reserved in both states and it only fades
   in, so the card is the same size throughout the transition. In the static
   layout the Record card has no footnote at all, so it collapses there. */
[data-pin-grow] { opacity: clamp(0, calc(var(--t) * 2 - 1), 1); }
[data-pin-grow] > div + div { margin-top: 6px; }   /* space between the note lines */
html:not([data-pin="on"]) [data-live] [data-pin-grow] { display: none; }

/* Phones: the static Pricing card has no room for name + formula on one
   line, so the formula wraps onto a second line under the asset name. */
@media (max-width: 760px) {
  [data-static] [data-legend-row] { flex-wrap: wrap; row-gap: 6px; }
  [data-static] [data-val] {
    flex: 1 0 100%;
    box-sizing: border-box;           /* the indent counts inside the 100% */
    padding-left: 27px;               /* under the name, past the dot */
    grid-template-columns: auto auto auto 1fr;
  }
}

/* ---- Pinned mode ------------------------------------------------------- */
html[data-pin="on"] [data-pin-track] {
  position: relative;
  height: calc(var(--pin-stick-h) + var(--pin-dist));
}
html[data-pin="on"] [data-pin-sticky] {
  position: sticky;
  top: var(--pin-nav-h);
  height: var(--pin-stick-h);
  /* Top-anchored at an offset the script computes from the final height, so
     the block is centred in the frame without drifting as the footnote
     opens. On the frame, not the content, so the scale does not shrink it. */
  box-sizing: border-box;
  padding-top: var(--pin-offset, 20px);
}
html[data-pin="on"] [data-pin-content] {
  width: 100%;
  transform: scale(var(--pin-scale, 1));
  transform-origin: top center;
}
/* #pricing lands on the scroll position where the transition completes:
   the track's top sits at (nav height − pin distance) there. */
html[data-pin="on"] [data-pricing-anchor] {
  position: absolute;
  left: 0;
  top: calc(var(--pin-dist) - var(--pin-nav-h));
  width: 1px;
  height: 1px;
}
html[data-pin="on"] [data-pricing-static] { display: none !important; }

/* ---- Static mode (narrow, reduced motion, short screens, no JS) ---------
   Record card, then the Pricing card. The live card's Pricing layers are
   dropped rather than faded, so each card reads as a single state. */
html:not([data-pin="on"]) [data-live] [data-xf="pricing"] { display: none !important; }
html:not([data-pin="on"]) [data-live] { --t: 0; }
html:not([data-pin="on"]) [data-pricing-anchor] { display: block; scroll-margin-top: 90px; }
[data-static] [data-xf="record"] { display: none !important; }
