/* ============================================================
   RHODE READER  —  reader.css   (2026-07-05, NEW file, additive)
   ------------------------------------------------------------
   The whole reading + browsing experience rendered "the Rhode way",
   grounded 1:1 in the Alan-approved reference
   (scratchpad/rhode-reader.html).

   THE SYSTEM (frozen):
   - ONE cool-putty ground everywhere. Text, chrome and photography
     all sit directly on --reader-ground. No framed cards, no dark
     glass INSIDE the reading column.
   - BLEND type: heavy LOWERCASE grotesque for big display; Didot for
     editorial accents; Avenir for prose; mono for tiny labels/fine
     print. Extreme scale contrast is the personality.
   - Frameless photography: product/texture floats on the ground with
     only a soft drop-shadow, OR runs full-bleed edge-to-edge.
   - The navy CLAIM block: one saturated big-number moment amid the calm.
   - The FLOP component: a segmented control that seamlessly swaps the
     body beneath it in place (crossfade + height ease) — the three
     DEPTH TIERS on every reader card.

   LOAD ORDER (documented for the build agents):
     tokens.css  →  editorial.css  →  glass.css  →  reader.css
   reader.css must load LAST so its reader-idiom overrides win the
   cascade over the shared editorial/glass rules it intentionally
   re-grounds. Exact <link> tag is in the delivery notes.

   THEME: Rhode-light is the DEFAULT reader look. Dark theme is a
   navy-ground variant that still reads Rhode (tokens in tokens.css).
   Both AA. Frameless surfaces carry ZERO backdrop-filter, so the
   ≤3-backdrop-filter-per-viewport budget (owned by glass.css) is
   untouched by this file.

   CONTRACT: every value reads var(--x, default); no existing class,
   token or route is renamed. All new class names are prefixed .r-
   (reader) or .flop- / .ed- as noted, so nothing collides with the
   Studio's shared classes.
   ============================================================ */


/* ============================================================
   1. THE READER SHELL  —  the one putty ground
   ------------------------------------------------------------
   .reader is the scroll container. It re-points the LOCAL --ground /
   --ink / --line to the reader-putty tokens on its OWN subtree, so
   every shared class inside it (.rt-spec, .quiz-choice, .rt-callout…)
   inherits the putty ground for free — no per-class edits needed. The
   page's global --ground / --ink are untouched OUTSIDE .reader.
   ============================================================ */
.reader {
  /* re-ground the subtree (local override; global tokens untouched) */
  --ground: var(--reader-ground, #E7E4DD);
  --ground-alt: var(--reader-ground-2, #F1EFEA);
  --ink: var(--reader-ink, #23211E);
  --ink-secondary: var(--reader-ink-soft, #6E6A63);
  --line: var(--reader-line, rgba(35, 33, 30, .14));

  background: var(--reader-ground, #E7E4DD);
  color: var(--reader-ink, #23211E);
  font-family: var(--font-body);
  font-size: 18px;                 /* reference reading size */
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;              /* full-bleed bands never scroll the body */
}

/* The 620px reading measure — the reference column. Distinct from the
   66ch --rt-measure used by richtext; this keeps giant lowercase display
   from over-running. Consumed as min(measure,100%) so phones win. */
.r-col {
  max-width: min(var(--reader-measure, 620px), 100%);
  margin-inline: auto;
  padding-inline: 26px;            /* reference gutter */
}


/* ============================================================
   2. READER CHROME  —  the bare top bar + slim read-progress
   ------------------------------------------------------------
   Rhode's chrome is nearly invisible: a hairline-bottomed sticky bar
   on the SAME ground (a whisper of blur is the only glass in the
   reader, well under budget). .r-progress is an optional 2px fill.
   ============================================================ */
.r-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: 1.1rem 26px;
  position: sticky;
  top: 0;
  z-index: 20;
  font-family: var(--font-grotesque);
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .02em;
  /* the only translucency in the reader — a bare tinted ground, not a card */
  background: color-mix(in srgb, var(--reader-ground, #E7E4DD) 88%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
}
.r-topbar .r-back {
  color: var(--reader-ink, #23211E);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-block: .25rem;
  gap: .5rem;
}
.r-topbar .r-meta {                /* "read · 4 min" — mono, quiet */
  color: var(--reader-ink-soft, #6E6A63);
  font-family: var(--font-mono);
  font-size: .72rem;
}

/* Slim read-progress bar — a 2px fill JS sizes to scroll depth. Sits
   directly under the top bar; no card, clay metal fill. */
.r-progress {
  position: sticky;
  top: 0;
  z-index: 21;
  height: 2px;
  background: transparent;
  pointer-events: none;
}
.r-progress > i {                  /* the filled portion (JS sets width) */
  display: block;
  height: 100%;
  width: var(--r-progress, 0%);
  background: var(--reader-clay, #A9673F);
  transition: width var(--dur-micro, .3s) var(--ease-out, ease);
}
@media (prefers-reduced-motion: reduce) {
  .r-progress > i { transition: none; }
}


/* ============================================================
   3. READER TYPE  —  the BLEND (grotesque display / prose / accents)
   ============================================================ */

/* eyebrow — heavy grotesque micro-caps in clay (the reader's signature) */
.r-eyebrow {
  font-family: var(--font-grotesque);
  font-weight: 700;
  font-size: .7rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--reader-clay, #A9673F);
  margin: 0 0 .5em;
}
/* label — quieter grotesque micro-caps for spec/table/tip labels */
.r-label {
  font-family: var(--font-grotesque);
  font-weight: 700;
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--reader-ink-soft, #6E6A63);
}

/* the hero: ENORMOUS lowercase heavy grotesque, tight — the Rhode move */
h1.r-display, .r-display {
  font-family: var(--font-grotesque);
  font-weight: var(--reader-display-weight, 800);
  /* huge on desktop, but the floor + vw are tuned so the longest single title
     token (e.g. "seneplex+:") still fits a 360px phone without clipping */
  font-size: clamp(2.9rem, 13.5vw, 8.5rem);
  line-height: .9;
  letter-spacing: var(--reader-display-tracking, -.035em);
  text-transform: lowercase;
  margin: .12em 0 .1em;
  color: var(--reader-ink, #23211E);
  text-wrap: balance;
  overflow-wrap: normal;
  word-break: normal;
  -webkit-hyphens: none;
  hyphens: none;
}
/* section head — big lowercase grotesque, one notch down from the hero */
h2.r-head, .r-head {
  font-family: var(--font-grotesque);
  font-weight: var(--reader-head-weight, 700);
  font-size: clamp(2.2rem, 7vw, 3.6rem);
  line-height: .98;
  letter-spacing: var(--reader-head-tracking, -.03em);
  text-transform: lowercase;
  margin: 0 0 .5em;
  text-wrap: balance;
  color: var(--reader-ink, #23211E);
}

/* the lead — the one large-serif-optional intro line under the hero.
   Kept in the body face at large size (the reference), with .r-lead--serif
   opting into Didot for an editorial pull. */
.r-lead {
  font-size: clamp(1.25rem, 3.2vw, 1.6rem);
  line-height: 1.42;
  letter-spacing: -.005em;
  color: var(--reader-ink, #23211E);
  margin: 0 0 1.15em;
}
.r-lead--serif { font-family: var(--font-display); letter-spacing: 0; }

/* Packet-shell ownership disclosure: compact but unavoidable, directly beneath
   the hero lead on every independently viewed packet that carries the field. */
.r-disclosure,
.ssr-disclosure {
  max-width: 66ch;
  margin: .2rem 0 0;
  padding-top: .85rem;
  border-top: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
  color: var(--reader-ink-soft, #6E6A63);
  font-family: var(--font-mono);
  font-size: .72rem;
  line-height: 1.5;
  letter-spacing: .045em;
  text-transform: uppercase;
}

/* prose defaults inside the reader column */
.reader p { margin: 0 0 1.15em; }
/* key-phrase emphasis — the reference's true-face 650 intent (resolves to
   the crisp Demi Bold via --rt-strong-weight, no synthesis) */
.reader strong {
  font-weight: var(--rt-strong-weight, 600);
  font-synthesis-weight: none;
}
.reader em { font-style: italic; }

/* editorial ACCENT — Didot pull-quote (the reserved display-serif moment) */
.r-quote {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 4.5vw, 2.4rem);
  line-height: 1.24;
  letter-spacing: -.005em;
  color: var(--reader-ink, #23211E);
  margin: clamp(2rem, 5vw, 3rem) 0;
  max-width: min(var(--reader-measure, 620px), 100%);
}
.r-quote cite {                    /* attribution, quiet mono */
  display: block;
  margin-top: .8em;
  font: 400 .8rem/1.5 var(--font-mono);
  font-style: normal;
  letter-spacing: .04em;
  color: var(--reader-ink-soft, #6E6A63);
  text-transform: uppercase;
}


/* ============================================================
   4. STRUCTURE  —  hero, sections, hairline rules
   ============================================================ */
.r-hero { padding: clamp(2.5rem, 7vw, 5rem) 0 1rem; }
.r-hero--answer-first {
  padding-top: clamp(2rem, 5vw, 3.5rem);
}
.r-hero--answer-first .r-display {
  max-width: 16ch;
  font-size: clamp(2.9rem, 9vw, 5.8rem);
}
.r-section { padding: clamp(1.5rem, 4vw, 2.5rem) 0; }

/* Reviewed behind-text art. The live-text panel sits inside each sidecar's safe
   zone and uses a theme-ground glass fill, so decorative pixels cannot weaken
   text contrast. Backgrounds remain claim-free and aria-hidden. */
.visual-hero-bg { position: relative; isolation: isolate; overflow: clip; }
.visual-hero-bg > :not(.visual-bg-layer) { position: relative; z-index: 1; }
.visual-bg-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-color: var(--reader-ground, var(--ground, #E7E4DD));
  background-image: var(--visual-bg-wide);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
.visual-bg-layer::after {
  content: "";
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--reader-ground, var(--ground, #E7E4DD)) 34%, transparent);
}
.visual-safe-copy {
  width: min(620px, calc(100% - 52px));
  margin-inline: auto;
  padding: clamp(1.15rem, 3.4vw, 2rem);
  border: 1px solid color-mix(in srgb, var(--gold, #9C8A5A) 42%, transparent);
  border-radius: clamp(12px, 2.5vw, 22px);
  background: color-mix(in srgb, var(--reader-ground, var(--ground, #E7E4DD)) 93%, transparent);
  color: var(--reader-ink, var(--ink, #23211E));
  box-shadow: 0 24px 60px -42px rgba(12, 35, 64, .72);
  -webkit-backdrop-filter: blur(14px) saturate(112%);
  backdrop-filter: blur(14px) saturate(112%);
}
.ed-hero > .visual-safe-copy {
  width: min(620px, calc(100% - (2 * var(--section-x, 26px))));
  margin-inline: var(--section-x, 26px) auto;
}
[data-theme="dark"] .visual-bg-layer { filter: saturate(.82) brightness(.64); }
[data-theme="dark"] .visual-bg-layer::after {
  background: color-mix(in srgb, var(--reader-ground, var(--ground, #0A1526)) 45%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .visual-bg-layer { filter: saturate(.82) brightness(.64); }
  :root:not([data-theme]) .visual-bg-layer::after {
    background: color-mix(in srgb, var(--reader-ground, var(--ground, #0A1526)) 45%, transparent);
  }
}
@media (max-width: 700px) {
  .visual-bg-layer {
    background-image: var(--visual-bg-phone, var(--visual-bg-wide));
    background-position: center top;
  }
}

/* Supplemental reviewed figures preserve D1-owned packshots as a separate
   educational layer. Packet cards place this gallery inside the text-first
   .r-proof disclosure below; answers/evidence may still use it directly. */
.r-visual-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: clamp(1rem, 3vw, 1.6rem);
  width: min(900px, calc(100% - 52px));
  margin: clamp(1.5rem, 4vw, 2.75rem) auto;
  clear: both;
}
.r-inline-visual {
  min-width: 0;
  margin: 0;
  padding: clamp(.45rem, 1.5vw, .8rem);
  border: 1px solid color-mix(in srgb, var(--gold, #9C8A5A) 38%, transparent);
  border-radius: clamp(10px, 2vw, 18px);
  background: #FBFAF7;
  box-shadow: 0 28px 54px -42px rgba(12, 35, 64, .72);
}
.r-inline-visual img {
  display: block;
  width: 100%;
  height: auto;
  max-height: min(78vh, 1180px);
  object-fit: contain;
  border-radius: calc(clamp(10px, 2vw, 18px) - 5px);
}
@media (max-width: 560px) {
  .r-inline-visual.is-phone-bleed {
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    padding-inline: 0;
    border-inline: 0;
    border-radius: 0;
  }
  .r-inline-visual.is-phone-bleed img { border-radius: 0; }
}
@media (prefers-reduced-transparency: reduce) {
  .visual-safe-copy { background: var(--reader-ground, var(--ground, #E7E4DD)); backdrop-filter: none; }
}
/* a hairline divider on the ground — the calm section break */
.r-rule {
  height: 1px;
  border: 0;
  background: var(--reader-line, rgba(35, 33, 30, .14));
  margin: clamp(2rem, 5vw, 3rem) 0;
}


/* ============================================================
   5. READER ART  —  complete-object plates, OR explicit full-bleed
   ------------------------------------------------------------
   A normal, wrap, or specimen card is a complete-object plate: the whole
   packshot/diagram remains visible on a theme-matched surface. Only the
   authored `float` layout opts into .r-art--cover/.r-fullbleed cropping.
   This distinction is emitted identically by the SPA and SSR renderers.
   ============================================================ */
.r-art {
  --r-art-surface: color-mix(in srgb,
    var(--reader-ground-2, #F1EFEA) 92%, var(--reader-ink, #23211E) 8%);
  --r-art-line: color-mix(in srgb,
    var(--reader-ink, #23211E) 13%, transparent);
}
.r-art-surface {
  min-width: 0;
  box-sizing: border-box;
}
/* Let the responsive <picture> sources participate in the plate's grid. */
.r-art-surface > picture { display: contents; }
.r-art--contain .r-art-surface {
  display: grid;
  /* Explicit tracks keep intrinsic square packshots and tall diagrams inside
     the authored plate. Without them, the implicit grid track can grow to the
     image's intrinsic ratio and the surface merely clips the overflow. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  place-items: center;
  width: 100%;
  aspect-ratio: 16 / 10;
  padding: clamp(.45rem, 1.4vw, .8rem);
  overflow: hidden;
  border: 1px solid var(--r-art-line);
  border-radius: 8px;
  background: var(--r-art-surface);
  box-shadow: 0 24px 46px -38px rgba(35, 33, 30, .55);
}
.r-art--contain .r-cover-plate {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 5px;
  filter: none;
}
.r-bleed {
  margin: clamp(2.2rem, 6vw, 4rem) 0;
  text-align: center;
}
/* official SeneGence S mark (from the 2023 Identity Guide) behind every reader
   figure — brands the reserved space while a photo lazy-loads on scroll (and
   fills image-less cards) instead of a flat blank ground. Image sits on top. */
.r-bleed { position: relative; min-height: 150px; }
.r-bleed.r-art--contain {
  width: min(600px, calc(100% - 52px));
  min-height: 0;
  margin-inline: auto;
}
.r-bleed::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: center / auto 92px no-repeat url("../img/senegence-s-mark.svg");
  opacity: .14;
}
.r-bleed > picture, .r-bleed > img, .r-bleed > .r-art-surface,
.r-bleed figcaption { position: relative; z-index: 1; }
.r-bleed img {
  width: min(560px, 86vw);
  height: auto;
  display: inline-block;
  /* the ONLY separation — a soft float shadow, no frame, no rim */
  filter: var(--reader-float-shadow, drop-shadow(0 30px 46px rgba(35, 33, 30, .14)));
}

/* [both-design PHOTO GLOW, HIGH — REWORKED 2026-07-06] Dark-theme treatment for
   reader figures. The previous mix-blend-mode:multiply approach had two faults:
   (1) multiply against the near-black navy ground crushed the whole photo, and
   (2) .r-reveal's opacity/transform transition suppressed the blend while
   animating (own stacking context), so the photo POPPED darker the moment its
   reveal finished — the "picture darkens as I scroll" bug. Blend modes are
   backdrop-dependent by design; anything scroll-coupled behind the figure
   changes the result. So: NO blend mode. The photography is jewel-toned
   lifestyle imagery that reads beautifully at near-full brightness on navy —
   we keep it bright, apply only a whisper of tone-down so pure whites don't
   sear, and let the inner vignette melt the bright edges into the ground.
   Scroll-stable, reveal-safe. Light theme is UNTOUCHED.
   .rt-figure is included as the review-named hook in case a shell applies it. */
[data-theme="dark"] .r-bleed,
[data-theme="dark"] .rt-figure { position: relative; }
/* every reader figure layout (bleed/fullbleed/wrap/specimen) gets the SAME
   scroll-stable dark treatment so brightness is consistent across a packet */
[data-theme="dark"] .r-bleed img,
[data-theme="dark"] .rt-figure img,
[data-theme="dark"] .r-fullbleed img,
[data-theme="dark"] .r-wrap-media img,
[data-theme="dark"] .r-specimen img {
  filter:
    brightness(.94) contrast(1.02)
    var(--reader-float-shadow, drop-shadow(0 30px 46px rgba(35, 33, 30, .14)));
}
/* inner vignette: sits over the centered image, sized to match .r-bleed img,
   fading the edges into the ground so a bright photo border dissolves */
[data-theme="dark"] .r-bleed::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: min(560px, 86vw);
  height: 100%;
  pointer-events: none;
  background: radial-gradient(120% 92% at 50% 46%,
    transparent 54%,
    color-mix(in srgb, var(--reader-ground, #0B1A2E) 55%, transparent) 100%);
}
[data-theme="dark"] .r-bleed.r-art--contain::after { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .r-bleed,
  :root:not([data-theme]) .rt-figure { position: relative; }
  :root:not([data-theme]) .r-bleed img,
  :root:not([data-theme]) .rt-figure img,
  :root:not([data-theme]) .r-fullbleed img,
  :root:not([data-theme]) .r-wrap-media img,
  :root:not([data-theme]) .r-specimen img {
    filter:
      brightness(.94) contrast(1.02)
      var(--reader-float-shadow, drop-shadow(0 30px 46px rgba(35, 33, 30, .14)));
  }
  :root:not([data-theme]) .r-bleed::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: min(560px, 86vw);
    height: 100%;
    pointer-events: none;
    background: radial-gradient(120% 92% at 50% 46%,
      transparent 54%,
      color-mix(in srgb, var(--reader-ground, #0B1A2E) 55%, transparent) 100%);
  }
  :root:not([data-theme]) .r-bleed.r-art--contain::after { display: none; }
}
/* prefers-reduced-transparency: the vignette is a translucency effect — drop it
   and lean on the plain brightness filter (opaque compositing, not transparency) */
@media (prefers-reduced-transparency: reduce) {
  [data-theme="dark"] .r-bleed::after { display: none; }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme]) .r-bleed::after { display: none; }
  }
}

.r-bleed figcaption {
  margin-top: 1rem;
  color: var(--reader-ink-soft, #6E6A63);
  font-size: .9rem;
  font-style: italic;
}

/* edge-to-edge band (breaks the column; parent is .reader, not .r-col) */
.r-fullbleed {
  width: 100%;
  margin: clamp(2.5rem, 7vw, 4.5rem) 0;
}
.r-fullbleed.r-art--cover .r-art-surface {
  display: block;
  width: min(100%, 1100px);
  aspect-ratio: 16 / 9;
  height: auto;
  margin-inline: auto;
  overflow: hidden;
  background: var(--reader-ground-2, #F1EFEA);
}
.r-fullbleed img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
.r-fullbleed.r-art--cover img { height: 100%; }
.r-wrap-media.r-art--contain .r-art-surface { aspect-ratio: 4 / 5; }
.r-specimen.r-art--contain {
  width: min(600px, calc(100% - 52px));
  margin-inline: auto;
}
.r-specimen.r-art--contain .r-art-surface { aspect-ratio: 16 / 11; }
/* This rule follows the generic .r-bleed/.r-fullbleed image rules on purpose:
   complete-object layouts must win the cascade even when the source is tall.
   The surface carries separation, so no second crop-like shadow is needed. */
.r-art--contain img {
  width: 100%;
  height: 100%;
  min-width: 0;
  object-fit: contain;
  object-position: center;
  display: block;
  filter: none;
}
[data-theme="dark"] .r-art--contain img {
  filter: brightness(.90) contrast(1.02);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .r-art--contain img {
    filter: brightness(.90) contrast(1.02);
  }
}
.r-fullbleed figcaption {          /* caption returns to the measure */
  max-width: min(var(--reader-measure, 620px), 100%);
  margin: 1rem auto 0;
  padding-inline: 26px;
  color: var(--reader-ink-soft, #6E6A63);
  font-size: .9rem;
  font-style: italic;
}


/* ============================================================
   6. THE CLAIM BLOCK  —  the navy big-number moment
   ------------------------------------------------------------
   One saturated moment amid the calm: a navy panel with a gold hairline
   crown, a HUGE grotesque stat, one sentence, and a mono fine-print
   disclaimer (the Rhode perception-claim pattern). This is the ONLY
   place the reader leaves the putty ground.
   ============================================================ */
.r-claim {
  position: relative;
  overflow: hidden;
  background: var(--reader-claim-bg, var(--navy));
  color: var(--reader-claim-ink, #EAE6DC);
  border-radius: 6px;
  padding: clamp(2rem, 6vw, 3.4rem) clamp(1.5rem, 5vw, 2.6rem);
  margin: clamp(2.5rem, 6vw, 4rem) 0;
}
/* the gold hairline crown (metal edge, top) */
.r-claim::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2px;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in srgb, var(--gold) 60%, transparent),
    transparent);
}
/* eyebrow inside the claim goes gold — per-theme so it clears AA on both claim grounds */
.r-claim .r-eyebrow { color: var(--reader-claim-eyebrow, var(--gold)); }
.r-claim-kicker {
  margin: 0 0 .8rem;
  color: var(--reader-claim-eyebrow, var(--gold));
  font-family: var(--font-grotesque);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .16em;
  line-height: 1.35;
  text-transform: uppercase;
}
/* the huge number */
.r-stat {
  font-family: var(--font-grotesque);
  font-weight: var(--reader-display-weight, 800);
  letter-spacing: -.03em;
  font-size: clamp(3.2rem, 13vw, 6rem);
  line-height: .9;
  color: var(--reader-claim-stat, #F3EFE6);
  margin: .2em 0;
}
/* the one sentence */
.r-say {
  font-size: 1.15rem;
  color: var(--reader-claim-say, #CFCABE);
  max-width: 32ch;
  margin: 0;
}
/* the mono fine-print disclaimer */
.r-disc {
  margin-top: 1.4rem;
  font-size: .78rem;
  line-height: 1.5;
  letter-spacing: .01em;
  font-family: var(--font-mono);
  color: var(--reader-claim-disc, #8E897C);
}
.r-disc a,
.reader .richtext a {
  color: inherit;
  font-weight: 750;
  text-decoration-line: underline;
  text-decoration-color: var(--reader-clay, #A9673F);
  text-decoration-thickness: 1.5px;
  text-underline-offset: .24em;
}
.r-disc a:hover,
.reader .richtext a:hover {
  text-decoration-thickness: 2px;
}
.r-claim-context {
  display: inline-flex;
  gap: .5rem;
  margin-top: 1.5rem;
  color: var(--reader-claim-ink, #EAE6DC);
  font-family: var(--font-grotesque);
  font-size: .78rem;
  font-weight: 750;
  text-decoration-color: color-mix(in srgb, var(--gold) 72%, transparent);
  text-underline-offset: .25em;
}

/* Proof is lifted out of a hidden persona tier and placed near the start of the
   page. Multiple registered results become a compact grid, while a single
   result keeps the calm one-column reading measure. */
.r-proof-overview { padding: clamp(1.5rem, 4vw, 2.5rem) 0; }
.r-proof-intro {
  max-width: 58ch;
  margin: -.35rem 0 1.25rem;
  color: var(--reader-ink-soft, #6E6A63);
}
.r-proof-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: clamp(.85rem, 2.5vw, 1.25rem);
}
.r-proof-grid .r-claim {
  min-width: 0;
  margin: 0;
  padding: clamp(1.4rem, 4vw, 2.15rem);
}
.r-proof-grid .r-stat { font-size: clamp(2.5rem, 8vw, 4.35rem); }
.r-proof-grid .r-say { max-width: 42ch; font-size: 1rem; }


/* ============================================================
   7. THREE DISTINCT READING LAYERS
   ------------------------------------------------------------
   Customer value stays visible. Professional technique and formula science
   use native details so a human can open only the depth they need while the
   complete text remains present in the document for accessibility and search.
   ============================================================ */
.r-depth-stack {
  clear: both;
  max-width: min(var(--reader-measure, 620px), 100%);
  margin: clamp(1.25rem, 3.5vw, 2rem) 0 0;
  border-block: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
}
.r-depth-primary {
  padding: clamp(1.2rem, 3vw, 1.65rem) 0;
}
.r-depth-name {
  display: block;
  margin: 0;
  color: var(--reader-ink, #23211E);
  font-family: var(--font-grotesque);
  font-size: .84rem;
  font-weight: 800;
  letter-spacing: -.01em;
  text-transform: lowercase;
}
.r-depth-hint {
  display: block;
  margin: .16rem 0 .9rem;
  color: var(--reader-ink-soft, #6E6A63);
  font-family: var(--font-mono);
  font-size: .75rem;
  letter-spacing: .045em;
  line-height: 1.45;
  text-transform: uppercase;
}
.r-depth-primary > .richtext p:first-child { margin-top: 0; }
.r-depth-primary > .richtext p:last-child { margin-bottom: 0; }

/* ---- EDITORIAL CARD BODIES (owner ruling R-31, Alan Kante, 2026-08-04) ----
   "The visible card body is editorial — multi-paragraph permitted, capped at
   1,500 visible characters." The component used to model the marketing tier as
   one short sayable line, so a body of eight paragraphs inherited caption
   rhythm.

   MEASURE IS DELIBERATELY UNTOUCHED. .r-col is min(620px, 100%) with a 26px
   gutter, so the reading column measured 568px at 1440px and 338px at 390px —
   ~54ch and ~32ch of Avenir Next at --text-body (18px), comfortably inside the
   45–75ch readable range. It is NARROWER than the 62–68ch band DIRECTION.md
   documents, because the 66ch --rt-measure cap on .richtext is dormant behind
   the 620px column and always has been. That gap predates R-31 and is the whole
   reading column, not this component — widening it would move every reader page
   and no ruling authorises that, so it is reported, not resolved here.
   What long copy actually needs is vertical anyway: paragraph separation that
   still reads as separation after the eighth paragraph, and an entry paragraph.

   These rules engage only on a body that HAS a second paragraph (:has(p + p)),
   so every existing one-line card renders byte-for-byte as before and nothing
   in the corpus moves. Where :has is unsupported the body simply keeps the
   base .richtext rhythm — same progressive posture as text-wrap: pretty above.
   Type scale, ink, measure and emphasis all stay as editorial.css sets them. */
.r-depth-primary > .richtext:has(p + p) > p + p,
.r-depth-body .richtext:has(p + p) > p + p {
  margin-top: 1.15em;              /* base .95em: too close to the 1.55 leading
                                      to hold a paragraph edge over long copy */
}
/* The entry paragraph, one step up — DIRECTION.md "Type rhythm": the first
   paragraph of a depth tier may carry .lead. Only on the visible card body:
   inside a collapsed depth this would compete with its own summary. */
.r-depth-primary > .richtext:has(p + p) > p:first-child {
  font-size: 1.0625em;
  line-height: 1.5;
}
@media (max-width: 560px) {
  /* Narrow measure means more lines per paragraph, so the paragraph edge has to
     work harder; leading opens with it so the block does not read as a wall. */
  .r-depth-primary > .richtext:has(p + p),
  .r-depth-body .richtext:has(p + p) { line-height: 1.62; }
  .r-depth-primary > .richtext:has(p + p) > p + p,
  .r-depth-body .richtext:has(p + p) > p + p { margin-top: 1.05em; }
  .r-depth-primary > .richtext:has(p + p) > p:first-child { font-size: 1.045em; }
}
.r-depth {
  border-top: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
}
.r-depth > summary {
  position: relative;
  display: grid;
  grid-template-columns: minmax(8.5rem, .42fr) 1fr auto;
  align-items: center;
  gap: .75rem 1rem;
  min-height: 58px;
  padding: .8rem 2rem .8rem 0;
  cursor: pointer;
  list-style: none;
}
.r-depth > summary::-webkit-details-marker { display: none; }
.r-depth > summary::after {
  content: "+";
  position: absolute;
  right: .2rem;
  color: var(--reader-clay, #A9673F);
  font: 400 1.25rem/1 var(--font-grotesque);
  transition: transform var(--dur-micro, .3s) var(--ease-gentle, ease);
}
.r-depth[open] > summary::after { transform: rotate(45deg); }
.r-depth[data-depth="p"] > summary { box-shadow: inset 3px 0 0 color-mix(in srgb, #4F6F94 60%, transparent); padding-left: .8rem; }
.r-depth[data-depth="s"] > summary { box-shadow: inset 3px 0 0 color-mix(in srgb, #7E62A7 60%, transparent); padding-left: .8rem; }
.r-depth > summary .r-depth-hint { margin: 0; }
.r-depth-body {
  padding: .25rem .2rem clamp(1.35rem, 3vw, 1.8rem) .8rem;
  color: var(--reader-ink, #23211E);
}
.r-depth-body .richtext > :first-child { margin-top: 0; }
.r-depth-body .richtext > :last-child { margin-bottom: 0; }
@media (hover: hover) and (pointer: fine) {
  .r-depth > summary:hover .r-depth-name { color: var(--reader-clay, #A9673F); }
}
@media (max-width: 560px) {
  .r-depth > summary { grid-template-columns: 1fr; gap: .15rem; padding-block: .9rem; }
  .r-depth > summary .r-depth-hint { padding-right: 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  .r-depth > summary::after { transition: none; }
}


/* ============================================================
   8. THE FLOP COMPONENT  —  seamless in-place tab-swap
   ------------------------------------------------------------
   Rhode's front-page "Mission / Philanthropy / Sustainability" move.
   A horizontal segmented control whose segments, when clicked, SWAP
   the content beneath them in place: crossfade + height ease, no page
   change, no modal. This is how the three DEPTH TIERS render on every
   reader card: [ The Marketer · The Professional · The Skintellectual ].

   MARKUP CONTRACT (build agents author this; JS toggles .is-active):
     <div class="flop">
       <div class="flop-tabs" role="tablist">
         <button class="flop-tab is-active" role="tab" aria-selected="true"
                 aria-controls="p1" id="t1">the marketer</button>
         <button class="flop-tab" role="tab" aria-selected="false"
                 aria-controls="p2" id="t2">the professional</button>
         <button class="flop-tab" role="tab" aria-selected="false"
                 aria-controls="p3" id="t3">the skintellectual</button>
       </div>
       <div class="flop-body">
         <div class="flop-panel is-active" role="tabpanel" id="p1" aria-labelledby="t1">…</div>
         <div class="flop-panel" role="tabpanel" id="p2" aria-labelledby="t2" hidden>…</div>
         <div class="flop-panel" role="tabpanel" id="p3" aria-labelledby="t3" hidden>…</div>
       </div>
     </div>

   The active state is driven by .is-active (JS adds/removes it and the
   `hidden` attribute). CSS does the crossfade + height ease. The height
   ease uses CSS grid-rows (0fr→1fr) on .flop-body so it animates without
   JS measuring — the outgoing panel is position:absolute during the swap
   so both panels overlap for the crossfade, then the incoming panel's
   natural height drives the container.
   ============================================================ */
.flop {
  margin: clamp(2rem, 5vw, 3rem) 0;
  max-width: min(var(--reader-measure, 620px), 100%);
}

/* the segmented control */
.flop-tabs {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: var(--r-pill, 980px);
  background: var(--reader-ground-2, #F1EFEA);
  border: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
  margin-bottom: clamp(1.2rem, 3vw, 1.8rem);
}
.flop-tab {
  flex: 1 1 0;
  min-width: 0;
  min-height: 40px;
  padding: .55rem .4rem;
  border: 0;
  border-radius: var(--r-pill, 980px);
  background: transparent;
  color: var(--reader-ink-soft, #6E6A63);
  font-family: var(--font-grotesque);
  font-weight: 700;
  /* shrinks just enough that "the skintellectual" (the longest tier label)
     shows in full across three equal tabs on a phone — no ellipsis */
  font-size: clamp(.58rem, 2.7vw, .74rem);
  letter-spacing: .01em;
  text-transform: lowercase;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color var(--dur-micro, .3s) var(--ease-gentle, ease),
              background var(--dur-micro, .3s) var(--ease-gentle, ease);
}
.flop-tab.is-active {
  color: var(--reader-ink, #23211E);
  background: var(--reader-ground, #E7E4DD);
  box-shadow: 0 1px 2px rgba(35, 33, 30, .10);
}
@media (hover: hover) and (pointer: fine) {
  .flop-tab:not(.is-active):hover { color: var(--reader-ink, #23211E); }
}
.flop-tab:focus-visible {
  outline: 2px solid var(--reader-clay, #A9673F);
  outline-offset: 2px;
}

/* the swap area — grid overlaps panels so they can crossfade in place;
   height eases because the active (in-flow) panel drives the row height */
.flop-body {
  display: grid;
}
.flop-panel {
  grid-area: 1 / 1;                 /* stack every panel in the same cell */
  min-width: 0;
  color: var(--reader-ink, #23211E);
  line-height: 1.6;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition:
    opacity var(--dur-micro, .3s) var(--ease-gentle, ease),
    transform var(--dur-micro, .3s) var(--ease-gentle, ease),
    visibility 0s linear var(--dur-micro, .3s);
}
/* the visible panel: it is the only one that participates in HEIGHT, so
   the container eases to its measure as content swaps */
.flop-panel.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  position: relative;              /* in-flow → drives grid row height */
  transition:
    opacity var(--dur-micro, .3s) var(--ease-gentle, ease),
    transform var(--dur-micro, .3s) var(--ease-gentle, ease);
}
.flop-panel p:last-child { margin-bottom: 0; }
/* first line of a tier can be a quiet clay lead-in via .flop-panel .r-label */
.flop-panel .r-label { display: block; margin-bottom: .5em; color: var(--reader-clay, #A9673F); }

/* Height ease: when the browser supports interpolate-size, let the grid
   row animate between panel heights smoothly. Progressive — without it
   the swap is an instant height jump under a crossfade (still clean). */
@supports (interpolate-size: allow-keywords) {
  .flop-body { interpolate-size: allow-keywords; transition: none; }
}

/* REDUCED MOTION: instant swap, no fade/slide/height ease */
@media (prefers-reduced-motion: reduce) {
  .flop-panel,
  .flop-panel.is-active { transition: none; transform: none; }
  .flop-tab { transition: none; }
}
/* Progressive no-JS / hidden-attr fallback: if a panel keeps the native
   [hidden] attribute (JS toggles both), honor it so non-active panels
   never leak in when scripting is unavailable. */
.flop-panel[hidden] { display: none; }


/* ============================================================
   8. THE CALM READER QUIZ  —  reuses the shared .quiz-choice markup
   ------------------------------------------------------------
   The brief: "calm inline quiz styling REUSING quiz markup." So .r-quiz
   is a WRAPPER that restyles the existing <button class="quiz-choice">
   toward the reader idiom (putty buttons, hairline borders, grotesque
   question). No new button class — the Studio's quiz JS keeps working.
   ============================================================ */
.r-quiz { margin: clamp(2.5rem, 6vw, 4rem) 0; max-width: min(var(--reader-measure, 620px), 100%); }
/* the question — grotesque, lowercase, tight (matches section heads) */
.r-quiz .r-q {
  font-family: var(--font-grotesque);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: -.02em;
  text-transform: lowercase;
  margin-bottom: 1.3rem;
  color: var(--reader-ink, #23211E);
}
/* restyle the SHARED .quiz-choice to the reader idiom (name unchanged) */
.r-quiz .quiz-choice {
  min-height: 0;
  background: var(--reader-ground-2, #F1EFEA);
  border: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
  border-radius: 4px;
  padding: 1rem 1.2rem;
  margin-bottom: .7rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--reader-ink, #23211E);
}
@media (hover: hover) and (pointer: fine) {
  .r-quiz .quiz-choice:hover { border-color: var(--reader-ink-soft, #6E6A63); }
}
/* correct/wrong keep the shared class hooks, re-tinted for the putty ground */
.r-quiz .quiz-choice.correct {
  border-color: var(--reader-correct, #3B7A57);
  background: color-mix(in srgb, var(--reader-correct, #3B7A57) 10%, var(--reader-ground-2, #F1EFEA));
}
.r-quiz .quiz-choice.wrong {
  border-color: var(--jewel-ruby);
  background: color-mix(in srgb, var(--jewel-ruby) 10%, var(--reader-ground-2, #F1EFEA));
}
/* the shared emerald tick (glass.css .quiz-choice.correct::after) still
   fires; re-point its color toward the reader emerald for tone match */
.r-quiz .quiz-choice.correct::after {
  color: color-mix(in srgb, var(--reader-correct, #3B7A57) 80%, var(--reader-ink, #23211E));
}
.r-quiz .quiz-feedback { color: var(--reader-ink, #23211E); }


/* ============================================================
   9. INLINE PROGRESSIVE DISCLOSURE  —  the science, on demand
   ------------------------------------------------------------
   The reference's <details> pattern: "the science" opens INLINE, not in
   a separate screen/sheet. A hairline-topped disclosure with a clay
   grotesque summary and a mono footnote foot.
   ============================================================ */
.r-details {
  margin: 1.5rem 0 0;
  border-top: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
  padding-top: 1.1rem;
  max-width: min(var(--reader-measure, 620px), 100%);
}
.r-details > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-grotesque);
  font-weight: 700;
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--reader-clay, #A9673F);
}
.r-details > summary::-webkit-details-marker { display: none; }
.r-details .r-chev { transition: transform var(--dur-micro, .3s); }
.r-details[open] > summary .r-chev { transform: rotate(90deg); }
.r-details .r-inner { padding-top: 1rem; color: var(--reader-ink, #23211E); }
.r-details .r-foot {
  margin-top: 1rem;
  padding-top: .8rem;
  border-top: 1px solid var(--reader-line, rgba(35, 33, 30, .14));
  font: 400 .8rem/1.5 var(--font-mono);
  color: var(--reader-ink-soft, #6E6A63);
}

/* Packet-card proof cadence: the tier text is the uninterrupted primary read.
   Every reviewed figure lives in one predictable, closed-by-default proof slot
   after that copy. Once invited open, figures stay deliberately narrower than
   the reading column on desktop; phone retains the available column width and
   the reviewed .is-phone-bleed exception. */
.r-proof {
  clear: both;
  margin-block: 0 clamp(1.5rem, 4vw, 2.25rem);
}
.r-proof > summary {
  min-height: 44px;
  color: var(--reader-ink-soft, #6E6A63);
  letter-spacing: .1em;
}
.r-proof > summary:hover { color: var(--reader-clay, #A9673F); }
.r-proof > summary:focus-visible {
  outline: 2px solid var(--reader-clay, #A9673F);
  outline-offset: 4px;
}
.r-proof-count {
  margin-left: auto;
  color: var(--reader-ink-faint, #A6A299);
  font: 400 .68rem/1.2 var(--font-mono);
  letter-spacing: .03em;
  text-transform: lowercase;
}
.r-proof .r-inner { padding-top: clamp(.8rem, 2vw, 1.2rem); }
.r-proof .r-visual-gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(.8rem, 2vw, 1.15rem);
  width: min(500px, 100%);
  margin: 0 auto;
}
.r-proof .r-inline-visual {
  padding: clamp(.35rem, 1vw, .55rem);
  border-radius: clamp(8px, 1.4vw, 13px);
  box-shadow: 0 18px 38px -34px rgba(12, 35, 64, .64);
}
@media (max-width: 560px) {
  .r-proof { margin-bottom: 1.25rem; }
  .r-proof .r-visual-gallery { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .r-details .r-chev { transition: none; }
}


/* ============================================================
   10. THE SEAMLESS NEXT  —  next-packet footer
   ------------------------------------------------------------
   The reader never dead-ends: a calm sign-off + a large lowercase
   grotesque link to the next packet, on the same ground. .r-next is
   an <a> so the whole block is one tap target.
   ============================================================ */
.r-fin {
  padding: clamp(3rem, 8vw, 5rem) 0 clamp(4rem, 10vw, 7rem);
  text-align: center;
}
.r-fin .r-fin-mono {
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .03em;
  color: var(--reader-ink-faint, #A6A299);
}
.r-next {
  display: block;
  text-decoration: none;
  color: var(--reader-ink, #23211E);
  margin-top: clamp(2rem, 5vw, 3rem);
  transition: transform var(--dur-micro, .3s) var(--ease-out, ease);
}
.r-next .r-next-kicker {          /* "up next" — clay grotesque micro-caps */
  font-family: var(--font-grotesque);
  font-weight: 700;
  font-size: .7rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--reader-clay, #A9673F);
  display: block;
  margin-bottom: .4em;
}
.r-next .r-next-title {           /* the big lowercase grotesque next-title */
  font-family: var(--font-grotesque);
  font-weight: 800;
  font-size: clamp(1.8rem, 6vw, 3rem);
  line-height: .98;
  letter-spacing: -.03em;
  text-transform: lowercase;
  color: var(--reader-ink, #23211E);
}
@media (hover: hover) and (pointer: fine) {
  .r-next:hover { transform: translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) {
  .r-next { transition: none; }
  .r-next:hover { transform: none; }
}


/* ============================================================
   11. REVEAL-ON-SCROLL  —  reader-scoped, motion-safe
   ------------------------------------------------------------
   The reference's gentle fade-up. Scoped to .reader so it never touches
   the Studio's own animations. JS adds .is-in when the element enters
   the viewport. Reduced-motion shows everything immediately.
   ============================================================ */
.reader .r-reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity .8s var(--ease-out, ease),
    transform .8s cubic-bezier(.2, .7, .3, 1);
}
.reader .r-reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reader .r-reveal { opacity: 1; transform: none; transition: none; }
}


/* ============================================================
   12. READER FOCUS  —  clay outline on the putty ground
   ------------------------------------------------------------
   The reference's focus color. Scoped to .reader so the global
   --focus-ring token (which serves the rest of the app) is untouched.
   Clay-on-putty clears 3:1 for the non-text focus indicator.
   ============================================================ */
.reader :focus-visible {
  outline: 2px solid var(--reader-clay, #A9673F);
  outline-offset: 3px;
}
