/* =====================================================================
   THE GILT FOLIO — engine layer  (cascades AFTER demo.css)
   Leaf-Depth parallax: 3 transform-only tiers, ONE sticky curtain,
   a fixed gilt progress thread, roman-numeral chapters, cv-parking.

   GOLDEN FREEZE-SAFE RULE, enforced throughout:
   every hidden / offset / drift state lives ONLY inside
     @supports (animation-timeline: view())  +  @media (prefers-reduced-motion: no-preference)
   so an unsupported engine, a frozen scroll-clock, or a reduced-motion
   user ALWAYS lands on the finished, legible layout. Body copy is painted
   at real coordinates and NEVER parallaxes — it is the legibility anchor.
   ===================================================================== */

/* ---- responsive knobs (mobile-first): the engine reads its budget from the cascade,
        so NO JavaScript ever branches on viewport width. ---- */
:root {
  --amp: 30px;              /* parallax drift amplitude (phone) */
  --rain-cols: 1;
  --marquee-play: paused;
  --fp: 0;                  /* fallback engines: raw scroll px  (set by JS) */
  --fprog: 0;               /* fallback engines: 0..1 page progress (set by JS) */
}
@media (min-width: 640px)  { :root { --amp: 44px; --rain-cols: 1; } }               /* tablet */
@media (min-width: 1024px) { :root { --amp: 56px; --rain-cols: 2; --marquee-play: running; } } /* desktop */

/* =====================================================================
   FIXED GILT PROGRESS THREAD
   ===================================================================== */
#folioThread {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 60;
  transform-origin: left center; transform: scaleX(0);
  background: linear-gradient(90deg, var(--wine) 0%, #D4A853 55%, var(--gold) 100%);
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  #folioThread { animation: folioThreadGrow linear both; animation-timeline: scroll(root block); }
  @keyframes folioThreadGrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}
@supports not (animation-timeline: scroll()) {
  #folioThread { transform: scaleX(var(--fprog, 0)); }
}

/* =====================================================================
   CHAPTER SHELLS  (#readoutBody becomes the folio body)
   ===================================================================== */
#readoutBody.folio-body { max-width: none; }
/* the folio wants the full page column, not the old 780px readout cap */
/* PART-D72 (2026-09-09) W4: the top padding was 0, so the results card sat hard against
   whatever preceded it. Give it real top breathing room, keeping the bottom 3rem. The side
   padding stays 0: the page gutter is main's own clamp(1rem, 4vw, 2.5rem) in styles/demo.css,
   the single source, and this section sits inside main. */
#stage-readout.folio { max-width: none; padding: clamp(2rem, 6vh, 3.5rem) 0 3rem; }

.folio-ch {
  position: relative; z-index: 1;
  background: var(--bg);                 /* opaque — so a rising chapter cleanly occludes the pinned cover */
  /* PART-D75 (2026-09-10) W2 / A12: the vertical padding was clamp(3rem, 9vh, 6rem). On a
     tall desktop viewport the 9vh term dominated and compounded with the parked-chapter
     placeholder below, which is what banked roughly a third of a screen of nothing between
     one card ending and the next chapter's eyebrow. Cut by roughly a third. The horizontal
     term is unchanged. THIS IS A CALIBRATION, EVIDENCED BUT NOT MEASURED against a live
     render, and it is a default that can be retuned.
     PART-D80 (2026-09-10) W5(a) RETUNES IT, on Avery's word of this date: "the spacing between
     the sections still too large to begin with. it should be even smaller ... i nedd ... there to
     be less space between sections". D75 cut clamp(3rem, 9vh, 6rem) to clamp(2.25rem, 6vh, 4rem);
     this cuts it again to clamp(1.6rem, 4.5vh, 3rem), strictly smaller in all three terms so it
     is smaller at every viewport rather than at one measured height. The horizontal term is
     still unchanged, and #stage-readout.folio's own page-level padding (:52) is untouched.
     Folio I is the ONE deliberate exception, and it is given back its own gap in the PART-D80
     block at the foot of this file (W5(c)), commented there so it never reads as a leftover. */
  /* PART-D96 (2026-09-15) SYE-16/SITE-3 (Q26): the top padding is the readout's card step, var(--ro-gap), and the
     bottom is 0, so a chapter seam is ONE var(--ro-gap) like a card seam; side padding is 0 on
     both sides, so chapters share main's own gutter and the readout box sits centred in it. */
  padding: var(--ro-gap) 0 0;
  overflow: visible;                     /* MUST stay visible on the curtain ancestor chain */
  scroll-margin-top: 12px;
}
/* the cover-inner + misc content centre at the page cap; cards/eyebrows get their OWN measure below
   (excluded here so this rule's specificity doesn't out-rank the reading-column max-width) */
/* PART-D96 (2026-09-15) SYE-18/Q9: ONE content box for the readout. Every chapter child (heading
   line, card, park wrapper) is capped at var(--ro-measure) and centred; this replaces the 1180px cap
   and the .ro-card / .folio-eyebrow / .folio-park-inner exclusions described below. The cover's
   inner layer keeps its own rule, in THE COVER block below, for reason (b). */
.folio-ch > :not(.pl-bg):not(.pl-mid):not(.pl-fg):not(.folio-cover-inner) { max-width: var(--ro-measure); margin-left: auto; margin-right: auto; }
/* PART-D86 (2026-09-11) W4 adds .folio-park-inner to the list, beside .folio-cover-inner and for
   the same reason this rule already excludes .ro-card: the wrapper is a structural content layer,
   not content. Capping it at 1180px and centring it would put a second measure between the
   chapter and the cards, which carry their own; the cards would still lay out correctly at their
   own width, but the depth tiers inside the wrapper are inset:0 against it, so the watermark
   would have been cropped to the narrower box on a wide viewport. */
/* .folio-cover-inner is excluded for TWO reasons, both of which bit on desktop:
   (a) this selector is (0,6,0) and was overriding the Cover's own deliberate
       max-width:860px at :244, which is only (0,2,0);
   (b) .folio-cover is the one FLEX chapter, and auto cross-axis margins on a column
       flex item defeat the default stretch - so the inner collapsed to fit-content
       (396px of a 924px column at 1440w) and dragged the 760px hero card down with it,
       which is what made the archetype and its detail block look shrunken and off-centre.
   It centres itself at :244 instead. */
/* content chapters: the eyebrow shares the card's centred reading column so numeral + rule stay on-axis */
.folio-ch:not(.folio-cover) .folio-eyebrow { max-width: var(--ro-measure); margin-left: auto; margin-right: auto; }   /* PART-D96 (2026-09-15) SYE-18: the heading line spans the box, text on its left edge (was 66ch) */

/* the chapter eyebrow: a label type-graphic with an auto roman numeral.
   PART-D96 (2026-09-15) SYE-15/Q2: DM Sans 600 at var(--fs-label), var(--ls-label) (was JetBrains Mono
   clamp(0.7rem, 0.4vw + 0.6rem, 0.82rem), 0.22em); var(--gap-block) to the first block (was 1.4rem). */
.folio-eyebrow {
  font-family: 'DM Sans', system-ui, sans-serif; font-weight: 600; font-size: var(--fs-label);
  letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--gold-text);   /* PART-D96 SYE-3 (Q8): was --gold2 */
  display: flex; align-items: center; gap: 0.8rem; margin-bottom: var(--gap-block);
}
.folio-eyebrow::before { content: "Folio " attr(data-roman) " \00B7\00A0"; color: var(--gold-text); }
.folio-eyebrow::after  { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, var(--border2), transparent); }

/* content-visibility parks OFFSCREEN chapters — III..VII only.
   NEVER on Ch I (.folio-cover, the sticky element) or Ch II (would be a curtain participant). */
/* PART-D75 (2026-09-10) W2 / A12: the reserved placeholder was a flat 760px for every parked
   chapter, so any chapter shorter than that showed the surplus as a void until the reader
   scrolled into it and the correction landed. It is now per-chapter: buildActs() writes
   --parked-est from that chapter's own card count. The 480px fallback covers only the case
   where the JS write has not yet run; the normal path always sets the property. */
/* PART-D86 (2026-09-11) W4, ledger item 3a: THE CONTAINMENT MOVES OFF THE CHAPTER AND ONTO THE
   CHAPTER'S INNER CONTENT WRAPPER, through a child combinator. content-visibility:auto paints the
   element's own box but skips every descendant while parked, and buildActs() used to append the
   chapter eyebrow into the very element carrying folio-park, so a parked chapter showed no
   heading at all, only a reserved void more than a mobile viewport tall on the merged chapter.
   The eyebrow is now a direct, un-parked child of .folio-ch and paints on entering layout; the
   cards and the three decorative depth tiers sit inside .folio-park-inner, which is what parks.
   THE LOW-RISK PATTERN, DELIBERATELY: the folio-park CLASS and the --parked-est custom-property
   write both stay on .folio-ch exactly as D75 and D80 left them, and only this selector moves.
   Custom properties inherit, so the wrapper resolves the chapter's own --parked-est, and neither
   setParkedEstimate() nor setMergedParkedEstimate() needs a single change.
   THE 480px FALLBACK still covers only the case where the JS write has not yet run. */
.folio-ch.folio-park > .folio-park-inner { content-visibility: auto; contain-intrinsic-size: auto var(--parked-est, 480px); }
/* the wrapper is position:relative via :133 below, so the .pl-* tiers inside it fill the wrapper
   rather than the chapter, and the cards inside it still sit above those tiers at real
   coordinates: that is what the second selector on :133 buys. */
.folio-park-inner > :not(.pl-bg):not(.pl-mid):not(.pl-fg) { position: relative; z-index: 1; }

/* =====================================================================
   CH I — THE COVER = the ONE sticky curtain
   (verified: sticks to the viewport even under html/body{overflow-x:clip})
   ===================================================================== */
.folio-cover {
  position: -webkit-sticky; position: sticky; top: 0; z-index: 0;
  min-height: 100vh; min-height: 100svh; min-height: 100dvh;   /* svh/dvh so iOS URL-bar collapse never jumps it */
  display: flex; flex-direction: column; justify-content: center;
  background: var(--bg);
}
/* the covering polish: the Cover gently recedes as Ch II slides over it */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .folio-cover .folio-cover-inner { animation: folioCoverExit linear both; animation-timeline: view(); animation-range: exit 0% exit 100%; }
    @keyframes folioCoverExit { to { opacity: 0.35; transform: scale(0.965); } }
  }
}

/* =====================================================================
   THE THREE DEPTH TIERS  (decorative, behind content; transform/opacity only)
   ===================================================================== */
.pl-bg, .pl-mid, .pl-fg {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  overflow: hidden;                      /* tiers may clip their own ornaments; they are NOT curtain ancestors */
}
/* real content sits above the tiers at real coordinates */
.folio-ch > :not(.pl-bg):not(.pl-mid):not(.pl-fg) { position: relative; z-index: 1; }

/* the oversized illuminated folio numeral — a ghost watermark riding the deep tier.
   Sits in the OUTER margin (not dead-centre behind the card) so it reads as editorial
   marginalia, like spur.us's oversized ghost numerals — translated to gold. */
.folio-watermark {
  position: absolute; top: 50%; right: -0.06em; transform: translateY(-52%);
  font-family: 'Cormorant Garamond', serif; font-weight: 300; font-style: italic; line-height: 0.72;
  font-size: clamp(12rem, 40vw, 30rem); white-space: nowrap;
  color: rgba(240, 200, 110, 0.045);
  -webkit-text-stroke: 1.5px rgba(240, 200, 110, 0.14);
  user-select: none;
}
.folio-cover .folio-watermark { top: 50%; right: auto; left: 50%; transform: translate(-50%, -50%); font-style: normal; color: rgba(240,200,110,0.05); }

/* phone runs 2 tiers (bg + fg); the mid tier joins from tablet up */
.pl-mid { display: none; }
@media (min-width: 640px) { .pl-mid { display: block; } }

/* PRIMARY PATH — compositor scroll-timeline (Chrome/Edge 115+, Safari 26+).
   Drift is an ENHANCEMENT: base state (no animation) is translateY(0) = final layout. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .pl-bg  { --d: calc(var(--amp) * 0.5);  animation: plDrift linear both; animation-timeline: view(); animation-range: entry 0% exit 100%; }
    .pl-mid { --d: calc(var(--amp) * 0.85); animation: plDrift linear both; animation-timeline: view(); animation-range: entry 0% exit 100%; }
    .pl-fg  { --d: calc(var(--amp) * 1.15); animation: plDrift linear both; animation-timeline: view(); animation-range: entry 0% exit 100%; }
    @keyframes plDrift {
      from { transform: translate3d(0, calc(var(--d) *  0.5), 0); }
      to   { transform: translate3d(0, calc(var(--d) * -0.5), 0); }
    }
  }
}
/* FALLBACK PATH — Firefox<155 / Safari<26: one JS-written scroll var drives a gentle page-linked drift. */
@supports not (animation-timeline: view()) {
  /* bounded, page-linked drift: --fprog is 0..1 so displacement never exceeds ~half the amplitude budget
     (unlike raw absolute scrollY, which slid lower-chapter watermarks off-screen) */
  .pl-bg  { transform: translate3d(0, calc((0.5 - var(--fprog, 0.5)) * var(--amp) * 0.4), 0); }
  .pl-mid { transform: translate3d(0, calc((0.5 - var(--fprog, 0.5)) * var(--amp) * 0.7), 0); }
  .pl-fg  { transform: translate3d(0, calc((0.5 - var(--fprog, 0.5)) * var(--amp) * 1.0), 0); }
}

/* =====================================================================
   CHAPTER ENTRANCE — the load-bearing legibility layer (transform-only, IO-driven).
   Base state is fully visible; .in-view merely adds a rise. Works in every engine.
   ===================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .folio-ch.reveal-act.in-view { animation: dossierRise 0.7s var(--ease-cinematic); }
}

/* =====================================================================
   REDUCED-MOTION — converge on the quiet, fully legible static magazine
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  * { animation-timeline: none !important; }
  html { scroll-behavior: auto; }
  #folioThread { display: none; }
  .pl-bg, .pl-mid, .pl-fg { transform: none !important; animation: none !important; }
  .folio-cover { position: static; }                 /* curtain becomes a normal block — reveal is instant */
  .folio-cover .folio-cover-inner { opacity: 1 !important; transform: none !important; animation: none !important; }
  .folio-ch.reveal-act.in-view { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* =====================================================================
   P2 — EDITORIAL BLOCKS
   The readout stops being repeated rounded panels and becomes ONE typeset
   magazine. Restyles the tested card markup IN PLACE — science.js untouched,
   every computed string/number passes through verbatim. Scoped to .folio-ch.
   ===================================================================== */

/* --- kill the panel box; the reading flows as measured columns --- */
.folio-ch .ro-card {
  background: none !important; border: none !important; border-radius: 0 !important;
  box-shadow: none !important; padding: 0; overflow: visible;
  /* PART-D96 (2026-09-15) SYE-16/SYE-18: the card fills the readout box, one var(--ro-gap) below it;
     its text keeps a 66ch measure on the box's left edge (was a 66ch card, clamp(2rem, 5vh, 3.4rem)) */
  margin: 0 auto var(--ro-gap); max-width: var(--ro-measure);
}
/* an editorial hairline separates consecutive readings within a chapter (not on the composed cover) */
.folio-ch:not(.folio-cover) .ro-card + .ro-card {
  border-top: 1px solid var(--border); padding-top: var(--ro-gap);
}
/* PART-D96 (2026-09-15) SYE-17: the next chapter's padding-top is the seam, so a chapter's last card adds no second gap */
.folio-ch:not(.folio-cover) .ro-card:last-child { margin-bottom: 0; }

/* --- headline + label eyebrow --- */
/* eyebrow ABOVE the headline (source order is h3→tag; reverse it in CSS, science.js untouched) */
.folio-ch .ro-card .ro-head { display: flex; flex-direction: column-reverse; align-items: flex-start; margin-bottom: var(--space-2); }
.folio-ch:not(.folio-cover) .ro-card .ro-head { max-width: 66ch; }   /* PART-D96 (2026-09-15) SYE-18: headings on the box's left edge at 66ch */
.folio-ch .ro-card h3 {
  font-family: 'Cormorant Garamond', serif; font-weight: 400;
  font-size: var(--fs-title); line-height: 1.08;   /* PART-D96 (2026-09-15) SYE-15/Q2: h3 is var(--fs-title) (was clamp(1.7rem, 1vw + 1.45rem, 2.45rem)) */
  letter-spacing: -0.012em; color: var(--fg); text-wrap: balance; margin: 0;
}
.folio-ch .ro-card .ro-tag {
  display: block; float: none; margin: 0 0 0.55rem 0;
  /* PART-D96 (2026-09-15) SYE-15/Q2: the house label (was JetBrains Mono 500, 0.6rem, 0.72rem from 900px, 0.24em) */
  font-family: 'DM Sans', system-ui, sans-serif; font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--gold-text);   /* PART-D96 SYE-3 (Q8): was --gold2 */
}

/* --- body copy at a true measure with reading rhythm --- */
/* PART-D96 (2026-09-15) SYE-2/SYE-16/SYE-18: running text is var(--fs-body)/1.6 at 66ch, one block
   step (var(--gap-block), Q26) apart (was 1.02-1.15rem/1.7 and 0.92rem/1.62 at 62ch and 60ch) */
.folio-ch .ro-card p.lede {
  font-size: var(--fs-body); line-height: 1.6;
  color: var(--fg); max-width: 66ch; margin-top: var(--gap-block);
}
.folio-ch .ro-card p.lede + p.lede { margin-top: var(--gap-block); }
.folio-cover .ro-card p.lede { margin-top: var(--space-2); }   /* the Folio I tagline keeps its 1rem step until Q20 (wave 3) */
.folio-ch .ro-card p.soft {
  font-size: var(--fs-body); line-height: 1.6; color: var(--fg2); max-width: 66ch; margin-top: var(--gap-block);
}
/* PART-D96 (2026-09-15) SYE-3 (Q8): gold text in the readout is var(--gold-text) (was --gold / --gold2) */
.folio-ch .ro-card strong, .folio-ch .ro-card b { color: var(--gold-text); font-weight: 600; }
.folio-ch .ro-card em { font-style: italic; color: var(--gold-text); }

/* --- illuminated opener: a gold drop cap on the first paragraph of each chapter (not the cover) --- */
.folio-ch:not(.folio-cover) .folio-eyebrow + .ro-card > p.lede:first-of-type::first-letter {
  font-family: 'Cormorant Garamond', serif; font-weight: 300; color: var(--gold-text);
  float: left; font-size: 3.6em; line-height: 0.66; padding: 0.04em 0.14em 0 0;
  text-shadow: 0 0 22px var(--gold-glow);
}

/* --- cue rows: the leaning bullets, elevated --- */
.folio-ch .lean-list { gap: var(--space-2); margin-top: var(--gap-block); }   /* PART-D96 (2026-09-15) SYE-16: a block step (was 1rem) */
.folio-ch .lean-line { font-size: var(--fs-body); line-height: 1.6; padding-left: 1.5rem; color: var(--fg); max-width: 66ch; }
.folio-ch .lean-line::before { content: "\25C6"; color: var(--gold); font-size: 0.5rem; top: 0.9em; }   /* PART-D96: top follows the 19px line; the ornament is not text */
.folio-ch .lean-firmmark { border-color: var(--border2); background: var(--gold-dim); }

/* --- verse: the portrait prose as a bordered gold pull-quote --- */
.folio-ch .ro-portrait { background: none; }
.folio-ch .portrait-text {
  font-family: 'Cormorant Garamond', serif; font-style: italic; font-weight: 400;
  font-size: var(--fs-lead); line-height: 1.45; color: var(--fg);   /* PART-D96 (2026-09-15) Q2: pull-quote is var(--fs-lead) */
}

/* --- gilt numerals: gone 2026-09-05 with the cover's gauge card (js/overhaul.js enhance()) --- */

/* --- footnote apparatus + guard note (PART-D96 (2026-09-15) SYE-2/SYE-16: body size, 66ch, one block step) --- */
.folio-ch .ro-meaning { font-size: var(--fs-body); border-left: 2px solid var(--gold3); padding-left: 0.9rem; max-width: 66ch; margin-top: var(--gap-block); }
.folio-ch .ro-dd summary { color: var(--fg); }   /* PART-D96 (2026-09-15) SYE-3 (Q8): toggles are var(--fg), not gold */
.folio-ch .guard-note { background: none; border: 1px dashed var(--border2); margin-top: var(--gap-block); }

/* =====================================================================
   THE COVER — Folio I, the illuminated opening plate
   ===================================================================== */
.folio-cover .folio-cover-inner { display: flex; flex-direction: column; align-items: center; text-align: center; width: 100%; max-width: var(--ro-measure); margin-left: auto; margin-right: auto; }   /* PART-D96 (2026-09-15) SYE-18: the readout box (was 860px); the plate stays centred in it */
.folio-cover .folio-eyebrow { justify-content: center; }
.folio-cover .folio-eyebrow::after { display: none; }
.folio-cover .ro-hero {
  display: flex; flex-direction: column; align-items: center; gap: clamp(1.2rem, 3vh, 2rem);
  /* width:100% is load-bearing. The parent .folio-cover-inner is a COLUMN flex container with
     align-items:center, which makes every child shrink-to-fit instead of filling - so without
     a definite width this card sized to its longest text run (395px at 1440w) and never
     reached the 760px measure it declares right here. Same trap as the auto-margin one at :59. */
  border: none; margin: 0; width: 100%; max-width: 760px;
}
/* width:100% for the third time in this chain - .ro-hero is also a column flex with
   align-items:center, so without it the arch sized to the archetype's own text run (395px)
   and capped the lede below its declared 30ch and squeezed the detail block to match. */
.folio-cover .ro-hero .hero-arch { text-align: center; order: 1; min-width: 0; width: 100%; }
/* the archetype label becomes the cover line — a huge italic serif */
.folio-cover .hero-arch .kicker {
  justify-content: center !important; display: block !important;
  font-family: 'Cormorant Garamond', serif !important; font-style: italic; font-weight: 300;
  font-size: clamp(2.6rem, 6vw, 4.8rem); line-height: 1.02; letter-spacing: -0.015em;
  color: var(--fg); text-transform: none !important; margin: 0;
}
.folio-cover .hero-arch .kicker::before, .folio-cover .hero-arch .kicker::after { display: none; }
.folio-cover .hero-arch .lede {
  font-family: 'DM Sans', system-ui, sans-serif; font-style: italic; font-size: var(--fs-lead);   /* PART-D96 (2026-09-15) SYE-15/SYE-3 (Q2/Q8): DM Sans in var(--fg) (was Cormorant in --gold2) */
  color: var(--fg); max-width: 30ch; margin: 0.6rem auto 0; text-align: center;
  text-wrap: balance;   /* even split when the line wraps; see .readout-sub in demo.css */
}
/* the cover stays clean: hide the redundant intro + the inline meaning gloss, but KEEP the
   collapsed "show the detail" so the method/numbers remain one tap away (never dropped) */
.folio-cover .hero-arch .soft, .folio-cover .hero-arch .ro-meaning { display: none; }
.folio-cover .hero-arch .ro-dd { margin-top: 1.4rem; }
.folio-cover .ro-portrait { margin-top: clamp(1rem, 3vh, 2rem); }
.folio-cover .portrait-text { border-left: none; padding-left: 0; text-align: center; max-width: 42ch; margin: 0 auto; }
.folio-cover .ro-portrait .soft { display: none; }
.folio-cover .ro-scroll-hint { margin-top: 2rem; }

/* ---- COVER FIT: the whole curtain (eyebrow → archetype → portrait → hint) must fit ONE
   screen and sit centred, so the sticky Cover reads complete before Ch II slides up over it. Every
   size is viewport-height-aware, so short laptops COMPRESS instead of pushing the portrait
   below the fold (the old overflow was ~200px, so nothing was ever fully readable at rest).
   The crest that used to sit between archetype and portrait went 2026-09-05. ---- */
.folio-cover { padding-top: clamp(4.1rem, 8.5vh, 5.1rem); padding-bottom: clamp(0.4rem, 1.5vh, 1.1rem); }
.folio-cover .folio-eyebrow { margin-bottom: clamp(0.5rem, 1.7vh, 1.2rem); }
.folio-cover .ro-hero { gap: clamp(0.6rem, 2.1vh, 1.6rem); }
.folio-cover .hero-arch .kicker { font-size: clamp(2rem, min(5.6vw, 5.9vh), 4rem); line-height: 1.02; }
/* PART-D96 (2026-09-15) SYE-2/Q2: tagline and pull-quote sizes are var(--fs-lead). The tagline's two
   declarations are still out-ranked by .folio-ch .ro-card p.lede (0,3,1), so it renders at var(--fs-body)
   until Q20 restyles the cover; the archetype name above is left for Q20. */
.folio-cover .hero-arch .lede { font-size: var(--fs-lead); margin-top: 0.25rem; }
.folio-cover .hero-arch .ro-dd { margin-top: clamp(0.5rem, 1.5vh, 1.05rem); }

/* .hero-arch carries flex:1 1 300px from the general readout hero, where it sits BESIDE a
   figure in a row. The cover stacks in a COLUMN, so that basis would be ~165px of dead
   vertical space under the detail line; keep it auto here. (The crest and caption rules
   that used to follow went 2026-09-05 with the gauge card.) */
.folio-cover .ro-hero .hero-arch { flex: 0 0 auto; }
/* margin-inline:auto is what centres this. .ro-portrait is a .ro-card, and folio.css:59
   excludes .ro-card from the chapter-child centring, so it inherited margin-left:0 with
   margin-right absorbing the leftover - which LEFT-aligns it, 195px off centre inside a
   centred column. align-self:center does NOT fix it: auto margins beat align-self in
   flexbox, so the margin has to be balanced rather than the alignment overridden.
   width:100% would also centre it but stretch a portrait paragraph to the full 680px. */
.folio-cover .ro-portrait { margin-top: clamp(0.5rem, 1.9vh, 1.35rem); margin-bottom: 0; margin-left: auto; margin-right: auto; }
.folio-cover .portrait-text { font-size: var(--fs-lead); line-height: 1.45; max-width: 44ch; }
/* the scroll cue sits pinned at the Cover's bottom edge (out of the centred flow), so it never pushes
   the hero off-centre or forces overflow on short screens — it just marks "there's more below" */
.folio-cover .ro-scroll-hint { position: absolute !important; /* beat the (0,4,0) `.folio-ch > :not()...` utility that pins content relative */ left: 50%; bottom: clamp(0.6rem, 2.2vh, 1.4rem); transform: translateX(-50%); margin: 0; }

/* =====================================================================
   PER-CHAPTER ARCHETYPES (stable semantic hooks)
   ===================================================================== */
/* V · Shape of Favourites — THE PLATE: sparse, centred votive object */
.folio-shape { text-align: center; }
.folio-shape .ro-card, .folio-shape .ro-card p.lede, .folio-shape .ro-card p.soft { margin-left: auto; margin-right: auto; }
.folio-ch.folio-shape .folio-eyebrow { margin-left: auto; margin-right: auto; } /* beat the (0,3,0) content left-align */
.folio-shape .ro-radar { max-width: 400px; }
.folio-shape .ro-radar-wrap { margin-top: 1.4rem; }
/* VII · Before You Share — THE COLOPHON: the printer's page, narrow + quiet */
/* PART-D96 (2026-09-15) SYE-2/SYE-18: the colophon card fills the box like every card (was 54ch) and takes the house sizes */
.folio-colophon .ro-card { max-width: var(--ro-measure); }
.folio-colophon .ro-card h3 { font-size: var(--fs-title); }
.folio-colophon .ro-card p.lede, .folio-colophon .ro-card p.soft, .folio-colophon .lean-line { font-size: var(--fs-body); color: var(--fg2); }

/* =====================================================================
   P3 · HOUSE CHARTS — gold = you, wine = the crowd; theme-safe vars only
   ===================================================================== */
/* PART-D96 (2026-09-15) SYE-18/SYE-16/SYE-2: a figure fills the readout box (was 62ch) one block step
   below the copy above it; its caption is var(--fs-label) at a 66ch measure. The PART-D72 W5 900px+
   step for the tag (0.72rem) and caption (0.82rem) is deleted: both are var(--fs-label) at every width. */
.folio-fig { margin: var(--gap-block) 0 0; max-width: none; }
.folio-figcap { font-family: 'DM Sans', sans-serif; font-size: var(--fs-label); font-style: italic; color: var(--fg2); line-height: 1.5; margin-top: var(--space-2); max-width: 66ch; }
.folio-figcap .fk { font-style: normal; letter-spacing: 0.02em; margin-right: 0.4rem; }
.folio-figcap .fk-u { color: var(--gold-text); }   /* PART-D96 SYE-3 (Q8) */
.folio-figcap .fk-c { color: var(--wine2, #9A3D48); }
.fig-svg { display: block; overflow: visible; }
.fig-svg text { font-family: 'DM Sans', system-ui, sans-serif; }   /* PART-D96 (2026-09-15) SITE-9/Q2: was JetBrains Mono */
.fig-svg .db-you, .fig-svg .db-crowd, .fig-svg .ba-marker { transform-box: fill-box; transform-origin: center; }

/* PART-D96 (2026-09-15) SYE-2/C3: chart text below is var(--fs-label), 16 user units (was 9 to 12.5px) */
/* paired bars */
.pb-lab { font-family: 'DM Sans', sans-serif; font-size: var(--fs-label); fill: var(--fg2); text-anchor: end; }
.pb-val { font-size: var(--fs-label); fill: var(--gold-text); dominant-baseline: middle; }   /* PART-D96 SYE-3 (Q8): chart text */
.pb-val-c { fill: var(--wine2, #9A3D48); }
.pb-bar { transform-box: fill-box; transform-origin: left center; }
.pb-user { fill: var(--gold); }
.pb-crowd { fill: var(--wine2, #9A3D48); opacity: 0.85; }
.pb-lab-compact { font-size: var(--fs-label); text-anchor: start; }

/* dumbbell */
.db-rail { stroke: var(--border2); stroke-width: 1.5; }
.db-tick { stroke: var(--border); stroke-width: 1; }
.db-ticklab { font-size: var(--fs-label); fill: var(--fg3); text-anchor: middle; }
.db-link { stroke: var(--gold3); stroke-width: 1.5; stroke-dasharray: 2 3; }
.db-you { fill: var(--gold); }
.db-crowd { fill: var(--wine2, #9A3D48); }
.db-lab { font-size: var(--fs-label); text-anchor: middle; }
.db-lab-you { fill: var(--gold-text); }   /* PART-D96 SYE-3 (Q8): chart text */
.db-lab-crowd { fill: var(--wine2, #9A3D48); }

/* bipolar axis */
.ba-rail { stroke: var(--border2); stroke-width: 1.5; }
.ba-center { stroke: var(--fg3); stroke-width: 1; }
.ba-whisker { stroke: var(--wine2, #9A3D48); stroke-width: 3; stroke-linecap: round; opacity: 0.7; }
.ba-marker { fill: var(--gold); }
.ba-pole { font-size: var(--fs-label); fill: var(--fg3); letter-spacing: var(--ls-label); text-transform: uppercase; }

/* The DATA animates as you scroll into the chart — bars grow to value, markers pop in, the dumbbell
   link + whisker draw. All SCROLL-driven (view() timeline) so it is FREEZE-SAFE: the zero-state lives
   ONLY inside @supports(view()) + no-preference, so a frozen/unsupported/reduced-motion frame renders
   the complete figure, and anything you've scrolled past is fully resolved. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .fig-pb:not(.is-static) .pb-bar {
      transform: scaleX(0); animation: chGrowX cubic-bezier(0.16, 1, 0.3, 1) both;   /* grows fast, settles */
      animation-timeline: view();
      animation-range: cover calc(20% + var(--bi, 0) * 4%) cover calc(50% + var(--bi, 0) * 4%);   /* plays as the chart RISES to centre (was finishing too early, low in the viewport); each row a beat after the one above */
    }
    /* DUMBBELL — the two dots DROP from above and settle onto the rail (Y only; X already holds the
       reading, so a mid-drop never lies about the value). Crowd lands first, YOUR dot a beat later. */
    .fig-db:not(.is-static) .db-crowd {
      transform: translateY(-24px) scale(0.4);
      animation: chDrop cubic-bezier(0.34, 1.3, 0.5, 1) both;
      animation-timeline: view(); animation-range: cover 22% cover 52%;
    }
    .fig-db:not(.is-static) .db-you {
      transform: translateY(-30px) scale(0.4);
      animation: chDrop cubic-bezier(0.34, 1.3, 0.5, 1) both;
      animation-timeline: view(); animation-range: cover 28% cover 60%;
    }
    /* BIPOLAR — the marker GLIDES out from the neutral centre to your lean; overshoot-free ease so a
       mid-scroll park never rests PAST the true reading (a data figure must not lie at rest) */
    .fig-bipolar:not(.is-static) .ba-marker {
      transform: translateX(var(--dx, 0)) scale(0.5);
      animation: chSlideV cubic-bezier(0.16, 1, 0.3, 1) both;
      animation-timeline: view(); animation-range: cover 26% cover 58%;
    }
    .fig-bipolar:not(.is-static) .ba-whisker {
      stroke-dasharray: 520; stroke-dashoffset: 520; animation: chDraw linear both;   /* 520 >= max whisker length (~349) so the error bar never truncates; dasharray now lives INSIDE the gate (unsupported/reduced render the full solid whisker). The db-link keeps its designed dotted 2 3 in EVERY mode — no draw-on, no solid override. */
      animation-timeline: view(); animation-range: cover 22% cover 56%;
    }
  }
}
@keyframes chGrowX { to { transform: scaleX(1); } }
@keyframes chSlideV { to { transform: translateX(0) scale(1); } }
@keyframes chDrop { to { transform: none; } }
@keyframes chDraw { to { stroke-dashoffset: 0; } }

/* Desktop pointer polish — hover lifts a bar/marker with light + glow. Filter ONLY (the entrance
   animation owns `transform`), so it composes cleanly and stays inert on touch / frozen frames. */
@media (hover: hover) and (pointer: fine) {
  .fig-pb .pb-bar, .fig-db .db-you, .fig-db .db-crowd, .fig-bipolar .ba-marker { transition: filter 0.18s ease; }
  .fig-pb .pb-bar:hover { filter: brightness(1.28) saturate(1.15); }
  .fig-db .db-you:hover, .fig-db .db-crowd:hover, .fig-bipolar .ba-marker:hover {
    filter: drop-shadow(0 0 7px var(--gold-glow, rgba(240, 200, 110, 0.55))) brightness(1.12);
  }
}

/* The RADAR blooms open from its centre as you reach it — the quality-profile polygon unfurls and its
   vertices emanate outward. CSS-only (no science edit): the shape is the last <polygon>, the vertices
   the only <circle>s. Freeze-safe — the collapsed base lives ONLY inside @supports(view()) + no-preference,
   so an unsupported / reduced-motion / frozen frame renders the finished profile at full size. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .ro-radar polygon:last-of-type {
      transform-box: view-box; transform-origin: center; transform: scale(0.04);
      animation: radarBloom cubic-bezier(0.34, 1.56, 0.64, 1) both;
      animation-timeline: view(); animation-range: cover 20% cover 54%;
    }
    .ro-radar circle {
      transform-box: view-box; transform-origin: center; transform: scale(0);
      animation: radarBloom cubic-bezier(0.34, 1.56, 0.64, 1) both;
      animation-timeline: view(); animation-range: cover 28% cover 62%;
    }
  }
}
@keyframes radarBloom { to { transform: scale(1); } }

/* PULLS lollipop + TASTE-MAP scatter — the last two native charts, animated CSS-ONLY so science.js
   stays byte-identical. Structural/attribute selectors: the value stem is the only round-capped <line>,
   the taste dots the only fill-opacity circles, the pull heads the only circles WITHOUT it; the radar
   (its own .ro-radar) is excluded so its bloom is untouched. transform-box/origin are inert without a
   transform, so they sit outside the gate; every zero-state lives INSIDE @supports(view()) + no-preference
   → an unsupported / reduced-motion / frozen frame renders every stem, head and dot at full. */
.ro-svg:not(.ro-radar) circle { transform-box: fill-box; transform-origin: center; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .ro-svg:not(.ro-radar) line[stroke-linecap="round"] {                 /* the pull stem DRAWS out from its label — a pen-stroke, distinct from the bars' grow */
      stroke-dasharray: 340; stroke-dashoffset: 340; animation: chDraw linear both;   /* 340 >= max stem length (trackW 330); gated so unsupported/reduced show the full solid stem */
      animation-timeline: view(); animation-range: cover 20% cover 52%;
    }
    .ro-svg:not(.ro-radar) circle:not([fill-opacity]) {                   /* then the lollipop head POPS on the end (springy) as the stem finishes */
      transform: scale(0); animation: plHeadPop cubic-bezier(0.34, 1.56, 0.64, 1) both;
      animation-timeline: view(); animation-range: cover 32% cover 60%;
    }
    /* the taste-map scatter RIPPLES in — dots land in overlapping waves by DOM/rating order (a soft
       ease, no overshoot), a distinct motion from the pull heads' single springy pop */
    .ro-svg:not(.ro-radar) circle[fill-opacity] {
      transform: scale(0); animation: plHeadPop cubic-bezier(0.22, 1, 0.36, 1) both;
      animation-timeline: view(); animation-range: cover 16% cover 46%;
    }
    .ro-svg:not(.ro-radar) circle[fill-opacity]:nth-of-type(4n+1) { animation-range: cover 21% cover 52%; }
    .ro-svg:not(.ro-radar) circle[fill-opacity]:nth-of-type(4n+2) { animation-range: cover 26% cover 58%; }
    .ro-svg:not(.ro-radar) circle[fill-opacity]:nth-of-type(4n+3) { animation-range: cover 31% cover 64%; }
  }
}
@keyframes plHeadPop { to { transform: scale(1); } }

/* =====================================================================
   P3 · THE COVER'S OPENER LINES.
   PART-D75 (2026-09-10) W3 / A13: this block used to open with a PER-ELEMENT
   SCROLL-REVEAL, six qualified .folio-ch:not(.folio-cover) rules arming folioRise
   (and cueSlide on .lean-line) on animation-timeline: view(), so every heading,
   paragraph, cue row, portrait, meaning line and disclosure in every content chapter
   faded from opacity 0 continuously as the reader scrolled. That is the effect on TEXT
   Avery asked to be removed, and it is deleted wholesale: the six arming rules, the
   cueSlide override, and both keyframes.
   WHAT SURVIVES, AND WHY THE PARTITION IS BY QUALIFIED SELECTOR RATHER THAN BY CLASS:
   .ro-portrait appeared in BOTH families. Only the :not(.folio-cover) rule was part of
   the prose reveal; the .folio-cover one below is the cover's own opener and stays
   byte-intact, as do the other two coverRise rules and the coverRise keyframe. Those
   three are TIME-BASED and TRANSFORM-ONLY, never fade to invisible, and were not part
   of the defect. dossierRise, every fig-*SVG chart keyframe, the .pl-bg watermark drift
   and the gold-ink headline sweep are all untouched and live elsewhere in this file.
   NO REDUCED-MOTION NEUTRALISER WAS ORPHANED BY THIS DELETION: the deleted rules lived
   inside @media (prefers-reduced-motion: no-preference) and were never armed under
   reduce; the two neutralisers that cover this region are broad catch-alls
   (* { animation-timeline: none !important } and the .reveal-act.in-view reset) which
   also cover survivors, so both stay.
   ===================================================================== */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* the cover's opener lines rise in on a TIME-BASED reveal, NOT view(): the cover is a sticky,
       above-the-fold curtain the Unwrap dismisses to via scrollTo(0), so a scroll-timeline never
       reaches 100% and the text sticks at ~0.96 opacity. Transform-only → always fully opaque and
       legible even mid-slide (freeze-safe), and it completes on load regardless of scroll. */
    .folio-cover .hero-arch .kicker { animation: coverRise 0.7s 0.05s var(--ease-cinematic, cubic-bezier(0.76, 0, 0.24, 1)) both; }
    .folio-cover .hero-arch .lede { animation: coverRise 0.7s 0.18s var(--ease-cinematic, cubic-bezier(0.76, 0, 0.24, 1)) both; }
    .folio-cover .ro-portrait { animation: coverRise 0.8s 0.32s var(--ease-cinematic, cubic-bezier(0.76, 0, 0.24, 1)) both; }
  }
}
@keyframes coverRise { from { transform: translateY(1.5rem); } to { transform: none; } }

/* The face photographs on "Where you and the crowd parted" (science.js:2064) ship with no width
   constraint, so they render at their natural 512px. On a 375px phone that was clipped by the
   html{overflow-x:clip} parallax guard rather than scaled — the faces were simply cut off. */
.folio-ch .ro-card figure { margin: 0; min-width: 0; }
.folio-ch .ro-card figure img { max-width: 100%; height: auto; display: block; border-radius: 6px; }
/* PART-D96 (2026-09-15) SYE-16: a chart figure or science chart placed in a card sits one block step
   below the copy above it (the margin:0 above stays for face photographs) */
.folio-ch .ro-card > figure.folio-fig, .folio-ch .ro-card > .ro-svg { margin: var(--gap-block) 0 0; }

/* P4 · the copyable EYE-PRINT (Wordle-style glyph row + reading fingerprint) in the share section */
/* PART-D96 (2026-09-15) SYE-2/SYE-15: the share-section helpers below take only the house sizes and DM Sans here; their layout is wave 3's */
.eye-print { text-align: center; margin: 1.3rem auto 0.2rem; max-width: 30rem; }
.eye-print .ep-glyph { font-size: var(--fs-title); letter-spacing: 0.14em; line-height: 1; margin-bottom: 0.55rem; }
.eye-print .ep-id { font-family: 'DM Sans', system-ui, sans-serif; font-size: var(--fs-label); letter-spacing: var(--ls-label); color: var(--gold-text); margin-bottom: 0.95rem; }   /* PART-D96 (2026-09-15) SYE-3: --gold-text, no opacity on text */
:root[data-theme="light"] .eye-print .ep-id { color: var(--fg2); opacity: 1; }   /* --gold2@0.85 on cream is ~2.4:1 (below AA); --fg2 is readable in light */
.eye-print .ep-actions { display: flex; gap: 0.6rem; justify-content: center; flex-wrap: wrap; }

/* P4 · the story-carousel LIGHTBOX (desktop, when multi-file share is unavailable) — each slide saved on its own gestured click */
.carousel-lightbox { position: fixed; inset: 0; z-index: 9999; background: rgba(8, 4, 6, 0.86); display: flex; align-items: center; justify-content: center; padding: 1.5rem; overflow: auto; }
.carousel-lightbox .cl-inner { max-width: 940px; width: 100%; position: relative; text-align: center; }
.carousel-lightbox .cl-close { position: absolute; top: -0.6rem; right: 0; background: none; border: none; color: var(--fg2); font-size: var(--fs-lead); line-height: 1; cursor: pointer; }
.carousel-lightbox .cl-title { color: var(--fg2); font-size: var(--fs-label); margin-bottom: 1rem; }
.carousel-lightbox .cl-strip { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }
.carousel-lightbox .cl-slide { margin: 0; display: flex; flex-direction: column; gap: 0.55rem; width: min(260px, 44vw); }
.carousel-lightbox .cl-slide img { width: 100%; border-radius: 8px; border: 1px solid var(--border2); box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45); }

/* P4 · READING STRENGTH — the funnel's honest module meter (real min_n gates; no invented stats) */
.reading-strength { max-width: 30rem; margin: 1.5rem auto 1.1rem; text-align: left; }
.reading-strength .rs-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin-bottom: 0.5rem; }
.reading-strength .rs-eyebrow { font-family: 'DM Sans', system-ui, sans-serif; font-weight: 600; font-size: var(--fs-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--fg3); }
.reading-strength .rs-count { font-family: 'DM Sans', system-ui, sans-serif; font-size: var(--fs-label); font-variant-numeric: tabular-nums; color: var(--gold-text); }   /* PART-D96 SYE-3 (Q8) */
.reading-strength .rs-bar { height: 4px; border-radius: 3px; background: var(--border2); overflow: hidden; }
.reading-strength .rs-fill { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--wine2, #9A3D48), var(--gold)); }
.reading-strength .rs-locked { list-style: none; margin: 0.9rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.45rem; }
.reading-strength .rs-locked li { font-size: var(--fs-body); line-height: 1.6; color: var(--fg2); padding-left: 1.1rem; position: relative; }
.reading-strength .rs-locked li::before { content: "\25C6"; position: absolute; left: 0; top: 1em; font-size: 0.5rem; color: var(--gold3, var(--gold)); }
.reading-strength .rs-locked strong { color: var(--gold-text); font-weight: 600; }
.reading-strength .rs-done { font-size: var(--fs-body); color: var(--fg2); margin: 0.9rem 0 0; }

/* stub sign-in field — deliberately OUTSIDE any sticky/transformed ancestor (iOS keyboard/focus-scroll) */
.stub-field { max-width: 22rem; margin: 1.2rem auto 0; text-align: left; }
.stub-field label { display: block; font-size: var(--fs-body); font-weight: 600; color: var(--fg2); margin-bottom: 0.32rem; }
.stub-field input { width: 100%; padding: 0.7rem 0.85rem; border-radius: 8px; border: 1px solid var(--border2); background: transparent; color: var(--fg); font-size: var(--fs-body); font-family: inherit; }
.stub-field input:focus { outline: none; border-color: var(--gold3, var(--gold)); }
.stub-field .stub-hint { font-size: var(--fs-label); color: var(--fg3); margin-top: 0.35rem; }

/* LIGHT-THEME contrast: measured on cream --gold2 is 2.92:1 and --fg3 is 2.67:1 — both below AA for this
   text size. --fg2 is 6.09:1 and --fg is 18.3:1, so light mode swaps to those. (Dark mode already passes.)
   The "nothing is sent or stored" hint especially must stay legible — it is the honesty disclaimer. */
:root[data-theme="light"] .reading-strength .rs-count,
:root[data-theme="light"] .reading-strength .rs-eyebrow,
:root[data-theme="light"] .stub-field .stub-hint { color: var(--fg2); }
:root[data-theme="light"] .reading-strength .rs-locked strong { color: var(--fg); }

/* =====================================================================
   P3 · SMOOTH DROPDOWNS — the "Show the detail" / "finer detail" <details> expand
   with a height glide where supported; native-instant (still fully functional) elsewhere.
   ===================================================================== */
@supports (interpolate-size: allow-keywords) {
  .folio-ch { interpolate-size: allow-keywords; }
  .folio-ch details.ro-dd::details-content,
  .folio-ch details.finer-details::details-content {
    height: 0; overflow: clip;
    transition: height 0.42s var(--ease-cinematic), content-visibility 0.42s allow-discrete;
  }
  .folio-ch details.ro-dd[open]::details-content,
  .folio-ch details.finer-details[open]::details-content { height: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .folio-ch details::details-content { transition: none; }
}

/* =====================================================================
   P3 · GOLD-INK READ-ALONG — each content chapter's headline fills with gold,
   left→right, as you scroll into it (the signature move). SCROLL-driven + freeze-safe:
   the text colour is ALWAYS the gradient (gold or fg — both visible), never transparent-
   invisible, and a solid var(--fg) fallback covers engines without background-clip:text.
   ===================================================================== */
@supports ((-webkit-background-clip: text) or (background-clip: text)) and (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .folio-ch:not(.folio-cover) .ro-card h3 {
      color: transparent;
      background: linear-gradient(90deg, var(--gold-text) 50%, var(--fg) 50%) no-repeat;   /* PART-D96 (2026-09-15) SYE-3 (Q8): gold ink is --gold-text (light --gold was about 2:1 on cream) */
      background-size: 200% 100%; background-position: 100% 0;
      -webkit-background-clip: text; background-clip: text;
      animation: inkRead linear both; animation-timeline: view(); animation-range: entry 32% cover 58%;
    }
  }
}
@keyframes inkRead { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* COVER DEPTH rings: removed 2026-09-05. They were the background ornament behind the
   cover's gauge card, and went with it. .pl-mid keeps its own display rules (:126-127); with
   the ring pseudo-elements gone it carries nothing on the cover. */

/* DESKTOP COVER two-column layout: removed 2026-09-05. Its right column WAS the crest, so
   with the gauge card gone the cover is one centred column at every width, as on a phone. */

/* =====================================================================
   PART-D80 (2026-09-10) · THE MERGED FOLIO ARCHETYPE AND THE SPACING PASS
   W1 step 8, W4 and W5. Everything here is presentation only; js/science.js is
   barred from edit and js/overhaul.js moves the rendered nodes, it does not restyle
   them. This block sits LAST in the file on purpose: two of its rules tie on
   specificity with the cover's own rules above, and source order is what decides
   them, which is easier to audit in one place than scattered up the file.
   ===================================================================== */

/* --- III · How Your Eye Reads: THE MERGED PLATE ---------------------------
   The archetype centres the VISUALS ONLY. .folio-shape (:331) centres its whole
   chapter with text-align, which is right for a chapter that is one plate and a
   caption; this chapter carries a lede, a leaning list and a disclosure of prose,
   and centring those would fight the reading column. So the figures take auto side
   margins and every word stays where the folio's own reading column puts it.
   SPECIFICITY, NOT STYLE: these read .folio-merged .ro-card figure... rather than the
   shorter .folio-merged .folio-fig because .folio-ch .ro-card figure { margin: 0 } (:534)
   is (0,2,1) and out-ranks a two-class rule, so the shorter form silently does nothing. */
.folio-merged .ro-card figure.folio-fig { margin-left: 0; margin-right: 0; }   /* PART-D96 (2026-09-15) SYE-18/Q9: figures fill the box; only the Folio I plate is centred */
/* mirrors the .folio-shape pair at :334-335, so the relocated radar keeps the size and
   the breathing room it had in the chapter it came from */
.folio-merged .ro-radar { max-width: 400px; margin-top: 0; }   /* margin-top 0: the wrap owns the gap */
.folio-merged .ro-radar-wrap { margin-top: var(--gap-block); }
/* THE RADAR'S OWN HOST in the merged card, scoped to the merged card itself rather than to the
   chapter. When buildLeanFolio declines the merge, its minimum-viable guard leaves the unmerged
   originals in this same chapter under the same folio-merged class, and they carry their own
   sizing from the .folio-shape pair; .ro-merged is written only by a merge that actually
   happened, so this block governs exactly the merged state and no other.
   PART-D86 (2026-09-11) W1 retitled this comment. It read "THE CONSTELLATION HOST" and explained
   the block as the overlay's positioning context, which is no longer true of a single line of it. */
.folio-merged .ro-merged .ro-radar-wrap {
  /* THE CAP AND THE CENTRING ARE THE RADAR'S OWN, AND THEY STILL EARN THEIR PLACE. The wrap IS
     the radar's rendered box. min(400px, 74vw) holds it to the house 400px cap on a desktop and
     to 74 per cent of the viewport on a phone, inside the page gutters, where
     html/body{overflow-x:clip} would otherwise cut a wider box off; the two auto margins centre
     it in the card. position:relative stays because the radar's own bloom rules and any future
     in-wrap layer resolve against this box.
     PART-D86 (2026-09-11) W1 rewrote this comment: it justified the cap by the deleted overlay's
     126.667 per cent width, a reason that no longer exists, and leaving it would have made the
     surviving declarations look like leftovers of the ring rather than the radar's own sizing. */
  /* PART-D96 (2026-09-15) SYE-18/Q9: the radar is a narrower figure, so it sits on the box's left edge
     (was auto side margins); the figure it lives in owns the block gap above it. */
  position: relative; width: 100%; max-width: min(400px, 74vw); margin-top: 0; margin-left: 0; margin-right: auto;
  /* PART-D86 (2026-09-11) W1, ledger item 5a as amended by disposition A1 of the same date:
     padding: 2rem 0 is DELETED and nothing else in this block is touched. It existed for one
     reason only, to RESERVE THE RING: the constellation overlay was out of flow and reached 31px
     beyond the radar box at the 400px cap, and this padding put that overhang inside the wrap's
     own box so the ordinary card rhythm spaced it correctly at every width. With the ring struck
     there is nothing left to reserve room for.
     THE FOUR DECLARATIONS ABOVE SURVIVE ON PURPOSE. position, width, max-width and the two auto
     margins are what size and centre the RADAR ITSELF inside the merged card, and they happen to
     share this one selector block with the dot-only padding. Avery's words strike the dots, not
     the hexagon, and item 5b's own wording ("must be seperated FROM IT") confirms the radar
     stays. Deleting this block wholesale would drop the merged-card radar back to the generic
     .folio-merged .ro-radar-wrap { margin-top: 1.4rem; } rule at :647 and lose its width cap and
     its centring silently, which is exactly the regression A1 was raised to prevent; the survival
     check in tools/d86-controls.js captures these five computed values before and after and
     asserts every one of them unchanged while the padding alone moved. */
}

/* --- PART-D86 (2026-09-11) W1 · THE DOT CONSTELLATION RULES ARE DELETED -----
   Ledger item 5a as amended by disposition A1 names the deletion precisely, and this is it in
   full: the .ro-constell block and its .cn-dot fill rule, the light-theme :root[data-theme]
   colour override, the two .ro-constell-fig rules (the figure's margin-bottom and the
   figcaption's own margin, centring and measure), the @supports(view()) + no-preference gate
   holding the collapsed entrance state, and the cnDotIn keyframe. Nothing else in the radar-wrap
   cascade is touched: see the block above, which keeps every layout declaration it had.
   WHAT THE BREADTH CAPTION LANDS ON NOW. Its two deleted rules were part of the same
   overhang tuning (the comment they shared read "the reserved overhang, top and bottom"), so
   with the ring gone the caption returns to the file's own .folio-figcap default, the same
   rule every other figure caption in the folio already uses. The figure keeps a class,
   renamed ro-shape-fig in js/overhaul.js, but no rule targets it: it exists to tell the radar
   figure from the dumbbell figure in the rendered evidence, and the old name could not stay
   because item 5a's acceptance check greps for the substring ro-constell as proof the layer
   is gone. */

/* --- PART-D91 (2026-09-12) W1, THE SCALE CARD IN FOLIO II ------------------
   PART-D86's h4 separator inside the merged Folio III card is superseded. The dumbbell now
   belongs to its own sibling card in Folio II, where this narrow rule restores the ordinary
   figure rhythm and centres the chart against the card without touching the radar rules. */
.folio-room .ro-scale-card figure.folio-fig { margin: var(--gap-block) 0 0; }
/* PART-D96 (2026-09-15) SYE-18/Q9: the scale chart fills the box (was centred), and the Folio II face deck,
   a narrower figure, sits on the box's left edge one block step down (styles/demo.css centres it) */
.folio-ch .dv-deck { margin: var(--gap-block) auto 0 0; }

/* --- W1 step 8 · the disclosure sub-label ---------------------------------
   A quiet sub-label sized BETWEEN .dd-h (0.58rem, mono, uppercase, --fg3) and .dd-k,
   so the four cards' number lists read as three named groups under one "Your numbers"
   heading rather than as one undifferentiated run. */
.ro-dd .dd-sub {
  font-family: 'DM Sans', system-ui, sans-serif; font-weight: 600; font-size: var(--fs-label);   /* PART-D96 (2026-09-15) SYE-15/Q2 */
  letter-spacing: normal; text-transform: none; color: var(--fg2);   /* PART-D96 (2026-09-15) SYE-22 (C9): no uppercase */
  margin: 0.85rem 0 0.3rem;
}

/* =====================================================================
   W5 · THE SPACING PASS (Avery's four requirements of 2026-09-10)
   (a) is the .folio-ch padding at :63, edited in place there.
   ===================================================================== */

/* (a, continued) the intra-chapter card rhythm, tightened in the same proportion as the
   chapter padding above it (roughly three quarters of D75's values), so the chapters that
   still hold more than one card keep their rhythm rather than reading loose beside the
   newly tight chapter gaps.
   THE COVER IS EXCLUDED FROM BOTH, and that exclusion is load-bearing rather than tidy:
   .folio-cover .ro-portrait (:321) pins margin-bottom: 0 at the same specificity a bare
   .folio-ch .ro-card rule would carry, so an unscoped rule here would silently reopen the
   gap the cover's one-screen fit closed. */
/* PART-D96 (2026-09-15) SYE-16: both resolve to var(--ro-gap), the same step as the card rules above */
.folio-ch:not(.folio-cover) .ro-card { margin-bottom: var(--ro-gap); }
.folio-ch:not(.folio-cover) .ro-card + .ro-card { padding-top: var(--ro-gap); }
/* PART-D96 (2026-09-15) SYE-16 (Q26): a card followed by a card adds no margin, so the gap is the hairline plus one var(--ro-gap) */
.folio-ch:not(.folio-cover) .ro-card:has(+ .ro-card) { margin-bottom: 0; }

/* (b) DIFFERENTIATED OPEN-STATE SPACING. "when the show more details opens the spacing
   should not be the same amount as when it is closed". Built WITH the existing
   ::details-content height glide at :577-586, not against it: nothing here touches height,
   overflow or the transition, and no new reveal motion is added. Two levers, both spacing:
   the block's own separation from the copy above changes on open, and the first revealed
   child gets a rhythm of its own that the closed pill never shows.
   The cover is excluded from the first lever so its one-screen COVER FIT budget (:298-325)
   is not moved by a state it does not use at rest. */
/* PART-D96 (2026-09-15) SYE-16 (Q26) supersedes (b): the drawer is a block like any other, var(--gap-block)
   above it open or closed, and its first revealed child sits one block step below the pill. */
.folio-ch .ro-dd { margin-top: var(--gap-block); }
.folio-ch .ro-dd[open] > summary + * { margin-top: var(--gap-block); }

/* (c) FOLIO I'S OWN PRESENCE. "the folio 1 is very hard for it to be seen without it being
   consumed by the previous sections". The cover follows the generated-faces card and the
   recovery panel with no gap of its own, so it reads as a continuation of them rather than
   as the opening plate of the reading.
   THIS IS THE ONE DELIBERATE EXCEPTION TO (a) AND IT IS NOT A LEFTOVER: everything else in
   this pass takes space away, and this single rule gives space back, at the one seam where
   the folio has to visibly begin. The panel's own pinned margin (styles/demo.css :909, the
   D76 W7 value that tools/d76-controls.js i4 pins) is deliberately left untouched; the
   separation is taken on the folio side, which is the side that needed it. */
/* PART-D96 (2026-09-15) SYE-17: held at the pre-wave value until SYE-14's call-PDF check settles the seam below 'Copy code' */
.folio-ch.folio-cover { margin-top: clamp(3rem, 8vh, 5.5rem); }

/* (d) THE CENTRED CONTROL. "i nedd the show more details to be centered".
   The summary BOX is centred, never the disclosure's prose. A bare text-align: center on
   .ro-dd would inherit into every revealed .dd-h, .dd-sub, .dd-p and .dd-nums the moment it
   opens, centre-aligning explanatory prose and undoing (b)'s own work. So the summary is
   made a block of its own width and centred by auto side margins instead, and no inherited
   alignment reaches anything inside the disclosure.
   MARGIN LONGHANDS, NOT THE SHORTHAND: .ro-dd[open] summary (styles/demo.css :436) sets
   margin-bottom at the same specificity as this rule, and a shorthand here would silently
   drop it in the open state. */
.folio-ch .ro-dd summary { display: block; width: fit-content; margin-left: auto; margin-right: auto; }

/* =====================================================================
   PART-D81 (2026-09-11) · THE BACKGROUNDS SECTION
   Chapter 5's rails chart, its order toggle and the confound sub-section.

   APPENDED, never edited into anything already here: PART-D80 shipped the merged folio
   and its spacing pass in the rules above, and every selector below is new and prefixed
   .bg-, so no existing rule changes meaning.

   EVERY COLOUR IS AN EXISTING CUSTOM PROPERTY, which is what makes the chart correct in
   both themes for nothing: gold is the rater, wine is where this panel put the same faces,
   exactly as .pb-user / .pb-crowd and .db-you / .db-crowd already read.

   NO SCROLL-LINKED MOTION ANYWHERE IN THIS ROUND. The house charts above animate on
   animation-timeline: view(), and the readout-chrome research named that mechanism applied
   to opacity as the likely cause of the "progressively dimmer" complaint elsewhere on this
   page. This section takes one short transform-and-opacity rise on mount instead, inside
   the no-preference gate, and nothing at all under reduced motion.
   ===================================================================== */

/* -- the rails ------------------------------------------------------------------------ */
.bg-chart { margin: var(--gap-block) 0 0; }   /* PART-D96 (2026-09-15) SYE-16: a block step (was 1.5rem 0 0.2rem) */
.bg-fig { margin-top: 0.6rem; }
.bg-grid { stroke: var(--border); stroke-width: 1; }
.bg-railline { stroke: var(--border2); stroke-width: 1.25; }
.bg-axisline { stroke: var(--border2); stroke-width: 1.5; }
.bg-ticklab { font-size: var(--fs-label); fill: var(--fg3); text-anchor: middle; }
.bg-axislab { font-size: var(--fs-label); fill: var(--fg3); text-anchor: end; letter-spacing: var(--ls-label); text-transform: uppercase; }
/* DM Sans for the background names, the same override .pb-lab makes against the .fig-svg
   monospace default: these are words a reader reads, not figures they scan. */
.bg-lab { font-family: 'DM Sans', sans-serif; font-size: var(--fs-label); fill: var(--fg); text-anchor: end; }
.bg-n { font-size: var(--fs-label); fill: var(--fg3); text-anchor: end; }
/* THE NON-RANKING CAPTION, once per rail. It is a safeguard rather than a decoration, so it
   takes --fg2 and not the fainter --fg3 the tick labels use: it has to survive a crop of one
   row, in either theme, at whatever size that crop is looked at. */
.bg-cap { font-size: var(--fs-label); fill: var(--fg2); text-anchor: end; letter-spacing: 0.1em; }
.bg-dot { fill: var(--gold); opacity: 0.62; }
.bg-mean { stroke: var(--gold); stroke-width: 2.5; stroke-linecap: round; }
.bg-crowd-tick { stroke: var(--wine2, #9A3D48); stroke-width: 2; stroke-linecap: round; }
/* The band's five stop levels, full at the mean and fading to almost nothing at either
   edge, so two rails the sort has placed together read as overlapping weather rather than
   as two marks one of which is in front. */
.bg-stop-in { stop-color: var(--gold); stop-opacity: 0.44; }
.bg-stop-mid { stop-color: var(--gold); stop-opacity: 0.27; }
.bg-stop-out { stop-color: var(--gold); stop-opacity: 0.12; }

/* -- the order toggle and the sentence that has to sit beside it ---------------------- */
.bg-sortbar { margin-top: var(--gap-block); display: flex; flex-direction: column; align-items: flex-start; gap: 0.75rem; }
.bg-sortnote { font-family: 'DM Sans', sans-serif; font-size: var(--fs-body); line-height: 1.6; color: var(--fg2); margin: 0; max-width: 66ch; }

/* -- layer 3, the confound sub-section ------------------------------------------------ */
.bg-confound { margin: var(--gap-block) 0 0; padding-left: 0.9rem; border-left: 2px solid var(--gold3); max-width: 66ch; }
.bg-confound-eyebrow { font-family: 'DM Sans', system-ui, sans-serif; font-weight: 600; font-size: var(--fs-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--gold-text); margin-bottom: 0.65rem; }   /* PART-D96 SYE-3 (Q8) */
.bg-synth { font-size: var(--fs-body); line-height: 1.6; color: var(--fg); margin: 0 0 0.75rem; }
.bg-confound-caveat { font-size: var(--fs-body); line-height: 1.6; color: var(--fg2); margin: 0; }
/* PART-D96 (2026-09-15) SITE-1/SYE-2: the 900px+ step (eyebrow 0.72rem, sort note 0.88rem) is deleted; both are tokens at every width. */

/* -- narrow screens ------------------------------------------------------------------- */
/* The chart scales with its viewBox, so on a phone every label scaled down with it: the
   row label to about 8px, the n to about 6.5px and the non-ranking caption to about 5.9px,
   which is not a readable size. That caption is a SAFEGUARD, and a phone is the device most
   screenshots are taken on, so letting it shrink out of legibility is the one place this
   chart could not be allowed to degrade. Below the breakpoint the figure holds the chart at
   its authored width, where the type is the size it was drawn to be, and scrolls it inside
   its own box instead. The page itself never scrolls sideways: the overflow is contained
   here, and demo.css already clips the body axis. */
@media (max-width: 700px) {
  .bg-fig { overflow-x: auto; overscroll-behavior-x: contain; }
  .bg-fig .bg-rails { min-width: 520px; }
  /* Shown, not left to the browser's hide-at-rest default: a scroll affordance nobody
     can see is close to no affordance at all. An edge fade was the other candidate and
     was rejected outright, because the caption this chart must not lose sits at the
     right-hand end of every rail and a fade would dim the one thing that has to stay
     readable. */
  .bg-fig { scrollbar-width: thin; scrollbar-color: var(--gold3) transparent; }
  .bg-fig::-webkit-scrollbar { height: 6px; }
  .bg-fig::-webkit-scrollbar-track { background: transparent; }
  .bg-fig::-webkit-scrollbar-thumb { background: var(--gold3); border-radius: 3px; }
}
/* The focus ring is the estate's own, the one .epf-toggle already uses. */
.bg-fig:focus-visible { outline: 2px solid var(--gold2); outline-offset: 3px; }

/* PART-D92, 2026-09-12. Folio V follows the established folio typography and
   spacing while keeping its figures broad enough for seven stable score rows. */
.folio-ch.folio-finer.reveal-act.in-view {
  animation: none !important;
  opacity: 1 !important;
  transform: none !important;
}
#stage-readout .folio-finer > .folio-real-title {
  margin-top: 0;
  font-size: var(--fs-label);   /* PART-D96 (2026-09-15) SYE-15: the same label as every chapter eyebrow */
  font-weight: 600;
  line-height: inherit;
  text-align: left;
}
#stage-readout .folio-finer > .folio-real-title::before { content: none; }
.folio-finer > .folio-park-inner { width: 100%; max-width: var(--ro-measure); margin-left: auto; margin-right: auto; }
.finer-chapter-intro {
  color: var(--fg2);
  font-size: var(--fs-body);
  line-height: 1.6;
  max-width: 66ch;
  margin: 0 0 var(--gap-block);
}
/* PART-D96 (2026-09-15) SYE-16: the mode control sits one card step above the first family card (demo.css had 2.6rem) */
.folio-finer .finer-toolbar { margin-bottom: var(--ro-gap); }
.folio-finer .finer-family-card {
  width: 100%;
  max-width: 100%;   /* PART-D96 (2026-09-15) SYE-18: fills the readout box (was 74rem) */
  margin: 0 0 var(--ro-gap);
}
.folio-finer .finer-family-card + .finer-family-card {
  border-top: 1px solid var(--border2) !important;
  padding-top: var(--ro-gap);
}
.folio-finer .finer-family-card .ro-head { max-width: 66ch; }
.folio-finer .finer-family-card p.lede { max-width: 66ch; }
/* PART-D96 (2026-09-15) SYE-16: figure and drawer are block steps, the same open or closed */
.folio-finer .finer-figure { margin-top: var(--gap-block); }
.folio-finer .finer-detail { margin-top: var(--gap-block); }
.folio-finer .finer-detail[open] > summary + * { margin-top: var(--gap-block); }
.folio-finer .finer-detail summary {
  display: block;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
}
@supports selector(details::details-content) {
  .folio-finer details.finer-detail::details-content {
    display: block;
    height: 0;
    overflow: clip;
  }
  .folio-finer details.finer-detail[open]::details-content { height: auto; }
}
/* PART-D96 (2026-09-15) SYE-16: the 480px 3.2rem card margin is deleted; var(--ro-gap) already steps down below 900px */

/* -- the one-shot reveal -------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .bg-chart { animation: bgRise 0.66s var(--ease-heavy) both; }
}
@keyframes bgRise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
/* PART-D93, 2026-09-12. Background distributions, native labels and a separate
   mean lane. Counts share one vertical scale across all background groups. */
.folio-ch .bg-fig { overflow: visible; }
.bg-fig .bg-distributions { width: 100%; min-width: 0; }
/* PART-D96 (2026-09-15) SYE-2/SYE-16: the native chart's text is var(--fs-label) (was .8 to .9rem) and its rows use var(--gap-block) */
.bg-distributions .bg-rail { display: block; padding: var(--gap-block) 0; border-top: 1px solid var(--border2); }
.bg-group-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.bg-group-heading h4 { font: 500 var(--fs-lead)/1.2 'DM Sans',system-ui,sans-serif; color: var(--fg); margin: 0; }
.bg-group-heading > span { color: var(--fg2); font-size: var(--fs-label); }
.bg-distribution-label { color: var(--fg2); font-size: var(--fs-label); margin: .7rem 0 .9rem; }
.bg-counts { display: grid; grid-template-columns: repeat(7,minmax(0,1fr)); gap: .65rem; }
.bg-count-column { text-align: center; min-width: 0; }
.bg-count-number { display: block; color: var(--fg); font-size: var(--fs-label); font-variant-numeric: tabular-nums; }
.bg-count-space { height: 52px; display: flex; align-items: end; justify-content: center; margin-top: .3rem; border-bottom: 1px solid var(--border3); }
.bg-count-bar { width: 100%; max-width: 42px; display: block; background: var(--gold2); border-radius: 3px 3px 0 0; }
.bg-count-score { display: block; padding-top: .45rem; font-size: var(--fs-label); color: var(--fg2); }
.bg-average-lane { position: relative; height: 20px; margin: 1.25rem calc(100%/14) .6rem; }
.bg-average-rule { position: absolute; top: 9px; width: 100%; border-top: 1px solid var(--border3); }
.bg-average-you { position: absolute; top: 3px; width: 12px; height: 12px; border-radius: 50%; background: var(--gold2); transform: translateX(-50%); }
.bg-average-crowd { position: absolute; top: 0; height: 19px; border-left: 3px solid var(--wine2); transform: translateX(-50%); }
.bg-average-labels { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .45rem 1rem; font-size: var(--fs-label); line-height: 1.6; }
.bg-exact-scores { width: 100%; font-size: var(--fs-label); text-align: left; border-collapse: collapse; margin: 1rem 0; }
.bg-exact-scores th, .bg-exact-scores td { padding: .35rem; border-bottom: 1px solid var(--border2); }
.bg-chart:has(.bg-distributions) { animation: none; }
.folio-finer .finer-illustrated { padding: 0; }
@media (max-width:480px) {
  .bg-counts { gap: .35rem; }
  .bg-average-labels { display: grid; }
}
/* PART-D93, 2026-09-12. Native scale labels and distinct overlapping markers. */
.scale-comparison { margin: 0 .7rem; }   /* PART-D96 (2026-09-15) SYE-16: its figure owns the block gap (was 2rem above and below) */
.scale-labels { display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem 1rem; font-size: var(--fs-label); }
.scale-native-rail { position: relative; height: 2px; background: var(--border3); margin: 1.7rem 0 1rem; }
.scale-native-link { position: absolute; border-top: 2px dotted var(--gold3); }
.scale-native-you { position: absolute; width: 13px; height: 13px; border-radius: 50%; top: -5.5px; background: var(--gold2); transform: translateX(-50%); }
.scale-native-crowd { position: absolute; height: 25px; border-left: 3px solid var(--wine2); top: -11.5px; transform: translateX(-50%); }
.scale-native-ticks { display: flex; justify-content: space-between; font-size: var(--fs-label); color: var(--fg2); margin: 0 -.25em; }
@media (min-width:800px) {
  .bg-distributions { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 0 2rem; }
}
/* PART-D93, 2026-09-12. Shape as well as colour identifies each average. */
.bg-average-labels .fk-u, .scale-labels .fk-u { color: var(--gold-text); }
.bg-average-labels .fk-c, .scale-labels .fk-c { color: var(--wine2); }
.bg-average-labels .fk::before, .scale-labels .fk::before { content: ''; display: inline-block; margin-right: .4em; vertical-align: middle; }
.bg-average-labels .fk-u::before, .scale-labels .fk-u::before { width: 7px; height: 7px; background: currentColor; border-radius: 50%; }
.bg-average-labels .fk-c::before, .scale-labels .fk-c::before { height: 12px; border-left: 2px solid currentColor; }
/* PART-D93, 2026-09-12. Accessible ordinary labels and essential data marks. */
.bg-count-bar, .bg-average-you, .scale-native-you { background: var(--d93-gold); }
.bg-average-crowd, .scale-native-crowd { border-color: var(--d93-crowd); }
.bg-average-labels .fk-u, .scale-labels .fk-u { color: var(--gold-text); }   /* PART-D96 (2026-09-15) SYE-3 (Q8): key text is --gold-text; --d93-gold stays on the marks */
.bg-average-labels .fk-c, .scale-labels .fk-c { color: var(--d93-crowd); }

/* PART-D94, 2026-09-12. Keep the original Cormorant / DM Sans / mono hierarchy.
   The preview's fallback-font defect is repaired in its CSP, not by changing families. */
/* PART-D96 (2026-09-15) SYE-18/Q9: the dial block is a narrower figure, so it and its lines sit on the box's
   left edge (was centred); its figure owns the block gap above it. The question takes var(--fs-body) (SYE-2) and,
   like .bg-group-heading h4, DM Sans (SYE-15/Q2 supersedes the D94 family note above). */
.consensus-curved { max-width: 38rem; margin: 0; }
.consensus-question { font: 400 var(--fs-body)/1.5 'DM Sans', system-ui, sans-serif; text-align: left; color: var(--fg); }
.consensus-dial { width: 100%; max-width: 380px; height: auto; display: block; margin: var(--gap-block) 0 0; overflow: visible; }
.consensus-arc { fill: none; stroke: var(--border3); stroke-width: 3; }
.consensus-centre { stroke: var(--fg2); stroke-width: 1; }
.consensus-dot { fill: var(--gold2); stroke: var(--bg); stroke-width: 3; }
.consensus-curved .consensus-directions { margin: -.5rem 0 0; max-width: 380px; gap: 1rem; }
.consensus-curved .consensus-value strong { font-weight: 400; margin-left: 0; }
.consensus-curved .consensus-zero-note { line-height: 1.6; }
.consensus-curved .consensus-value, .consensus-curved .consensus-zero-note { text-align: left; }
.folio-background-eye { position: absolute; width: min(90%,860px); height: auto; top: 50%; left: 50%; transform: translate(-50%,-50%); opacity: .16; pointer-events: none; }
.folio-background-eye * { animation: none !important; stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
.folio-cover .pl-bg:has(.folio-background-eye) .folio-watermark { display: none; }
:root[data-theme="light"] .folio-background-eye { opacity: .2; }
.ro-rail-tick:focus-visible { outline: 2px solid var(--gold2); outline-offset: 5px; }
.story-dialog { width: min(94vw,760px); max-height: 94dvh; box-sizing: border-box; padding: clamp(1rem,3vw,2rem); background: var(--bg); color: var(--fg); border: 1px solid var(--border3); border-radius: 16px; overflow: auto; font-family: 'DM Sans', sans-serif; }
.story-dialog::backdrop { background: var(--bg); opacity: .85; }
.story-dialog-head { display: flex; justify-content: space-between; align-items: start; gap: 1rem; }
.story-dialog-head h2 { margin: 0; font: 400 var(--fs-h2)/1.1 'Cormorant Garamond', Georgia, serif; color: var(--gold-text); }   /* PART-D96 SYE-3 (Q8) */
.story-dialog button { min-height: 44px; font: inherit; cursor: pointer; }
.story-dialog-head button, .story-navigation button { background: transparent; color: var(--fg); border: 1px solid var(--border3); border-radius: 22px; padding: .5rem .9rem; }
.story-dialog button:focus-visible { outline: 2px solid var(--gold2); outline-offset: 3px; }
.story-explanation, [data-story-status] { font-size: var(--fs-body); line-height: 1.6; color: var(--fg2); }
.story-view[hidden] { display: none; }
.story-view > img { display: block; width: 100%; max-width: 440px; height: auto; aspect-ratio: 9/16; margin: 1rem auto; border: 1px solid var(--border3); }
.story-navigation { display: flex; justify-content: space-between; align-items: center; gap: .8rem; max-width: 440px; margin: 1rem auto; }
.story-navigation button:disabled { opacity: 1; color: var(--fg3); border-color: var(--fg4); cursor: default; }   /* PART-D96 (2026-09-15) SYE-3: no opacity on text */
.story-actions { display: flex; justify-content: center; gap: .7rem; flex-wrap: wrap; }
@media print { .story-dialog { max-height: none; border: 0; position: absolute; inset: 0; } .story-dialog-head, .story-explanation, [data-story-status], .story-navigation, .story-actions { display: none; } .story-view > img { max-width: none; width: 100%; } }

/* PART-D94, 2026-09-12. Anchor the eye to the cover content itself. Reduced-motion
   styles unstick the chapter, so its old absolute depth tier can span the whole dossier. */
.folio-cover-inner > .folio-background-eye { z-index: -1; width: min(110%,860px); }

/* PART-D94, 2026-09-12. Match the existing light-theme native marker contrast. */
:root[data-theme="light"] .consensus-dot { fill: var(--gold3); }

/* PART-D94, 2026-09-12. Consistent Folio II introductions, including the scale card.
   Keep the shared house type; the isolated drop cap was splitting the visual rhythm. */
.folio-ch.folio-room:not(.folio-cover) .folio-eyebrow + .ro-card > p.lede:first-of-type::first-letter {
  font: inherit; color: inherit; float: none; padding: 0; text-shadow: none;
}
/* PART-D94, 2026-09-12. Extend the existing chart entrance language to native
   comparisons, background distributions and finer-detail groups. Only decorative
   transforms change; labels and the final data positions remain unchanged. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .folio-ch .consensus-dot {
      transform-box: fill-box; transform-origin: center;
      animation: d94MarkSettle cubic-bezier(.16,1,.3,1) both;
      animation-timeline: view(); animation-range: entry 15% cover 48%;
    }
    .folio-ch .scale-native-you, .folio-ch .scale-native-crowd,
    .folio-ch .bg-average-you, .folio-ch .bg-average-crowd {
      animation: d94NativeSettle cubic-bezier(.16,1,.3,1) both;
      animation-timeline: view(); animation-range: entry 15% cover 48%;
    }
    .folio-ch .bg-count-bar {
      transform-origin: center bottom;
      animation: d94BarGrow cubic-bezier(.16,1,.3,1) both;
      animation-timeline: view(); animation-range: entry 10% cover 48%;
    }
    .folio-finer .finer-group > svg, .folio-finer .finer-group .finer-art {
      animation: d94IllustrationSettle cubic-bezier(.16,1,.3,1) both;
      animation-timeline: view(); animation-range: entry 10% cover 48%;
    }
  }
}
@keyframes d94MarkSettle { from { transform: translateY(-18px) scale(.4); } to { transform: none; } }
@keyframes d94NativeSettle { from { transform: translate(-50%,-18px) scale(.4); } to { transform: translateX(-50%); } }
@keyframes d94BarGrow { from { transform: scaleY(.04); } to { transform: scaleY(1); } }
@keyframes d94IllustrationSettle { from { translate: 0 18px; scale: .92; } to { translate: 0 0; scale: 1; } }
