/* ============================================================
   COMPONENT PARAGRAPH RESET
   base.css gives <p> a 1.15em bottom margin for prose rhythm. That margin
   scales with font-size, so a 76px .stat-figure inherited an 87px gap and
   detached itself from its own label. Component text takes its spacing from
   the container's gap instead.
   ============================================================ */
.stat-figure,
.stat-label,
.stat-note,
.card-eyebrow,
.quote-text,
.title-card-topline,
.title-card-meta,
.step-num,
.step-desc,
.media-figure-caption,
.logorow-item-text,
.hero-cinematic-tagline {
  margin: 0;
}

/* ============================================================
   Sections — reusable section library
   Generalized from the "Story of America 250" cinematic
   one-off page (reference/cinematic-reference.css) into named,
   modifier-based section types for a 16-page Webflow site.

   Conventions inherited from base.css — do not redefine here:
   .wrap, .wrap-text, .section, .eyebrow (+.eyebrow-bar,
   .eyebrow-accent), .lede, .reveal (+.reveal-d1..d4), .btn
   (+.btn-primary), h1–h4, .display-italic, .accent, .brass.

   Flat class selectors only. No :has(), no nesting, no @layer,
   no @container, no child combinators deeper than one level,
   no :nth-child. The only attribute selector is [data-parallax].
   ============================================================ */


/* ============================================================
   HERO-CINEMATIC
   Sticky 100vh hero with a logo lockup, scroll cue and radial
   glows. From .cine-hero / .hero-spacer. The spacer gives the
   sticky section room to sit still while the page scrolls past
   it — a layout mechanism, not a motion effect, so it is not
   gated by the intensity dial.
   ============================================================ */
.hero-cinematic-spacer {
  height: 120vh;
  position: relative;
}
.hero-cinematic {
  height: 100vh;
  position: sticky;
  top: 0;
  overflow: hidden;
  background: var(--black);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Two soft radial glows, matched to the reference exactly. */
.hero-cinematic-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(50% 50% at 50% 50%, rgba(36, 50, 133, 0.25), transparent 70%),
    radial-gradient(70% 60% at 50% 100%, rgba(192, 31, 60, 0.10), transparent 70%);
}
.hero-cinematic-content {
  position: relative;
  z-index: 5;
  text-align: center;
  padding: 0 var(--gutter);
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.hero-cinematic-logo {
  width: min(58vw, 580px);
  height: auto;
  margin: 0 auto;
}
/* Optional line under the logo lockup, e.g. a tagline. */
.hero-cinematic-tagline {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-3);
  line-height: 1.18;
  letter-spacing: -0.01em;
  color: var(--paper);
  margin: var(--gutter) auto 0;
  max-width: 24ch;
}

/* ---- Scroll cue ---- */
.hero-cue {
  position: absolute;
  bottom: 44px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  color: var(--paper-dim);
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  transition: opacity 0.6s ease;
}
/* Toggled by scroll-position JS once the visitor starts scrolling. */
.hero-cue.is-hidden {
  opacity: 0;
  pointer-events: none;
}
.hero-cue-chev {
  color: var(--paper);
}


/* ============================================================
   HERO-PAGE
   Shorter, non-sticky interior-page hero (~60vh): eyebrow,
   display h1, lede. Not in the reference — derived from the
   title card's centered proportions at a page-header scale.
   ============================================================ */
.hero-page {
  min-height: 60vh;
  display: flex;
  align-items: center;
  background: var(--black);
}
.hero-page-inner {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: var(--section-pad) var(--gutter);
  text-align: center;
}
.hero-page-inner .eyebrow {
  justify-content: center;
  margin-bottom: 28px;
}
.hero-page-inner h1 {
  margin: 0 auto;
  max-width: 20ch;
}
.hero-page-inner .lede {
  margin: 24px auto 0;
  text-align: center;
}
/* Left-aligned variant for pages that don't want a centered header. */
.hero-page-left .hero-page-inner {
  text-align: left;
}
.hero-page-left .hero-page-inner .eyebrow {
  justify-content: flex-start;
}
.hero-page-left .hero-page-inner .lede {
  margin-left: 0;
  margin-right: 0;
}
/* The base rule centres the h1 with `margin: 0 auto`, which survives
   text-align: left and leaves the heading floating away from its own copy. */
.hero-page-left .hero-page-inner h1 {
  margin-left: 0;
  margin-right: 0;
}

/* Constrain the hero to the reading measure, so a document's title sits
   directly above its own text column rather than in a much wider container.
   Pair with .hero-page-left on the long-form legal pages. */
.hero-page-narrow .hero-page-inner {
  max-width: var(--wrap-text);
}


/* ============================================================
   MASTHEAD
   An informative opening, as against the cinematic hero's teaser.
   Carries eyebrow, h1, lede, actions and a stat strip in a single
   screen, over a scrimmed photograph. Use where a visitor arrives
   to evaluate rather than to be impressed.
   ============================================================ */
.masthead {
  position: relative;
  /* Deliberately under 100vh: a sliver of the next section shows, which
     tells the reader there is substance below without needing a scroll cue. */
  min-height: 88vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--black);
  padding-top: 84px;
}
.masthead-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}
.masthead-bg-media,
.masthead-bg video {
  filter: brightness(var(--photo-dim, 1));
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
}
.masthead-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Heavier on the left where the copy sits, and closing to solid at the
     bottom so the stat strip and the next section read as one surface. */
  background:
    linear-gradient(to right, rgba(var(--scrim-rgb), 0.94) 0%, rgba(var(--scrim-rgb), 0.82) 38%, rgba(var(--scrim-rgb), 0.34) 72%, rgba(var(--scrim-rgb), 0.14) 100%),
    linear-gradient(to bottom, rgba(var(--scrim-rgb), 0.85) 0%, rgba(var(--scrim-rgb), 0.30) 38%, rgba(var(--scrim-rgb), 0.72) 82%, var(--black) 100%);
}
.masthead-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: calc(var(--section-pad) * 0.28) var(--gutter);
}
/* Copy and player side by side, both sitting ON the background image. The
   copy column is the wider of the two: the video supports the claim, it is not
   the claim. */
.masthead-split {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  gap: clamp(32px, 4vw, 64px);
  align-items: center;
}
.masthead-copy { max-width: 56ch; }
.masthead-media { min-width: 0; }
.masthead h1 {
  font-size: clamp(44px, 6.4vw, 104px);
  font-style: italic;
  line-height: 0.98;
  margin-top: 22px;
}
.masthead-lede {
  margin: 28px 0 0;
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--paper-dim);
  max-width: 56ch;
}
.masthead-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 40px;
}

/* Stat strip: the three numbers that answer "what is this, and at what
   scale" without the reader having to go looking for them. */
.masthead-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gutter);
  margin-top: calc(34px * var(--density));
  padding-top: 22px;
  border-top: 1px solid var(--line-strong);
}
.masthead-stat-figure {
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(32px, 3.4vw, 52px);
  line-height: 1;
  color: var(--paper);
}
.masthead-stat-label {
  margin: 10px 0 0;
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-mute);
  /* Reserve the line: the "100%" stat has no label word in the source copy,
     and without this its note rides up out of alignment with the others. */
  min-height: 1.4em;
}
.masthead-stat-note {
  margin: 8px 0 0;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--paper-dim);
  max-width: 30ch;
}

@media (max-width: 991px) {
  /* One column below the desktop breakpoint: side by side, neither the copy
     nor a 16:9 player has enough width to hold its shape. */
  .masthead-split { grid-template-columns: 1fr; gap: 36px; }
  .masthead-copy { max-width: none; }
}

@media (max-width: 767px) {
  .masthead { min-height: auto; padding-top: 88px; }
  .masthead-stats { grid-template-columns: 1fr; gap: 28px; }
  .masthead-scrim {
    /* One column means the copy spans the full width, so the horizontal
       gradient no longer protects it. Go darker overall instead. */
    background: linear-gradient(to bottom, rgba(var(--scrim-rgb), 0.94) 0%, rgba(var(--scrim-rgb), 0.89) 55%, var(--black) 100%);
  }
  .masthead-actions .btn { width: 100%; justify-content: center; }
}

/* ============================================================
   STATE LOGO + TICK SPEC
   Small pieces the state-partnership pages need.
   ============================================================ */

/* The partner's own mark, sitting beside the masthead copy. State seals and
   department logos arrive in wildly different aspect ratios and mostly assume
   a light ground, so this gives them a consistent, legible plate rather than
   letting each one set its own size. */
.statelogo {
  position: relative;
  z-index: 2;
  margin-top: calc(34px * var(--density));
  padding-top: 22px;
  border-top: 1px solid var(--line-strong);
}
/* No plate. The earlier note here assumed these were dark marks on
   transparency that would vanish on a dark ground — they are not. Four of the
   five are self-contained medallions: dark line art on their own white circle,
   baked into the artwork. The cream tile was wrapping a circle in a rectangle,
   which is the whole of why they looked stuck on. Oklahoma is a horizontal
   lockup and uses the transparent variant, whose wordmark is already white.

   Sized by AREA rather than height, because a 1:1 seal and a 3:1 lockup set
   to the same height do not carry the same weight — the lockup looks twice as
   loud. The square marks get the height; the wide one is capped by width so
   the two end up about equally present. */
.statelogo img {
  width: auto;
  /* 170 rather than 136: at 136 the rim lettering on the seals — FLORIDA
     STATE UNIVERSITY, SOUTH CAROLINA DEPARTMENT OF EDUCATION — is still a
     grey smudge, and that lettering is what identifies the mark. At 170 it
     reads. Past about 190 the partner starts competing with the page's own
     headline, which is the wrong hierarchy for an endorsement. */
  height: clamp(112px, 11vw, 170px);
  max-width: min(300px, 62vw);
  object-fit: contain;
  object-position: left center;
}

/* A short specification list — mono, hairline-ruled, no bullet glyphs. */
.tickspec {
  list-style: none;
  margin: 28px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0 32px;
}
.tickspec li {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-dim);
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  min-width: 160px;
}

@media (max-width: 767px) {
  .statelogo img { height: 72px; max-width: 200px; }
  .tickspec { gap: 0; }
  .tickspec li { min-width: 0; width: 100%; }
}

/* ============================================================
   FIGURE SCENE EXTRAS
   Small pieces the Fireside page's figure scenes need on top of .scene.
   ============================================================ */

/* The figure's role, sitting immediately under their name. */
.figurerole {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-mute);
}

/* The question a student might put to this figure. Set apart from the body
   copy because it is the line that carries the whole idea. */
.figureask {
  margin: 8px 0 0;
  padding-left: 20px;
  border-left: 2px solid var(--brass);
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-2);
  line-height: 1.35;
  color: var(--paper);
}

/* The source a figure's answers are grounded in. Set small and quiet — it is
   a citation, not a claim, but it is the reason to trust the whole thing. */
.figuresource-date { white-space: nowrap; }
/* Separator between the date and the citation. A real element rather than a
   middot in the text, so each string stays a verbatim run of its own. */
.figuresource-sep {
  display: inline-block;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  margin: 0 10px;
  vertical-align: middle;
  opacity: 0.7;
}
.figuresource {
  margin: 14px 0 0;
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-mute);
}

/* The Fireside product lockup. Constrained because it arrives as a tall
   stacked raster and would otherwise dominate its section. */
.firesidemark {
  display: block;
  width: min(46vw, 340px);
  height: auto;
  margin-top: 28px;
}

@media (max-width: 767px) {
  .figureask { font-size: var(--step-1); padding-left: 14px; }
  .firesidemark { width: min(70vw, 260px); }
}

/* ============================================================
   BACKGROUND VIDEO + MOTION CONTROL
   A video slot behind the masthead, with the still as its poster so the
   section is complete before a single frame downloads — and correct forever
   if no video is ever supplied.
   ============================================================ */

.masthead-bg video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  display: block;
}

/* WCAG 2.2.2: anything that moves automatically for more than five seconds
   needs a way to stop it. This is a requirement, not a nicety — and it also
   gives anyone on a metered connection a way out. */
.motiontoggle {
  position: absolute;
  z-index: 3;
  right: var(--gutter);
  bottom: 22px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 7px 16px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(var(--scrim-rgb), 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.25s ease, border-color 0.25s ease;
}
.motiontoggle:hover { background: rgba(var(--scrim-rgb), 0.8); }
/* Hidden until the script confirms there is a video to control. */
.motiontoggle.is-hidden { display: none; }
.motiontoggle-icon {
  width: 9px;
  height: 10px;
  flex: none;
  background: currentColor;
  /* Two bars for pause; the script swaps the clip path for play. */
  clip-path: polygon(0 0, 34% 0, 34% 100%, 0 100%, 0 0, 66% 0, 100% 0, 100% 100%, 66% 100%, 66% 0);
}
/* Fixed width so the button does not resize when the label swaps between
   "Pause" and "Play" — a control that jumps as you press it feels broken. */
.motiontoggle-text {
  display: inline-block;
  min-width: 4.4em;
  text-align: left;
}

.motiontoggle.is-paused .motiontoggle-icon {
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

@media (max-width: 767px) {
  .motiontoggle { right: auto; left: var(--gutter); bottom: 14px; }
}

/* ============================================================
   FEATURE VIDEO
   An on-demand player: poster only until asked, so nothing downloads for a
   visitor who never presses play.
   ============================================================ */
.featurevideo {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  background: var(--ink);
  /* Sitting on a photograph, the player needs to read as an object placed on
     top rather than a window cut into it. */
  box-shadow: 0 24px 60px rgba(var(--scrim-rgb), 0.55);
}
.featurevideo video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.featurevideo-caption {
  margin: 12px 0 0;
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-mute);
}

/* ============================================================
   TITLE-CARD
   Full-bleed centered display statement — a film cold-open.
   From .title-card.
   ============================================================ */
.title-card {
  min-height: 100vh;
  background: var(--black);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  padding: calc(var(--gutter) * 1.25) var(--gutter);
  border-top: 1px solid var(--line);
}
.title-card-inner {
  text-align: center;
  max-width: var(--wrap);
  margin: 0 auto;
}
.title-card-topline {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--paper-mute);
  margin-bottom: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}
.title-card-topline-bar { width: 40px; height: 1px; background: var(--paper-mute); }
.title-card-statement {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--display);
  line-height: 0.92;
  letter-spacing: -0.025em;
  color: var(--paper);
  margin: 0;
  font-weight: 400;
}
.title-card-meta {
  margin-top: 64px;
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--paper-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  flex-wrap: wrap;
}
.title-card-meta-num { color: var(--paper); font-size: 14px; }
.title-card-meta-dash { width: 60px; height: 1px; background: var(--paper-mute); }


/* ============================================================
   SCENE
   One full-bleed background (image or video) with a scrim and
   overlaid text. Generalizes .cine-premise (centered) and the
   per-figure .cine-scene (side-anchored) into one section type.
   Placement is set with a modifier: .scene-left / .scene-right /
   .scene-center.
   ============================================================ */
.scene {
  position: relative;
  min-height: 100vh;
  background: var(--black);
  overflow: hidden;
  display: flex;
}
/* Background layer. Either set background-image inline on this element,
   or drop an <img>/<video class="scene-bg-media"> inside it for object-fit. */
.scene-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center 18%;
  background-repeat: no-repeat;
}
.scene-bg-media {
  filter: brightness(var(--photo-dim, 1));
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 18%;
}
/* Slow drift, gated on [data-parallax] so static scenes stay perfectly still.
   At --motion-parallax: 0 every keyframe value collapses to the same
   transform, so the animation is a true visual no-op rather than a slow one. */
/* Scrim: vertical read-legibility gradient plus a horizontal one used by
   the side-anchored modifiers. Opacities match the reference — do not
   lighten them, text contrast depends on this. */
.scene-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(72% 52% at 50% 52%, rgba(var(--scrim-rgb), 0.55), rgba(var(--scrim-rgb), 0) 72%),
    linear-gradient(to bottom,
      var(--black) 0%,
      rgba(var(--scrim-rgb), 0.45) 14%,
      rgba(var(--scrim-rgb), 0.18) 42%,
      rgba(var(--scrim-rgb), 0.42) 74%,
      var(--black) 100%);
}
.scene-content {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: calc(var(--section-pad) * 0.8) var(--gutter);
  display: flex;
  flex: 1;
}
.scene-content-inner {
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-width: 46ch;
}
.scene-content-inner .eyebrow-bar { background: currentColor; }
.scene-content-inner h2,
.scene-content-inner h3 {
  font-style: italic;
  /* Deliberately smaller than the global h2. Overlaid on imagery in a narrow
     column, display sizes wrap a long heading into an unreadable stack. */
  font-size: var(--step-3);
}
.scene-content-inner p {
  font-family: var(--serif);
  font-size: var(--step-2);
  line-height: 1.4;
  color: var(--paper-dim);
}

/* ---- Placement modifiers ---- */
.scene-center .scene-content {
  align-items: center;
  justify-content: center;
  text-align: center;
}
.scene-center .scene-content-inner {
  max-width: 32ch;
  align-items: center;
}
/* Darken the side the text actually sits on. Without this, overlaid copy
   depends on the photograph's luminance at that spot, which is not a
   contrast guarantee. */
.scene-left .scene-scrim {
  background:
    linear-gradient(to right, rgba(var(--scrim-rgb), 0.92) 0%, rgba(var(--scrim-rgb), 0.72) 34%, rgba(var(--scrim-rgb), 0.10) 68%, rgba(var(--scrim-rgb), 0) 100%),
    linear-gradient(to bottom, var(--black) 0%, rgba(var(--scrim-rgb), 0.25) 22%, rgba(var(--scrim-rgb), 0.25) 72%, var(--black) 100%);
}
.scene-right .scene-scrim {
  background:
    linear-gradient(to left, rgba(var(--scrim-rgb), 0.92) 0%, rgba(var(--scrim-rgb), 0.72) 34%, rgba(var(--scrim-rgb), 0.10) 68%, rgba(var(--scrim-rgb), 0) 100%),
    linear-gradient(to bottom, var(--black) 0%, rgba(var(--scrim-rgb), 0.25) 22%, rgba(var(--scrim-rgb), 0.25) 72%, var(--black) 100%);
}

.scene-left .scene-content {
  align-items: center;
  justify-content: flex-start;
}
/* Vertically centred, like .scene-left: bottom-aligning pushed a tall block's
   own closing paragraph off the foot of the scene. The block sits right, but
   the text inside stays left-aligned — a right-aligned ragged-left paragraph
   is markedly harder to read, and these scenes carry real body copy. */
.scene-right .scene-content {
  align-items: center;
  justify-content: flex-end;
}
.scene-right .scene-content-inner {
  align-items: flex-start;
}


/* ============================================================
   PROSE
   Long-form body copy for legal/support pages. There is almost
   nothing to adapt from the reference here — this is built up
   from base.css's own type rules so it reads as the same brand
   at a quieter, reading register, and used inside a Rich Text /
   CMS-bound block that outputs plain h2/h3/p/ul/ol/etc.
   ============================================================ */
/* Horizontal padding is required, not optional: without it the body copy
   sits flush against the screen edge on narrow viewports, and five of the
   sixteen pages are text documents. */
.prose {
  width: 100%;
  max-width: var(--wrap-text);
  margin: 0 auto;
  padding: 0 var(--gutter);
  /* The legal documents print bare URLs as body text — the longest is 37
     characters. On a 320px viewport an unbreakable token that long pushes the
     line box past the edge. body{overflow-x:hidden} would mask it rather than
     fix it, so break the word instead. */
  overflow-wrap: break-word;
}
.prose h2 {
  font-size: var(--step-3);
  margin-top: 2em;
  margin-bottom: 0.6em;
}
.prose h2:first-child { margin-top: 0; }
.prose h3 {
  font-size: var(--step-2);
  margin-top: 1.8em;
  margin-bottom: 0.5em;
}
/* The privacy statement genuinely nests to h5 ("From Educators" / "From
   Children"). Without a rule these fell back to the browser default — sans,
   browser-sized — on a serif document. Styled rather than downgraded to a
   bold paragraph, so the legal outline stays intact. */
.prose h4 {
  font-size: var(--step-1);
  margin-top: 1.6em;
  margin-bottom: 0.4em;
}
.prose h5 {
  font-family: var(--serif);
  font-weight: 400;
  font-style: italic;
  font-size: var(--step-0);
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--paper);
  margin-top: 1.5em;
  margin-bottom: 0.35em;
}

.prose p {
  font-size: var(--step-0);
  line-height: 1.75;
  color: var(--paper-dim);
  margin-bottom: 1.4em;
}
.prose ul,
.prose ol {
  margin: 0 0 1.4em;
  padding-left: 1.4em;
  color: var(--paper-dim);
  font-size: var(--step-0);
  line-height: 1.75;
}
.prose li { margin-bottom: 0.5em; }
.prose li:last-child { margin-bottom: 0; }
.prose blockquote {
  margin: 2em 0;
  padding: 0.2em 0 0.2em 1.4em;
  border-left: 2px solid var(--brass);
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--paper);
}
.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 2em 0;
  font-size: var(--step--1);
}
.prose th,
.prose td {
  text-align: left;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.prose th {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-mute);
  font-weight: 400;
}
/* Wrap any wide table in <div class="prose-scroll"> — the page body must
   never scroll horizontally, and the legal pages do carry real tables. */
.prose-scroll {
  width: 100%;
  overflow-x: auto;
  margin: 2em 0;
  -webkit-overflow-scrolling: touch;
}
.prose-scroll table { margin: 0; }
.prose-scroll th,
.prose-scroll td { white-space: nowrap; }
.prose hr {
  border: none;
  border-top: 1px solid var(--line);
  margin: 2.5em 0;
}
.prose strong { color: var(--paper); font-weight: 600; }
/* Emphasis stays the body colour. Legal copy italicises defined terms and
   statute names constantly; tinting every one of them reads as noise. */
.prose em { font-style: italic; }
.prose a { color: var(--paper); }
/* First element flush against the top of the section padding. */
.prose > *:first-child { margin-top: 0; }
.prose > *:last-child { margin-bottom: 0; }


/* ============================================================
   CARDGRID / CARD
   Responsive card grid. Hairline borders, mono eyebrow, serif
   heading. Not a single named section in the reference — the
   hairline-bordered grid rhythm is lifted from .cine-grounded
   / .cine-coalition, generalized into a plain content card.
   ============================================================ */
.cardgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gutter);
}
.cardgrid-2 { grid-template-columns: repeat(2, 1fr); }
.cardgrid-3 { grid-template-columns: repeat(3, 1fr); }
.cardgrid-4 { grid-template-columns: repeat(4, 1fr); }

.card {
  /* A fill, not just a hairline. Jessica, 2026-10-20: "can the background of
     these squares be a different colour to make them stand out more". They were
     transparent with a 1px line on a near-black page and barely read as tiles.
     --ink is the site's navy, one step up from the ground, so it lifts the card
     without introducing a colour the palette does not have. Applied to the
     component, not to Idaho: the same cards appear on every page. */
  background: var(--ink);
  border: 1px solid var(--line-strong);
  padding: calc(var(--gutter) * 0.9);
  display: flex;
  flex-direction: column;
  gap: 20px;
  transition: border-color 0.4s var(--ease-cine);
}
.card:hover { border-color: var(--line-strong); }
.card-eyebrow {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--red-text);
}
/* Numerals only. The signature 0.34em tracking makes "01" read as "0 1". */
.card-eyebrow-num { letter-spacing: 0.1em; }
.card h3,
.card h4 {
  font-style: italic;
  margin: 0;
}
.card p {
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--paper-dim);
  flex: 1;
}
.card-foot {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--paper-mute);
  padding-top: 16px;
  border-top: 1px solid var(--line);
}


/* ============================================================
   STEPS / STEP
   Numbered process list with large mono index numerals.
   From .cine-method / .cine-step, re-scaled to use mono for the
   index (the reference used serif there; mono reads clearer as
   a generic numbered-list index across many different pages).
   ============================================================ */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line-strong);
}
.step {
  padding: calc(var(--gutter) * 1.1) calc(var(--gutter) * 0.7);
  border-bottom: 1px solid var(--line-strong);
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.step-rail {
  display: flex;
  align-items: baseline;
  gap: 20px;
}
.step-num {
  font-family: var(--mono);
  font-size: var(--step-3);
  line-height: 0.85;
  color: var(--red-text);
  letter-spacing: -0.01em;
}
.step-label {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-mute);
}
.step h3,
.step h4 {
  font-style: italic;
  max-width: 14ch;
  margin: 0;
}
.step-desc {
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--paper-dim);
  flex: 1;
  max-width: 36ch;
}
.step-foot {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-0);
  line-height: 1.45;
  color: var(--brass);
  padding-top: 20px;
  border-top: 1px solid var(--line);
}


/* ============================================================
   QUOTE / QUOTEGRID
   .quote works standalone as a pull quote, or as a cell inside
   .quotegrid for a testimonial wall. From .cine-quote / VOICES.
   ============================================================ */
.quotegrid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: var(--gutter);
}
.quote {
  padding: calc(var(--gutter) * 0.85) calc(var(--gutter) * 0.55) calc(var(--gutter) * 0.55);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
  background: linear-gradient(180deg, rgba(232, 222, 197, 0.02), transparent);
  min-height: 380px;
}
/* Highlighted testimonial in a grid, or a standalone pull-quote. */
.quote-feature {
  background: linear-gradient(180deg, rgba(192, 31, 60, 0.08), rgba(192, 31, 60, 0.02));
  border-color: rgba(192, 31, 60, 0.3);
}
.quote-mark {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-4);
  line-height: 0.5;
  color: var(--red-text);
  height: 36px;
}
.quote-text {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-1);
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--paper);
  margin: 0;
  flex: 1;
}
.quote-feature .quote-text {
  font-size: var(--step-2);
  line-height: 1.18;
}
.quote-byline {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-mute);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  /* Row gap is tighter than column gap: when the role wraps to its own line
     it should read as a continuation, not a separate block. */
  gap: 6px 14px;
  line-height: 1.6;
}
.quote-byline-who { color: var(--paper); }
/* Hairline between name and role; flex:none stops it collapsing when wrapped. */
.quote-byline-sep { flex: none; width: 22px; height: 1px; background: currentColor; opacity: 0.4; align-self: center; }


/* ============================================================
   LOGOROW
   A row of partner/state logos, greyscale until hover.
   From .cine-coalition's grid, flattened into a simple row so
   it drops into any section rather than owning a full layout.
   ============================================================ */
.logorow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: calc(var(--gutter) * 1.2);
  padding-top: var(--gutter);
  border-top: 1px solid var(--line);
}
.logorow-item {
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.5;
  filter: grayscale(1);
  transition: opacity 0.4s var(--ease-cine), filter 0.4s var(--ease-cine);
}
.logorow-item:hover {
  opacity: 1;
  filter: grayscale(0);
}
.logorow-item img {
  height: 32px;
  width: auto;
}
/* Text-only fallback for a partner without a mark. */
.logorow-item-text {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-1);
  color: var(--paper-dim);
}


/* ============================================================
   STATROW / STAT
   Big serif figure over a mono label. Derived; the reference's
   yearline treatment (title-card-meta above) is the right
   flavour — large numeral, wide-tracked mono caption, hairline
   dashes between entries.
   ============================================================ */
.statrow {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(var(--gutter) * 1.4);
}
.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
}
.stat-figure {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-4);
  line-height: 0.9;
  letter-spacing: -0.02em;
  color: var(--paper);
}
.stat-figure .accent { color: var(--red-text); }
.stat-label {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-mute);
  /* Reserve the line so notes align across the row. One stat in the source
     ("100%") carries no label word, and without this its note rides up. */
  min-height: 1.4em;
}
/* Hairline separator between stat columns; omit on the last one by hand
   (author-placed markup, not :last-child, to stay Webflow-simple). */
/* The descriptive line under a stat's label. Kept separate from .stat-label
   because the source copy splits them, and one stat has no label word at all. */
.stat-note {
  margin-top: 10px;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--paper-dim);
  max-width: 28ch;
}

.stat-sep {
  width: 1px;
  align-self: stretch;
  background: var(--line-strong);
}


/* ============================================================
   CTA-BAND
   Full-width closing call to action. From .cine-cta, de-coupled
   from a fixed 100vh so it can close out a mid-page section too.
   ============================================================ */
.cta-band {
  position: relative;
  background: var(--black);
  border-top: 1px solid var(--line);
  overflow: hidden;
  text-align: center;
}
.cta-band-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(40% 50% at 50% 60%, rgba(36, 50, 133, 0.30), transparent 70%),
    radial-gradient(50% 50% at 50% 100%, rgba(192, 31, 60, 0.18), transparent 70%);
}
.cta-band-inner {
  position: relative;
  z-index: 2;
  max-width: var(--wrap);
  margin: 0 auto;
  /* Vertical padding belongs here rather than on .cta-band, because the band's
     glow is an inset overlay and must still reach the section's edges. Matches
     the rhythm .section sets, so a CTA sits in the page like any other block
     instead of running into the one above it. */
  padding: var(--section-pad) var(--gutter);
}
.cta-band-inner .eyebrow {
  justify-content: center;
  margin-bottom: var(--gutter);
}
.cta-band h2 {
  font-style: italic;
  max-width: 16ch;
  margin: 0 auto;
}
.cta-band-actions {
  display: flex;
  align-items: center;
  gap: 24px;
  justify-content: center;
  margin-top: calc(var(--gutter) * 1.3);
  flex-wrap: wrap;
}


/* ============================================================
   END-CARD
   Final full-height sign-off. From .cine-end.
   ============================================================ */
.end-card {
  padding: var(--section-pad) var(--gutter);
  background: var(--black);
  border-top: 1px solid var(--line);
  text-align: center;
}
.end-card-mark {
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-3);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--paper);
  margin: 0 0 32px;
}
.end-card-mark .accent { color: var(--red-text); }
.end-card-logo {
  display: block;
  width: clamp(280px, 42vw, 620px);
  height: auto;
  margin: 0 auto 36px;
}
.end-card-meta {
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--paper-mute);
  display: flex;
  justify-content: center;
  gap: 28px;
  flex-wrap: wrap;
}


/* ============================================================
   MEDIA-FIGURE
   An image or video with a mono caption and hairline frame.
   Not a distinct reference section — the hairline-frame-plus-
   mono-caption idiom is lifted from the reference's recurring
   eyebrow/rule detailing and applied to a plain media block.
   ============================================================ */
.media-figure {
  margin: 0;
}
.media-figure-frame {
  border: 1px solid var(--line-strong);
  overflow: hidden;
}
.media-figure-frame img,
.media-figure-frame video {
  width: 100%;
  height: auto;
  display: block;
}
.media-figure-caption {
  margin-top: 16px;
  font-family: var(--mono);
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-track);
  text-transform: uppercase;
  color: var(--paper-mute);
}


/* ============================================================
   SPLIT
   Standard two-column text-and-image section, used heavily
   across the existing site. Not in the reference — built to
   match its spacing and type rhythm. .split-reverse swaps which
   side the media sits on via `order`, so markup order (and
   thus reading order / a11y) never has to change.
   ============================================================ */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(var(--gutter) * 1.5);
  align-items: center;
}
.split-media {
  order: 1;
}
.split-text {
  order: 2;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.split-text .eyebrow { margin-bottom: 4px; }
.split-media img,
.split-media video {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--line-strong);
}
/* Swap sides on wide viewports only — mobile always stacks media first. */
.split-reverse .split-media { order: 2; }
.split-reverse .split-text { order: 1; }


/* ============================================================
   RESPONSIVE
   Matches Webflow's own breakpoints: 991 / 767 / 479.
   ============================================================ */
@media (max-width: 991px) {
  .cardgrid-3,
  .cardgrid-4 { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: 1fr; }
  .step { border-bottom: 1px solid var(--line); }
  .quotegrid { grid-template-columns: 1fr; }
  .scene-content-inner { max-width: 50ch; }
  .split { grid-template-columns: 1fr; }
  .split-media,
  .split-reverse .split-media { order: 1; }
  .split-text,
  .split-reverse .split-text { order: 2; }
}

@media (max-width: 767px) {
  .hero-cinematic-logo { width: min(72vw, 420px); }
  .title-card-statement { font-size: clamp(40px, 14vw, 96px); }
  .title-card-meta { gap: 14px; }
  .title-card-meta-dash { width: 32px; }
  .cardgrid,
  .cardgrid-2,
  .cardgrid-3,
  .cardgrid-4 { grid-template-columns: 1fr; }
  .scene-content { padding: calc(var(--section-pad) * 0.6) var(--gutter); }
  .scene-left .scene-content,
  .scene-right .scene-content {
    align-items: flex-start;
    justify-content: flex-end;
    text-align: left;
  }
  .scene-right .scene-content-inner { align-items: flex-start; }
  .statrow { gap: calc(var(--gutter) * 0.8); }
  .stat-sep { display: none; }
  .cta-band-actions { flex-direction: column; align-items: stretch; }
  .cta-band-actions .btn { justify-content: center; }
  .end-card-meta { gap: 14px; }
}

@media (max-width: 479px) {
  .hero-page-inner h1,
  .title-card-statement { font-size: clamp(34px, 15vw, 64px); }
  .scene-content-inner { max-width: 100%; }
  .quote { padding: var(--gutter) 20px 20px; min-height: 0; }
  .logorow { gap: var(--gutter); }
  .card { padding: calc(var(--gutter) * 0.6); }
}

/* =========================================================================
   COMPONENT LIBRARY — styled, demonstrated on _specimen.html, not currently
   used by any page.

   Title cards, pull quotes, logo rows, stat rows, and the two- and four-column
   card grids are all kept deliberately. They are what a new page gets built
   from, and check_unused.py lists them every run so they are not mistaken for
   residue and deleted. Open _specimen.html to see them drawn.

   If one is genuinely never wanted, delete it from here AND from the specimen
   in the same change, so the two never disagree about what exists.
   ========================================================================= */

/* ---- Video embed (facade) ----------------------------------------------
   A poster we host, with the Vimeo iframe injected only when someone clicks.

   Why a facade rather than an iframe in the markup: a bare Vimeo embed
   contacts a third party on every page load, for every visitor, whether or
   not they ever press play. That would undo the reason the fonts were
   self-hosted. It is also faster — the player is roughly a megabyte of
   script the page does not need until it is wanted.

   With JS off the trigger falls back to a plain link to the video, so the
   page is never a dead rectangle.
   ------------------------------------------------------------------------ */
.videoembed {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--black);
}
.videoembed-trigger {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.videoembed-poster {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.videoembed-play {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 84px;
  height: 84px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.45);
  transition: transform 0.25s ease, background-color 0.25s ease;
}
/* The triangle is drawn rather than an icon file: one less request, and it
   scales with the button instead of blurring. */
.videoembed-play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 54%;
  width: 0;
  height: 0;
  transform: translate(-50%, -50%);
  border-left: 26px solid var(--on-accent);
  border-top: 16px solid transparent;
  border-bottom: 16px solid transparent;
}
.videoembed-trigger:hover .videoembed-play { transform: translate(-50%, -50%) scale(1.08); }
.videoembed-trigger:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }
.videoembed-frame { width: 100%; height: 100%; border: 0; display: block; }

/* ---- Greeting video ----------------------------------------------------
   A decorative silent loop. The portrait is roughly square, so it is centred
   at a readable size rather than stretched across the measure. */
/* Shrink-wrapped to the video and centred, rather than a full-width flex row.
   The pause control is positioned against this box, so if it spanned the whole
   measure the button would float off to the right of the video it controls. */
.greetingvideo {
  position: relative;
  width: min(520px, 100%);
  margin-inline: auto;
}
.greetingvideo-media {
  width: 100%;
  height: auto;
  display: block;
}
/* The video is a light image on a dark page, so the control needs to sit on
   the video rather than beside it to stay legible. */
.greetingvideo .motiontoggle {
  right: 12px;
  bottom: 12px;
}
/* Someone who has asked for less motion gets the poster frame instead of a
   loop running behind their reading. Pausing beats hiding: the image still
   carries the meaning. */
@media (prefers-reduced-motion: reduce) {
  .greetingvideo-media { animation: none; }
}

/* Card icon. Restored from the original about page, where each of these six
   cards carried one; the discs were Istation navy and all but vanished on this
   ground, so they were recoloured to the brand crimson. The glyph stays white,
   a pairing already verified at 6.0 contrast. */
.card-icon {
  width: 52px;
  height: 52px;
  display: block;
  /* The card is a flex column with a 20px gap; the icon wants to sit closer to
     its heading than the gap allows. */
  margin-bottom: -8px;
}

/* ---- Home page, after Billy's review (2026-10-09) ------------------------ */

/* #3 — "the font in this paragraph is different". Scene paragraphs are set in
   the display serif as cinematic pull quotes, which is right on Fireside. The
   home page's one is now a statistic and an argument, which is body copy, so
   it takes the body face. Scoped to .lede: only the home page's scene
   paragraph carries it, so Fireside's quotes keep the serif. */
.scene-content-inner p.lede {
  font-family: var(--sans);
  font-size: var(--step-1);
  line-height: 1.55;
}

/* #2 — the citation under the NAEP statistic. Small and quiet: it is there to
   be checkable, not to compete with the claim. */
.scene-source {
  margin-top: 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
}
.scene-content-inner .scene-source { font-family: var(--mono); font-size: 11px; }
.scene-source a {
  color: var(--paper-mute);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.scene-source a:hover { color: var(--paper); }

/* #4/#5 — the two standards benefits, stacked beside the teacher dashboard.
   Not bordered cards: beside a dense screenshot, two more boxes would make
   three competing frames. A hairline between them does the separating. */
.benefits { display: flex; flex-direction: column; gap: 28px; }
.benefit h3 { font-style: italic; margin: 0 0 8px; }
.benefit p {
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--paper-dim);
}
.benefit + .benefit { padding-top: 28px; border-top: 1px solid var(--line); }

/* Jessica, 2026-10-20 (Idaho, Training, About): "this subheading should be
   centred". The band centres its text, and the heading block is centred with
   margin: auto, but the lede is a narrower block with no auto margins — so its
   text was centred inside a box that sat 195px left of the band's centre, on
   every page that has one. Measured, then fixed once for all of them. */
.cta-band-inner .lede { margin-left: auto; margin-right: auto; }
