/* =========================================================================
   Schoolio — Rails-specific components (flashes, errors, skip-link,
   page shell layout). Design tokens come from tokens.css.
   ========================================================================= */

/* Skip link for keyboard/screen-reader users ------------------------------ */
.skip-link {
  position: absolute;
  left: -999px;
  top: auto;
  padding: .6rem 1rem;
  background: var(--ink);
  color: var(--paper);
  font: var(--fw-600) var(--fs-16) var(--font-educating);
  z-index: 9999;
}
.skip-link:focus { left: 1rem; top: 1rem; outline: 3px solid var(--highlighter); }

/* Page shell ------------------------------------------------------------- */
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-educating);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  margin: 0;
}
main { min-height: 60vh; }

/* Header / Footer -------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
}
/* Brand row — wordmark left, the quiet "About" utility link right. Sits on
   its own line above the nav so the three topic menus get the full width to
   themselves (and never share the mobile line with the logo). */
.site-header__brand {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  max-width: var(--container-max); margin: 0 auto;
  padding: .85rem var(--container-gutter) .6rem;
}
.site-header__about {
  font-family: var(--font-educating);
  font-size: var(--fs-14);
  font-weight: 600;
  color: #7c7263;                 /* quiet, secondary — not a peer of the menus */
  text-decoration: none;
  letter-spacing: .02em;
  white-space: nowrap;
  padding: .25rem .1rem;
}
.site-header__about:hover,
.site-header__about:focus-visible,
.site-header__about.is-active { color: var(--ink-blue); }

/* Right-hand cluster of the brand row: the "About" link and — on phones —
   the hamburger button beside it. */
.site-header__brand-actions {
  display: flex;
  align-items: center;
  gap: .75rem;
}

/* Hamburger — hidden on desktop, revealed at ≤640px (see the mobile block).
   Three ink bars drawn from the inner span + its ::before/::after; they
   collapse into an "×" when .site-header.is-menu-open. */
.site-header__burger {
  display: none;            /* desktop: no hamburger */
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 1px solid rgba(28, 28, 28, .18);
  border-radius: var(--radius-md, 8px);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.site-header__burger:hover,
.site-header__burger:focus-visible { border-color: var(--ink-blue); color: var(--ink-blue); }
.site-header__burger-bars,
.site-header__burger-bars::before,
.site-header__burger-bars::after {
  content: "";
  display: block;
  width: 1.25rem;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform .18s ease, opacity .18s ease;
}
.site-header__burger-bars { position: relative; }
.site-header__burger-bars::before { position: absolute; top: -6px; left: 0; }
.site-header__burger-bars::after  { position: absolute; top:  6px; left: 0; }
/* Open state → morph the three bars into an "×". */
.site-header.is-menu-open .site-header__burger-bars { background: transparent; }
.site-header.is-menu-open .site-header__burger-bars::before { top: 0; transform: rotate(45deg); }
.site-header.is-menu-open .site-header__burger-bars::after  { top: 0; transform: rotate(-45deg); }

/* Nav row — now holds ONLY the three topic menus, left-aligned under the
   wordmark, with a hairline separating it from the brand row above. */
.site-header__inner {
  display: flex; align-items: center;
  gap: 1.5rem;
  max-width: var(--container-max); margin: 0 auto;
  padding: .5rem var(--container-gutter) .75rem;
  border-top: 1px solid rgba(28, 28, 28, .10);
}
.site-header__logo {
  display: flex; align-items: center; gap: .75rem;
  text-decoration: none; color: var(--ink);
}
.site-header__logo img { height: 52px; width: auto; }
.site-header__logo .wordmark {
  font: var(--fw-700) var(--fs-22)/1 var(--font-display);
  letter-spacing: .02em;
}

/*
 * The `.nav` rule in tokens.css was designed for a standalone, full-width
 * header in the style guide. Inside `.site-header__inner` we need to neutralize
 * its padding, border, and background, and give the flex children real spacing
 * (space-between does nothing on a shrink-to-fit flex item).
 */
.site-header__inner .nav {
  padding: 0;
  background: transparent;
  border-bottom: 0;
  justify-content: flex-start;
  gap: 1.35rem;
  flex-wrap: nowrap;   /* nav has its own row now — keep all three on one line */
}
.site-header__inner .nav a {
  padding: .25rem .1rem;
}

/* Dropdown nav groups -----------------------------------------------------
   A NavItem with children renders as <details><summary>…</summary><ul>…</ul></details>.
   Default <details> styles are ugly; we hide the marker and roll our own. */
.site-header__inner .nav .nav-group {
  position: relative;
  display: inline-block;
}
.site-header__inner .nav .nav-group__label {
  list-style: none;        /* Firefox marker */
  cursor: pointer;
  user-select: none;
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  padding: .25rem .1rem;
  color: var(--ink);
  font: inherit;
}
.site-header__inner .nav .nav-group__label::-webkit-details-marker { display: none; }
.site-header__inner .nav .nav-group__caret {
  font-size: .8em;
  opacity: .6;
  transition: transform .12s ease;
}
.site-header__inner .nav .nav-group[open] .nav-group__caret { transform: rotate(180deg); }

/* Lead arrow — the ink-blue chevron carried by every top-level menu except
   the first, so the desktop row reads as a sequence: More than hope ›
   Science confirms › Choose your school system › Services. Rendered by
   ApplicationHelper#nav_label from the NavItem::LEAD_ARROW_PREFIX marker.
   Nudges right on hover. */
.site-header__inner .nav .nav-lead {
  display: inline-flex;
  align-items: center;
  color: var(--lo-color-2);
  transition: transform .16s ease;
}
.site-header__inner .nav .nav-lead__icon { display: block; }
.site-header__inner .nav .nav-group__label:hover .nav-lead,
.site-header__inner .nav .nav-group__label:focus-visible .nav-lead,
.site-header__inner .nav a:hover .nav-lead {
  transform: translateX(2px);
}

/* Inline ink-blue bold accent inside a top-level nav label (the "your" in
   "Choose your school system"). Rendered by ApplicationHelper#nav_label from
   the `**…**` marker. */
.site-header__inner .nav .nav-accent {
  color: var(--ink-blue);
  font-weight: 700;
}

.site-header__inner .nav .nav-group__menu {
  position: absolute;
  top: 100%;
  margin-top: .35rem;          /* visual gap below the label */
  left: 0;                     /* nav is left-aligned now — open rightward so
                                  the leftmost menu doesn't spill off-screen */
  min-width: 18rem;
  padding: .75rem 0;
  list-style: none;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px -16px rgba(28, 28, 28, .35);
  z-index: 50;
}
/* Invisible bridge across the visual gap above the menu — without it
   the cursor briefly leaves :hover when crossing from the label down
   into the menu, and the dropdown collapses. */
.site-header__inner .nav .nav-group__menu::before {
  content: "";
  position: absolute;
  top: -.35rem;
  left: 0;
  right: 0;
  height: .35rem;
}
.site-header__inner .nav .nav-group__menu a {
  display: block;
  padding: .35rem 1rem;
  text-decoration: none;
  color: var(--ink);
}
.site-header__inner .nav .nav-group__menu a:hover,
.site-header__inner .nav .nav-group__menu a:focus {
  background: var(--paper-2, #F3ECD6);
}
/* Current page WITHIN the dropdown. The deep link for the page you're on
   gets the same ink-blue underline as the top-level section indicator. The
   extra specificity here is required to beat the `.nav-group__menu a
   { text-decoration: none }` reset above and the `.nav-group__sublist a`
   reset below — otherwise the active link renders with no underline. */
.site-header__inner .nav .nav-group__menu a.is-active {
  color: var(--ink-blue);
  text-decoration: underline;
  text-decoration-color: var(--ink-blue);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

/* Second-level grouping inside the dropdown (e.g. "Team", "What science
   says is the Right Problem"). The label is non-clickable when its path is
   "#", or a link when it carries its own path; children indent slightly. */
.site-header__inner .nav .nav-group__section {
  padding: .35rem 0;
}
.site-header__inner .nav .nav-group__section + .nav-group__section {
  border-top: 1px solid var(--rule);
  margin-top: .35rem;
  padding-top: .6rem;
}
.site-header__inner .nav .nav-group__section-label {
  display: block;
  padding: 0 1rem .15rem;
  font: var(--fw-600, 600) var(--fs-14, .875rem) var(--font-display, "Source Serif 4", serif);
  letter-spacing: .01em;
  opacity: .65;
  text-transform: uppercase;
  font-size: .72rem;
}
/* When a section header carries its own path it is a real landing page, not
   just a grouping label — promote it so it reads as a confident doorway:
   mixed-case, larger, full-strength, in the display serif. The quiet
   uppercase whisper above is reserved for non-clickable grouping labels
   (e.g. "Team"), so the hierarchy sharpens instead of flattening. */
.site-header__inner .nav a.nav-group__section-label {
  color: var(--ink);
  text-decoration: none;
  text-transform: none;
  letter-spacing: normal;
  opacity: 1;
  /* A touch larger than 1rem so the top-level "doorways" read confident and
     even across every header menu. The Beautiful Problem's small-caps label
     is nudged just above this to stay optically level (see below). */
  font-size: 1.06rem;
  padding-top: .1rem;
  padding-bottom: .2rem;
}
.site-header__inner .nav a.nav-group__section-label:hover,
.site-header__inner .nav a.nav-group__section-label:focus-visible {
  opacity: 1;
  text-decoration: underline;
}
/* Each menu's "front door" — its primary landing page — carries a standing
   "→" so it reads as *the* place to start: "Hope — in seconds" (More than
   hope), "How to choose?" (If you choose), and "Choosing an implementation"
   (To implement). nowrap keeps the arrow on the same line as its label (the
   long "Choosing an implementation" would otherwise wrap the → onto its own
   line); inline-block keeps the hover underline from running under it. */
.site-header__inner .nav a.nav-group__section-label[href="/more-than-hope/hope-in-a-few-seconds"],
.site-header__inner .nav a.nav-group__section-label[href="/two-choices-in-depth/how-to-choose"],
.site-header__inner .nav a.nav-group__section-label[href="/services/choosing-an-implementation"] {
  white-space: nowrap;
}
.site-header__inner .nav a.nav-group__section-label[href="/more-than-hope/hope-in-a-few-seconds"]::after,
.site-header__inner .nav a.nav-group__section-label[href="/two-choices-in-depth/how-to-choose"]::after,
.site-header__inner .nav a.nav-group__section-label[href="/services/choosing-an-implementation"]::after {
  content: "\2192";            /* → */
  display: inline-block;
  margin-left: .4em;
  opacity: .9;
}
/* "The Beautiful Problem" is the pivot of the whole argument, so it earns
   its named-idea signature even here in the menu: small caps with the ✦
   sparkle mark leading it. Kept in the nav's normal ink (not the terracotta
   used in page content) so the chrome stays quieter than the copy. */
.site-header__inner .nav a.nav-group__section-label[href="/more-than-hope/the-beautiful-problem"] {
  color: var(--ink);
  font-variant-caps: small-caps;
  letter-spacing: .03em;
  /* Small caps read optically a hair smaller than the mixed-case siblings at
     the same size, so sit just above the shared 1.06rem doorway size to stay
     level with them — distinguished by treatment (small caps + ✦), not size. */
  font-size: 1.08rem;
}
.site-header__inner .nav a.nav-group__section-label[href="/more-than-hope/the-beautiful-problem"]::before {
  content: "\2726";                                  /* ✦ */
  font-variant-caps: normal;
  font-weight: 400;
  font-size: .82em;
  margin-right: .34em;
  vertical-align: .04em;
  display: inline-block;
}
/* "The Beautiful Problem" carries a quiet, non-bold second line naming what
   solves it. Rendered as generated content (there's no subtitle field on
   NavItem) on its own line, lighter and smaller than the label. The extra
   margin below sets it apart from the "Eva Fugitt" sub-link that follows.
   text-decoration:none keeps the label's hover underline off the subtitle.
   color/font-variant are reset so it stays quiet ink prose rather than
   inheriting the label's terracotta small caps. */
.site-header__inner .nav a.nav-group__section-label[href="/more-than-hope/the-beautiful-problem"]::after {
  content: "\2014 solved by The Lead Out Method";   /* — solved by … */
  display: block;
  margin-top: .1rem;
  margin-bottom: .55rem;
  color: var(--ink);
  font-variant-caps: normal;
  font-weight: 400;
  font-size: .8rem;
  letter-spacing: .01em;
  opacity: .68;
  text-decoration: none;
}
/* The "Science confirms" doorway reads as two lines within a single link: the
   mixed-case label on top, and beneath it — indented to line up with the
   author sub-links — the named idea it proves out, "The Beautiful Problem", in
   that idea's standard small-caps ✦ signature. Rendered as generated content
   (there's no subtitle field on NavItem), mirroring the Beautiful Problem
   doorway's own subtitle. white-space:normal lets the label wrap to two lines;
   text-decoration:none keeps the label's hover underline off the second line. */
.site-header__inner .nav a.nav-group__section-label[href="/science-confirms"] {
  white-space: normal;
}
.site-header__inner .nav a.nav-group__section-label[href="/science-confirms"]::after {
  content: "\2726 The Beautiful Problem";   /* ✦ The Beautiful Problem */
  display: block;
  margin-top: .12rem;
  margin-left: .5rem;            /* aligns with the .nav-group__sublist links */
  color: var(--ink);
  font-variant-caps: small-caps;
  font-weight: 400;
  letter-spacing: .03em;
  font-size: .95rem;
  opacity: .9;
  text-decoration: none;
}
.site-header__inner .nav .nav-group__sublist {
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-header__inner .nav .nav-group__sublist a {
  padding-left: 1.5rem;
}

/* Linked variant — About is a real link with a hover-revealed dropdown
   beside it AND a separate toggle button so touch users can open the
   dropdown without giving up the link's own tap target. */
.site-header__inner .nav .nav-group--linked {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0;                       /* button supplies its own breathing room */
  padding: .25rem .1rem;
}
.site-header__inner .nav .nav-group--linked .nav-group__label {
  /* Override the .nav a padding above so the link sits flush with the
     toggle button in the same baseline. */
  padding: 0;
}
/* The tap-to-toggle button beside the link. Sized at 44×44 minimum for
   touch (Apple/Google guidelines) so the caret has a real target on
   phones. On desktop the hover behavior still works without ever
   needing to click — the button is just a redundant affordance. */
.site-header__inner .nav .nav-group--linked .nav-group__toggle {
  background: transparent;
  border: 0;
  margin: 0;
  padding: .25rem .35rem;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  -webkit-tap-highlight-color: transparent;
}
.site-header__inner .nav .nav-group--linked .nav-group__toggle:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Hidden by default; the JS controller flips .is-open on tap, and the
   hover media query below also reveals it on hover/focus. */
.site-header__inner .nav .nav-group--linked > .nav-group__menu {
  display: none;
}
.site-header__inner .nav .nav-group--linked.is-open > .nav-group__menu {
  display: block;
}
.site-header__inner .nav .nav-group--linked.is-open .nav-group__caret {
  transform: rotate(180deg);
}

/* Hover-to-open on devices that actually have hover. Touch devices get
   tap-to-toggle via <details> on the non-linked variant. */
@media (hover: hover) and (pointer: fine) {
  .site-header__inner .nav .nav-group:hover > .nav-group__menu,
  .site-header__inner .nav .nav-group:focus-within > .nav-group__menu {
    display: block;
  }
  .site-header__inner .nav details.nav-group:not([open]) > .nav-group__menu {
    display: none;
  }
  .site-header__inner .nav .nav-group:hover .nav-group__caret,
  .site-header__inner .nav .nav-group:focus-within .nav-group__caret {
    transform: rotate(180deg);
  }
}

/* Mobile / narrow viewports — anchor every dropdown to the full width
   of the header instead of the small .nav-group wrapper, otherwise the
   panel (min-width 18rem, right:0) extends off the LEFT edge of the
   screen when its parent sits near the left of the (now left-aligned,
   wrapped) nav bar. Applies to both the <details> variant (About,
   Guides) and the .nav-group--linked variant. The wrappers go
   position:static on small screens so the absolute menu picks up
   .site-header__inner as its positioning context. */
@media (max-width: 720px) {
  .site-header__inner {
    position: relative;
  }
  .site-header__inner .nav .nav-group,
  .site-header__inner .nav .nav-group--linked {
    position: static;
  }
  .site-header__inner .nav .nav-group > .nav-group__menu,
  .site-header__inner .nav .nav-group--linked > .nav-group__menu {
    top: 100%;
    margin-top: .35rem;
    left: var(--container-gutter, 1rem);
    right: var(--container-gutter, 1rem);
    min-width: 0;
    max-width: none;
    width: auto;
    /* Distinguish the panel from the header's paper bg so the
       dropdown reads as a discrete surface on a phone where it
       spans the full width. Slightly warmer paper + a heavier ink
       border + a deeper shadow do the work. */
    background: var(--paper-2, #F3ECD6);
    border: 1px solid var(--ink);
    box-shadow: 0 16px 40px -18px rgba(28, 28, 28, .55);
  }
  /* Hover bridge is unnecessary on touch (no hover) and would land in
     the wrong place once the anchor changes. */
  .site-header__inner .nav .nav-group > .nav-group__menu::before,
  .site-header__inner .nav .nav-group--linked > .nav-group__menu::before {
    display: none;
  }
  /* The front-door "→" reads tiny on a phone; scale it up so it stays a
     clear "start here" cue on the full-width mobile panel. */
  .site-header__inner .nav a.nav-group__section-label[href="/more-than-hope/hope-in-a-few-seconds"]::after,
  .site-header__inner .nav a.nav-group__section-label[href="/two-choices-in-depth/how-to-choose"]::after,
  .site-header__inner .nav a.nav-group__section-label[href="/services/choosing-an-implementation"]::after {
    font-size: 1.35em;
    vertical-align: -.06em;
  }
}

/* Phones — the four topic menus no longer fit on one line, so they collapse
   behind the hamburger to the right of "About". Tapping it drops the nav down
   as a full-width, in-flow accordion: each top-level menu is a row whose
   sub-items expand below it (native <details>), instead of an absolute
   overlay. */
@media (max-width: 640px) {
  /* Trim the header's side padding so the drawer has more room. */
  .site-header__brand { padding-left: 16px; padding-right: 16px; }

  /* Reveal the hamburger; hide the nav panel until the menu is toggled. */
  .site-header__burger { display: inline-flex; }
  .site-header__inner {
    display: none;
    padding: .25rem 16px .85rem;
  }
  .site-header.is-menu-open .site-header__inner { display: block; }

  /* Stack the top-level menus vertically with hairline separators. */
  .site-header__inner .nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    width: 100%;
  }
  .site-header__inner .nav > * { border-top: 1px solid rgba(28, 28, 28, .10); }
  .site-header__inner .nav > *:first-child { border-top: 0; }

  /* Full-width menu rows; caret pushed to the trailing edge. */
  .site-header__inner .nav .nav-group,
  .site-header__inner .nav .nav-group--linked { display: block; width: 100%; }
  .site-header__inner .nav .nav-group__label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    padding: .7rem .1rem;
    font-size: 1.05rem;
    white-space: normal;
  }
  .site-header__inner .nav > a {           /* childless top-level links */
    display: block;
    padding: .7rem .1rem;
    font-size: 1.05rem;
  }
  .site-header__inner .nav .nav-group__caret { font-size: .9em; opacity: .7; }

  /* Drop the lead arrow in the drawer. Along the desktop row the chevrons sit
     between the menus and read as "then", which is the whole point of them.
     Stacked vertically that sequence is already carried by the order of the
     rows, and the chevron instead reads as a control — every row here has a ▾
     on the trailing edge, so a second chevron on the leading edge of all but
     the first row looks like an expander missing from that one.

     Hidden here rather than unset at the source: the ═► markers in nav.rake
     still do their job everywhere there is room for them to be legible. */
  .site-header__inner .nav .nav-lead { display: none; }

  /* Sub-menu flows in the document (accordion) instead of the ≤720px absolute
     overlay — same selector/specificity so this wins the cascade below it. */
  .site-header__inner .nav .nav-group > .nav-group__menu,
  .site-header__inner .nav .nav-group--linked > .nav-group__menu {
    position: static;
    top: auto; left: auto; right: auto;
    margin: 0 0 .5rem;
    padding: .1rem 0 .35rem .85rem;
    min-width: 0; max-width: none; width: auto;
    background: transparent;
    border: 0;
    box-shadow: none;
  }
  /* An expanded <details> shows its panel regardless of the hover-media rule. */
  .site-header__inner .nav details.nav-group[open] > .nav-group__menu { display: block; }
}

.site-footer {
  background: var(--ink);
  color: var(--paper);
  margin-top: 5rem;
  padding: 2.5rem var(--container-gutter);
}
.site-footer__inner {
  max-width: var(--container-max); margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 2rem; justify-content: space-between;
}
/* Footer links (brand wordmark + nav) read clean at rest — position and
   grouping signal they're clickable — and reveal an underline on hover/focus
   for affordance and keyboard visibility. Share links manage their own. */
.site-footer a { color: var(--paper); text-decoration: none; }
.site-footer nav a:hover,
.site-footer nav a:focus-visible,
.site-footer a.site-footer__brand:hover,
.site-footer a.site-footer__brand:focus-visible { text-decoration: underline; text-decoration-color: var(--highlighter); }
.site-footer small { color: color-mix(in srgb, var(--paper) 70%, transparent); }

/* Share row — centered, directly beneath the main footer row. */
.site-footer__share {
  max-width: var(--container-max);
  margin: .4rem auto 0;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .6rem 1.15rem;
  padding-top: .4rem;
  border-top: 1px solid color-mix(in srgb, var(--paper) 15%, transparent);
}
.site-footer__share-label {
  font: var(--fw-600) var(--fs-14) var(--font-educating);
  color: color-mix(in srgb, var(--paper) 70%, transparent);
  letter-spacing: .02em;
}
.site-footer .share-link {
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--paper); text-decoration: none;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: var(--fw-600) var(--fs-14) var(--font-educating);
  line-height: 1;
}
/* The rule above is a class selector and so outranks the browser's own
 * `[hidden] { display: none }`, which is an attribute selector. Without this
 * line the hidden attribute on the "Share…" button does nothing at all and the
 * button appears on desktop Linux and Firefox, where navigator.share does not
 * exist — visible, hoverable, and inert. Any `hidden` in this row needs to win
 * here, not just be set. */
.site-footer .share-link[hidden] { display: none; }
.site-footer .share-link svg { width: 18px; height: 18px; fill: currentColor; flex: none; }
.site-footer .share-link:hover .share-link__text,
.site-footer .share-link:focus-visible .share-link__text {
  text-decoration: underline; text-decoration-color: var(--highlighter);
}
.site-footer .share-link--copy.is-copied { color: var(--highlighter); }

/* Flash messages --------------------------------------------------------- */
.flash {
  max-width: var(--container-max); margin: 1rem auto;
  padding: .85rem 1rem; border-radius: var(--radius-md);
  font: var(--fw-600) var(--fs-16) var(--font-educating);
}
.flash--notice { background: color-mix(in srgb, var(--chalkboard) 18%, var(--paper)); color: var(--chalkboard-ink); border: 1px solid var(--chalkboard); }
.flash--alert  { background: color-mix(in srgb, var(--rose) 22%, var(--paper)); color: color-mix(in srgb, var(--rose) 80%, black); border: 1px solid var(--rose); }

/* Error summary in forms ------------------------------------------------- */
.error-summary {
  background: color-mix(in srgb, var(--rose) 18%, var(--paper));
  border-left: 4px solid var(--rose);
  padding: 1rem 1.25rem; border-radius: var(--radius-md);
  margin-bottom: 1.25rem;
}
.error-summary h3 { margin: 0 0 .5rem; font: var(--fw-700) var(--fs-18) var(--font-display); }
.field--invalid .field-input,
.field--invalid .field-textarea { border-color: var(--rose); outline-color: var(--rose); }
.field-error { color: color-mix(in srgb, var(--rose) 80%, black); font-size: var(--fs-14); margin-top: .25rem; }

/* Paper-2 prose bands (guide/choice pages) — hairline seams top & bottom so
   the band reads as a deliberate standout zone rather than a faint accident,
   matching the home page's .lo-sec[data-bg="paper-2"] treatment. */
.paragraph-part--paper-2 {
  box-shadow: inset 0 1px 0 rgba(28, 28, 28, .14),
              inset 0 -1px 0 rgba(28, 28, 28, .14);
}

/* Admin bridge (minimal — enough to feel like an admin, not a public page) */
.admin-body { background: color-mix(in srgb, var(--paper) 85%, var(--chalkboard) 15%); }
.admin-shell {
  display: grid; grid-template-columns: 220px 1fr; min-height: 100vh;
}
.admin-sidebar {
  background: var(--ink); color: var(--paper);
  padding: 1.25rem 1rem; position: sticky; top: 0; height: 100vh;
}
.admin-sidebar h1 { font: var(--fw-700) var(--fs-22)/1 var(--font-display); margin: 0 0 1rem; }
.admin-sidebar ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.admin-sidebar a {
  display: block; color: var(--paper); text-decoration: none;
  padding: .45rem .6rem; border-radius: var(--radius-sm);
}
.admin-sidebar a:hover { background: color-mix(in srgb, var(--paper) 12%, transparent); }
.admin-sidebar a.is-active { background: var(--highlighter-soft); color: var(--ink); }

.admin-main { padding: 2rem; max-width: 1100px; }
.admin-main h1 { font: var(--fw-700) var(--fs-32) var(--font-display); margin: 0 0 1rem; }
.admin-main table { width: 100%; border-collapse: collapse; background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-md); overflow: hidden; }
.admin-main th, .admin-main td { text-align: left; padding: .6rem .85rem; border-bottom: 1px solid var(--rule); }
.admin-main th { background: color-mix(in srgb, var(--paper) 92%, var(--ink) 8%); font-weight: var(--fw-700); }
.admin-main .actions { display: flex; gap: .5rem; }

/* Guides prev/next pager -------------------------------------------------- *
 * Rendered at the bottom of every Guides page via app/views/pages/_guide_pager.
 * Source of truth for the order is the nav menu (lib/tasks/nav.rake) — the
 * GuidesHelper walks the "Guides" header dropdown and skips placeholder ("#")
 * entries.
 * --------------------------------------------------------------------- */
.guide-pager {
  width: min(100%, var(--container-max));
  margin: clamp(48px, 6vw, 96px) auto 0;
  padding: clamp(28px, 3vw, 40px) var(--gutter, 1.25rem);
  border-top: 1px solid color-mix(in srgb, var(--ink) 18%, transparent);
  display: flex;
  justify-content: space-between;
  align-items: stretch;
  gap: 1.5rem;
}
/* Inline variant — the pager placed directly below a video sits closer to
   it than the full bottom-of-page pager. */
.guide-pager--inline {
  margin-top: clamp(20px, 2.5vw, 36px);
}
.guide-pager__link {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  text-decoration: none;
  color: var(--ink);
  max-width: 28rem;
  /* Big tappable target on mobile, but no visual chrome unless hovered. */
  padding: 0.25rem 0;
  border-bottom: 1px solid transparent;
  transition: border-color 120ms ease, color 120ms ease;
}
.guide-pager__link--next {
  text-align: right;
  align-items: flex-end;
}
/* At the ends of the chain only one link renders. Keep a lone "next" link
   (first page — no "previous") pinned to the right so the arrow still reads
   correctly against the right edge. */
.guide-pager__link--next:first-child {
  margin-left: auto;
}
.guide-pager__link:hover,
.guide-pager__link:focus-visible {
  color: var(--link, var(--ink-blue));
  border-bottom-color: var(--link-underline, currentColor);
}
.guide-pager__link:focus-visible {
  outline: 2px solid var(--focus-ring, var(--ink-blue));
  outline-offset: 4px;
}
.guide-pager__direction {
  font-family: var(--font-mono, "IBM Plex Mono", monospace);
  font-size: var(--fs-12, 0.75rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
}
.guide-pager__title {
  font-family: var(--font-display, "Source Serif 4", Georgia, serif);
  font-weight: 500;
  font-size: clamp(1.125rem, 2vw, 1.5rem);
  line-height: 1.2;
  letter-spacing: -.01em;
}
/* The Beautiful Problem keeps its named-idea signature in the pager too —
   small caps so it reads as a titled concept wherever it appears, but in the
   pager's normal ink (not the terracotta used in page content) so the chrome
   stays quiet. The ✦ sparkle is held back here (unlike the menu and page
   heroes) so the prev/next link set keeps its uniform rhythm rather than one
   link looking like a highlighted or active state. */
.guide-pager__link[href="/more-than-hope/the-beautiful-problem"] .guide-pager__title {
  color: var(--ink);
  font-variant-caps: small-caps;
  letter-spacing: .03em;
}

@media (max-width: 600px) {
  /* Keep prev / next side by side on small screens rather than stacking.
     Each link takes half the row and is allowed to shrink (min-width: 0)
     so long titles wrap within their column instead of forcing a stack. */
  .guide-pager {
    gap: 1rem;
  }
  .guide-pager__link {
    flex: 1 1 0;
    min-width: 0;
  }
  .guide-pager__title {
    font-size: 1rem;
  }
}

/* Lead statement --------------------------------------------------------- */
/* An oversized standout line (e.g. the "already been done" promise that
   sits above the Hope video). Larger than body prose, and its bold words
   pick up the terracotta accent for extra emphasis. */
.lead-statement {
  font-size: clamp(1.5rem, 3.4vw, 2.125rem);
  line-height: 1.3;
  margin: 0;
}
/* Slightly bump an emphasized word (e.g. an italic "not") a touch above the
   surrounding text so it lands harder. Relative em keeps it in scale. */
.emph-up {
  font-size: 1.12em;
}
.lead-statement strong {
  color: var(--terracotta);
}
/* Explicit accent override — lets a bold phrase inside a lead statement take
   the ink-blue accent instead of the default terracotta (e.g. an emphasized
   ink-blue question). */
.lead-statement strong.lo-accent {
  color: var(--ink-blue);
}
/* Narrow variant — pulls the left/right margins in for a tighter column. */
.lead-statement--narrow {
  max-width: 34rem;
  margin-left: auto;
  margin-right: auto;
}
/* Indent variant — nudges a single statement line in to set it apart. */
.lead-statement--indent {
  padding-left: 1.5rem;
}
/* Space-after variant — adds a little breathing room beneath a statement
   line so the one that follows reads as a separate beat (used to give the
   Beautiful Problem statement air above and below on the-beautiful-problem). */
.lead-statement--space-after {
  margin-bottom: .55em;
}
/* (A --tight variant lived here. Its only user was the old two-column
   Beautiful Problem question, which .bp-statement replaced; verified unused in
   both the local and production DBs before removal.) */

/* Beat heading ----------------------------------------------------------- */
/* A compact display heading that marks a turn in the argument mid-section
   (e.g. "Bottom line"), set off from the prose above it by a hairline rule
   so it reads as a distinct concluding beat rather than another paragraph. */
.prose .beat-head {
  font-family: var(--font-display);
  font-weight: 600;
  /* Matches the "modest" section-title size so this beat heading reads as a
     peer of the section's own heading above it. */
  font-size: clamp(1.5rem, 3vw, var(--fs-30));
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: var(--sp-6) 0 var(--sp-3);
  padding-top: var(--sp-4);
  border-top: 1px solid rgba(28, 28, 28, 0.18);
}

/* Problem-provocation build (Lead Out Method) ---------------------------- */
/* Turns the "we need a new problem" beat into a short rhetorical ladder:
   two bold display statements — the second (the thesis) largest and ink-blue —
   each followed by smaller supporting lines, so the block reads as a build
   with clear hierarchy rather than a wall of same-size statements. */
.prose .problem-provoke {
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid rgba(28, 28, 28, 0.18);
}
.prose .problem-provoke__major {
  font-family: var(--font-display);
  /* Matches the "modest" section-title scale (weight + size) so the three
     major statements read as peers of the heading above. */
  font-weight: 600;
  font-size: clamp(1.5rem, 3vw, var(--fs-30));
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
.prose .problem-provoke__peak {
  /* No size bump — sits at the same title scale as the other majors,
     just with extra breathing room above. */
  margin-top: 1.5rem;
}
.prose .problem-provoke__sub {
  font-size: clamp(1.2rem, 2.6vw, 1.5rem);
  line-height: 1.4;
  /* Full ink at normal weight — matches the .impossible-statement scale so
     the supporting questions read as peers of the section's opening claim. */
  color: var(--ink);
  margin: .3rem 0 0;
  max-width: 40rem;
}
/* The supporting questions as a bulleted list — same scale/colour as the
   __sub lines above, just presented as two bullets. */
.prose .problem-provoke__list {
  font-size: clamp(1.2rem, 2.6vw, 1.5rem);
  line-height: 1.4;
  color: var(--ink);
  max-width: 40rem;
  margin: .6rem 0 0;
  padding-left: 1.3em;
}
.prose .problem-provoke__list > li + li {
  margin-top: .5rem;
}
/* The section's opening claim reads a touch smaller than a full lead
   statement, and shares its size with the provocation's supporting lines so
   all the section's context text sits at one scale below the bold headers. */
.prose .impossible-statement {
  font-size: clamp(1.2rem, 2.6vw, 1.5rem);
  line-height: 1.4;
  margin: 0 0 .35rem;
  max-width: 40rem;
}

/* Beautiful-Problem callout — frames the two-line statement in a soft
   paper-2 panel so it reads as a discrete "here's the problem" block rather
   than relying on whitespace alone. Matches the house .choice-box treatment
   (paper-2 + thin ink border + rounded) with lighter padding. */
.bp-callout {
  /* Full content width, not the old 38rem cap. The statement inside is three
     parallel lines sharing a left edge (see .bp-statement); narrowing the box
     only forces those lines to wrap, which is the one thing that breaks the
     parallel reading. The prose column is the real limit. */
  margin: 1.5rem auto;
  padding: 1.1rem 1.5rem 1.25rem;
  background: var(--paper-2, #F3ECD6);
  border: 1px solid rgba(28, 28, 28, .16);
  border-radius: var(--radius-md, .5rem);
}
/* Inside the panel the narrow statements no longer need their own centering
   frame — let them fill the panel's padded width. */
.bp-callout .lead-statement--narrow {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}
/* Header row of the callout: the Schoolio mark (an "i" — inside — within an
   "O" — outside) sits beside the "The Beautiful Problem:" label, so the mark
   visually restates the inside/outside idea the statement below spells out. */
.bp-callout__head {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin-bottom: .55em;
}
.bp-callout__head .lead-statement {
  margin: 0;
}
.bp-callout__mark {
  flex: 0 0 auto;
  width: 3rem;
  height: auto;
  display: block;
}
@media (max-width: 640px) {
  .bp-callout__mark { width: 2.5rem; }
  /* Buy back width where it is scarcest. On a 414px phone the box's own
     padding is 48 of the 96px separating the viewport from the text, and each
     16px returned is 16px the statement does not have to wrap. The card still
     reads as a card at 1rem. (The matching override for .problem-box--bp has
     to live further down, after .problem-box's own padding shorthand — see
     the note there.) */
  .bp-callout { padding-left: 1rem; padding-right: 1rem; }
}
/* Branded "inside" / "outside" words. The Schoolio mark does letter duty:
   the bare "i" glyph (schoolio-mark-i.svg) replaces the "i" in "inside", and
   the full mark (schoolio-mark.svg — an "i" within an "O") replaces the "O" in
   "outside". Reusable anywhere the inside/outside idea appears; pair with the
   branded_inside_html / branded_outside_html rake helpers in guides.rake, or
   hand-write the same <img class="lo-mark-letter lo-mark-letter--i|--o"> markup.
   Heights/baselines are tuned so each glyph sits like a capital-height letter. */
.lo-mark-letter { width: auto; vertical-align: -0.14em; }
.lo-mark-letter--i { height: 1.18em; }
.lo-mark-letter--o { height: 1em; vertical-align: -0.18em; }
/* The last line shouldn't add margin below the panel's own bottom padding. */
.bp-callout > :last-child {
  margin-bottom: 0;
}
/* The Beautiful Problem statement — the site-wide standard treatment, emitted
   by the bp_statement_html helper in guides.rake. Three lines: a bold lead-in
   ("How to get students"), then the inside/outside pair, each opening with its
   branded glyph and hinged on an en dash.

   This replaced a two-column .bp-split treatment that put "inside …" and
   "outside …" either side of a hairline seam. The parallel structure is what
   carries the idea, and a shared left edge shows it far better than a seam
   did: the two lines start the same way, so the eye compares the halves
   directly instead of reading them as two separate fragments. It also frees
   the box to be full width, which is why .bp-callout no longer caps at 38rem.

   On size vs. line count. This first shipped with a viewport-tracking
   font-size floor copied from the home hero sub-line, chosen to hold three
   lines at every width. That was the wrong trade here, and the measurement
   says why the home version gets away with it and this one cannot: the hero
   spans nearly the whole viewport (40px of chrome), while this sits inside a
   section (24px each side) inside a box (24px each side) — 96px gone, leaving
   318px of text on a 414px phone. Three lines at a proper statement size
   (24px x the measured 15.3 width-to-size ratio = 367px) does not fit in 318,
   and would not fit even with the box padding removed entirely.

   So the floor was buying line count with type size, and the bill came due on
   phones: 15px text against 15px body copy, when every other .lead-statement
   on the page is 24px. It read as body copy, not as the statement of the
   problem the whole site is about.

   The floor is kept, but re-derived from constants that are now correct
   rather than guessed, which is what was actually wrong the first time:
     - chrome is 80px, not 96 — the box's phone padding is trimmed to 1rem
       below 640px (see the media query above), returning 16px of text width;
     - the divisor is 15.8, close to the measured 15.3 width-to-size ratio of
       the longest line plus a little safety. The original 18.5 was picked
       conservatively rather than measured, and that alone cost ~3px.
   Together those lift a 360px phone from 15.1px to 17.7px and a 414px phone
   from 18.1px to 21.1px, while still holding three lines — so this is not a
   trade of size against line count, it is both.

   The wrap case is still handled rather than merely avoided: each line is its
   own block (.bp-line) with a hanging indent, so if a line does wrap — user
   font scaling, a narrower device than any tested — its continuation sits
   inboard of the branded glyph and the three lines still start on a shared
   left edge. .lo-nowrap-beat keeps "need to succeed" whole so the break lands
   somewhere sensible. */
.bp-statement {
  /* The display serif, explicitly — not the inherited page voice. This is the
     home hero's sub-line promoted to a standard, and the serif is part of that
     treatment: it sets the statement apart from the body copy around it as a
     thing being quoted rather than another paragraph. Naming the family here
     also makes the callout look identical on "educating" pages (sans voice)
     and "learning" pages (serif voice), which a standard treatment should. */
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: clamp(min(1.5rem, calc((100vw - 5rem) / 15.8)), 3.4vw, 2.125rem);
  line-height: 1.3;
  letter-spacing: -.008em;
  margin: 0;
  text-align: left;
}
/* One block per line, with a hanging indent for the wrap case. The indent is
   sized to clear the branded glyph plus its following space, so a continuation
   line starts under the word rather than under the mark. */
.bp-statement .bp-line {
  display: block;
  padding-left: 1.15em;
  text-indent: -1.15em;
}
/* The statement is a <p>, so inside a guide page `.page-paper .prose p`
   (tokens.css) out-specifies the class above — two classes plus an element
   beats one class — and would add a bottom margin that pushes the last line
   past the box's own padding. Match it with three classes rather than !important. */
.page-paper .prose .bp-statement,
.prose .bp-callout .bp-statement,
.prose .problem-box .bp-statement {
  margin: 0;
}
/* .lead-statement sets bold runs in terracotta, which would collide with the
   red "The Beautiful Problem:" label directly above. Here the bold is doing
   structural work, not colour work — it just anchors the lead-in — so keep it
   ink and let the ink-blue accents carry the emphasis, exactly as on home. */
.bp-statement strong {
  color: inherit;
  font-weight: 600;
}
.bp-statement .lo-accent em {
  font-style: italic;
}
/* Weld a branded glyph to the rest of its word. The mark is an <img>, so a
   line is otherwise free to break between it and the letters after it, which
   printed "outside" as a lone O-mark followed by "utside". Matching on :has()
   targets only the wrapper branded_inside_html / branded_outside_html emit,
   leaving ordinary .lo-accent runs free to wrap. Same rule as the home hero. */
.bp-statement .lo-accent:has(> .lo-mark-letter) {
  white-space: nowrap;
}
/* Keep "need to succeed" whole if its line ever does overflow, so the beat
   moves down intact rather than leaving a two-word orphan. The floor above
   should mean this never fires; it is a fallback for engines that set the
   line wider than the slack the floor allows. */
.bp-statement .lo-nowrap-beat {
  white-space: nowrap;
}
/* Forward-pointer aside that sits between a section title and the content
   below it (e.g. "you'll see the exact same steps on the Education page").
   Set a touch larger than the body/step text and gently emphasised — italic,
   accent colour, with a soft accent hairline on the left — so it reads as a
   quiet standout without shouting. */
.prose .steps-note,
.steps-note {
  margin: .35rem 0 1.35rem;
  padding-left: .9rem;
  border-left: 3px solid var(--terracotta);
  font-family: "Source Serif 4", Georgia, serif;
  font-style: italic;
  font-size: clamp(1.3rem, 2.4vw, 1.65rem);
  line-height: 1.4;
  color: var(--terracotta);
}
.prose .steps-note em,
.steps-note em {
  font-style: normal;
  font-weight: 600;
}
/* Smaller variant of the forward-pointer note — for a full-sentence note
   (rather than a one-line aside) that should read quieter, closer to body
   size, while keeping the italic terracotta accent-rule treatment. */
.prose .steps-note--sm,
.steps-note--sm {
  font-size: clamp(1.05rem, 1.7vw, 1.25rem);
  line-height: 1.45;
}
/* "The trap" line in the Beautiful Problem "significance" block. Set off
   with a terracotta left-rule (echoing steps-note) but kept in ink and a
   touch smaller than the surrounding prose, so it reads as a subordinate
   aside rather than a louder beat — and the sentence above it stays the
   dominant line. The bold anchor + italic question inside stay visible. */
.prose .problem-note,
.problem-note {
  margin: .35rem 0 1.35rem;
  padding-left: .9rem;
  border-left: 3px solid var(--terracotta);
  font-size: .92em;
  line-height: 1.5;
}
/* Quiet qualifier line beneath a section title (e.g. "The problem" /
   "— as understood by Taylor's method"). Sits on its own line, sized well
   down from the heading and set in a softer weight/colour so it reads as a
   subordinate framing note rather than a second heading. */
.title-qualifier {
  display: block;
  margin-top: .2rem;
  font-size: .5em;
  font-weight: 500;
  font-style: italic;
  line-height: 1.25;
  color: rgba(28, 28, 28, .6);
}

/* Problem box — a raised "here's the problem" card. Used inside the paper-2
   "science of learning motivation" section, so it takes the *lighter* --paper
   bg (plus a thin border + paper shadow) to lift off the paper-2 ground. */
.problem-box {
  max-width: 40rem;
  margin: 1rem auto 1.5rem;
  padding: 1.1rem 1.6rem 1.2rem;
  background: var(--paper, #FBF6EA);
  border: 1px solid rgba(28, 28, 28, .16);
  border-radius: var(--radius-md, 8px);
  box-shadow: var(--shadow-paper, 4px 4px 0 0 rgba(28, 28, 28, .12));
  text-align: center;
}
/* Excludes .bp-statement deliberately. This rule out-specifies a bare class
   (one class + one element beats one class), so without the :not() it would
   override .bp-statement's font-size and line-height — and the only way to win
   it back would be to restate the measured clamp here, giving that constant a
   second home to drift from. Narrowing this selector keeps one source. */
.problem-box p:not(.bp-statement) {
  margin: 0;
  /* Sized to keep the single statement on one line within the box on
     desktop; it may wrap on the narrowest phones, which is fine. */
  font-size: clamp(1.05rem, 2.3vw, 1.35rem);
  line-height: 1.25;
}
/* When the box holds the standard Beautiful Problem statement, it is the same
   full-width, left-aligned block as the .bp-callout — only the card styling
   differs (this one lifts off a paper-2 ground). */
.problem-box--bp {
  max-width: none;
  text-align: left;
}
/* Phone padding, matching .bp-callout's, so the statement gets the same text
   width in both containers. This must sit *after* .problem-box above: both
   selectors are a single class, so the cascade falls to source order, and
   .problem-box's `padding` shorthand would otherwise reinstate its wider
   1.6rem sides. That is exactly what happened when this override was first
   written up beside the .bp-callout one — the callout took the extra width
   and this box silently did not, wrapping its second line on every phone
   width while the callout beside it held three lines. */
@media (max-width: 640px) {
  .problem-box--bp { padding-left: 1rem; padding-right: 1rem; }
}

/* Tiny utilities --------------------------------------------------------- */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.text-center { text-align: center; }
.mt-4 { margin-top: 2rem; }
.mt-6 { margin-top: 3rem; }

/* Thought bubble --------------------------------------------------------- */
/* A student's inner voice, rendered as a rounded thought balloon with two
   trailing dots to the lower-left. Used on the Dan Pink guide's closing
   "Did Mr Pink succeed?" beat (the Purpose line). */
.thought-bubble {
  position: relative;
  display: inline-block;
  margin: 0.5rem 0 1.25rem 1.9rem;
  padding: 0.85rem 1.15rem;
  max-width: 48ch;
  background: var(--paper-2);
  border: 1px solid rgba(28, 28, 28, 0.15);
  border-radius: 1.4rem;
  box-shadow: var(--shadow-paper);
  font-style: italic;
  line-height: 1.4;
}
.thought-bubble::before,
.thought-bubble::after {
  content: "";
  position: absolute;
  background: var(--paper-2);
  border: 1px solid rgba(28, 28, 28, 0.15);
  border-radius: 50%;
}
.thought-bubble::before {
  width: 0.9rem; height: 0.9rem;
  left: -0.7rem; bottom: 0.5rem;
}
.thought-bubble::after {
  width: 0.5rem; height: 0.5rem;
  left: -1.3rem; bottom: 0.05rem;
}

/* ------------------------------------------------------------------ *
 * Classroom-proof "results after the video" beat (Eva Fugitt &
 * Marva Collins pages).
 * Shared, page-agnostic pieces are prefixed `.proof-`; each page adds
 * its own results graphic (`.eva-read` growth bar, `.marva-read`
 * reading list, `.marva-outcomes` life-outcomes contrast). All styling
 * is class-based so it survives the paragraph part's rich_text
 * sanitiser (inline styles are stripped).
 * ------------------------------------------------------------------ */
.proof-result { margin: 0 auto; }
.proof-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(28, 28, 28, 0.6);
  margin: 1.6rem 0 0.35rem;
}
.proof-result > .proof-eyebrow:first-child { margin-top: 0; }
/* Cohort descriptor: meaningful context, so it reads stronger than the
   quiet section-label eyebrows. */
.proof-eyebrow--cohort {
  color: var(--ink);
  font-weight: 600;
  font-size: var(--fs-16);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.proof-eyebrow--cohort::before {
  content: "";
  flex: none;
  width: 1.7rem;
  height: 3px;
  border-radius: 2px;
  background: var(--terracotta);
}
/* "Yes — spectacularly." subtitle, lifted in terracotta so the verdict pops. */
.proof-yes { color: var(--terracotta); }
.proof-caption {
  margin: 0.5rem 0 0;
  font-size: var(--fs-16);
  line-height: 1.5;
  color: var(--ink);
}

/* Shared: a paper card that lifts a results graphic off the paper-2 band. */
.proof-card {
  background: var(--paper);
  border-radius: 12px;
  box-shadow: var(--shadow-paper);
  padding: 1.25rem 1.4rem;
  margin: 1rem 0 0;
  max-width: 44rem;
}
.proof-card .marva-read { max-width: none; }
.proof-card .marva-read__row:last-child { border-bottom: 0; padding-bottom: 0; }

/* Shared: the people's own voices (parents, reporters, students) */
.proof-voices { display: grid; gap: 1rem; margin: 1.7rem 0 0; }
.proof-voice {
  border-left: 3px solid var(--terracotta);
  padding: 0.15rem 0 0.15rem 1rem;
}
.proof-voice__quote {
  font-style: italic;
  font-size: var(--fs-20);
  line-height: 1.4;
  margin: 0;
}
.proof-voice__who {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: rgba(28, 28, 28, 0.6);
}

/* Feature voice — a highlighted story card (e.g. the two hidden gifts). */
.proof-voice--feature {
  border-left: 0;
  padding: 1.15rem 1.3rem;
  margin: 1.4rem 0 0;
  max-width: 44rem;
  background: var(--paper);
  border-top: 4px solid var(--terracotta);
  border-radius: 0 0 12px 12px;
  box-shadow: var(--shadow-paper);
}
.proof-voice__tag {
  display: inline-block;
  margin: 0 0 0.55rem;
  font-family: var(--font-mono);
  font-size: var(--fs-12);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--terracotta);
}
.proof-voice--feature .proof-voice__quote { font-size: var(--fs-20); }

/* Shared: the point — educating, not just same-pace learning */
.proof-point {
  margin: 2rem 0 0;
  padding: 1.6rem 0 0;
  border-top: 2px solid rgba(28, 28, 28, 0.14);
  max-width: 44rem;
}
.proof-bp { margin: 2.4rem 0 0; }
.proof-point__head {
  font-size: clamp(1.5rem, 3vw, var(--fs-30));
  line-height: 1.15;
  margin: 0 0 0.6rem;
}

/* Eva Fugitt: reading-level growth bar (grade-equivalent 2.4 -> 6.0) */
.eva-read { max-width: 40rem; margin: 0 0 0.4rem; }
.eva-read__scale {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  font-weight: 600;
  color: rgba(28, 28, 28, 0.55);
}
.eva-read__track {
  position: relative;
  height: 2.5rem;
  margin-top: 0.45rem;
  background: rgba(28, 28, 28, 0.08);
  border-radius: 7px;
}
.eva-read__fill {
  position: absolute;
  top: 0; bottom: 0;
  left: 28%;            /* grade-equivalent 2.4 on a 1–6 scale */
  right: 0;             /* grade-equivalent 6.0 */
  background: var(--chalkboard);
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0.8rem;
  box-shadow: var(--shadow-paper);
}
.eva-read__from,
.eva-read__to {
  font-weight: 700;
  font-size: var(--fs-18);
  color: #F7F1E1;
  line-height: 1;
}
.eva-read__gain {
  text-align: center;
  margin: 0.6rem 0 0;
  font-weight: 700;
  font-size: var(--fs-18);
  color: var(--chalkboard);
}

/* Eva Fugitt: hero-stat card — the big "+3.6 years" figure beside the bar,
   lifted off the paper-2 band on its own paper card. */
.eva-result {
  display: flex;
  align-items: stretch;
  gap: 1.1rem;
  max-width: 44rem;
  margin: 1rem 0 0;
  padding: 1.25rem;
  background: var(--paper);
  border-radius: 12px;
  box-shadow: var(--shadow-paper);
}
.eva-result__figure {
  flex: none;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.35rem;
  padding: 1rem 1.2rem;
  background: var(--chalkboard);
  border-radius: 10px;
  text-align: center;
}
.eva-result__num {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.75rem, 8vw, var(--fs-60));
  line-height: 0.9;
  color: #F7F1E1;
}
.eva-result__unit {
  font-family: var(--font-mono);
  font-size: var(--fs-12);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1.35;
  color: rgba(247, 241, 225, 0.85);
}
.eva-result__bar {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.eva-result__bar .eva-read { margin: 0; max-width: none; }

/* Marva Collins: what her young children were reading (age -> authors) */
.marva-read { max-width: 40rem; margin: 0; display: grid; gap: 0.55rem; }
.marva-read__row {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  align-items: baseline;
  gap: 0.9rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid rgba(28, 28, 28, 0.12);
}
.marva-read__grade {
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--chalkboard);
}
.marva-read__authors {
  margin: 0;
  font-size: var(--fs-18);
  line-height: 1.35;
}

/* Marva Collins: life-outcomes contrast (predicted vs. her students) */
.marva-outcomes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 1.25rem;
  max-width: 48rem;
  margin: 0.6rem 0 0;
}
.marva-outcomes__vs {
  align-self: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-style: italic;
  font-size: var(--fs-20);
  color: var(--terracotta);
}
.marva-outcome {
  align-self: stretch;
  border-radius: 10px;
  padding: 1.3rem 1.5rem;
}
.marva-outcome--predicted {
  background: rgba(28, 28, 28, 0.06);
  border: 1px solid rgba(28, 28, 28, 0.12);
}
.marva-outcome--actual {
  background: var(--chalkboard);
  color: #F7F1E1;
  box-shadow: var(--shadow-paper);
}
.marva-outcome__label {
  font-family: var(--font-mono);
  font-size: var(--fs-16);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
  margin: 0 0 0.6rem;
  opacity: 1;
}
.marva-outcome__list { margin: 0; padding: 0; list-style: none; }
.marva-outcome__list li {
  font-weight: 700;
  font-size: var(--fs-24);
  line-height: 1.5;
}
@media (max-width: 34rem) {
  .marva-outcomes { grid-template-columns: 1fr; }
  .marva-outcomes__vs { justify-self: center; padding: 0.15rem 0; }
  .marva-read__row { grid-template-columns: 1fr; gap: 0.15rem; }
  .eva-result { flex-direction: column; align-items: stretch; }
  .eva-result__figure { flex-direction: row; align-items: baseline; justify-content: center; gap: 0.6rem; }
}

/* --- Book endorsements ---------------------------------------------------
 * Long-form, attributed endorsements: several paragraphs each, under the
 * endorser's name and credentials. Used on /team/robert-j-caveney for the
 * five endorsements of SCHOOLING For Readiness And Drive.
 *
 * These deliberately do NOT take the default `blockquote` treatment from
 * tokens.css. That one — display serif at fs-24 on a yellow highlighter wash
 * — is built for a single arresting line; five multi-paragraph quotes in it
 * would be a wall of yellow with nothing left to emphasise. Here the quote
 * is body-sized prose behind a quiet accent rule, and the attribution above
 * does the work of announcing whose voice it is.
 *
 * The endorsements arrive through rich_text, whose sanitizer allows `class`
 * but strips `style` — which is why this lives in CSS rather than inline on
 * the generated markup.
 */
.book-endorsement { margin: var(--sp-7) 0 0; }

.book-endorsement + .book-endorsement {
  border-top: var(--hairline);
  padding-top: var(--sp-6);
}

.book-endorsement__name {
  font-family: var(--font-display);
  font-size: var(--fs-24);
  line-height: 1.2;
  margin: 0 0 0.35rem;
}

/* Sentence case, not the uppercase mono the site uses for short eyebrow
 * labels. These credentials run long — "Former VP of the California
 * Federation of Teachers (CFT) and former president of CFT's Early
 * Childhood/K-12 Council" — and uppercase with letter-spacing turns a line
 * that length into something you decode rather than read. */
.book-endorsement__credit {
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  line-height: 1.5;
  opacity: 0.75;
  margin: 0 0 0.15rem;
}

/* Outweigh the element selector in tokens.css without !important. */
.prose blockquote.book-endorsement__quote {
  margin: var(--sp-4) 0 0;
  padding: 0 0 0 var(--sp-4);
  background: none;
  border-left: 3px solid var(--highlighter);
  font-family: inherit;
  font-size: inherit;
  line-height: 1.55;
}

.book-endorsement__quote p { margin: 0 0 var(--sp-3); }
.book-endorsement__quote p:last-child { margin-bottom: 0; }

/* ── Open positions ─────────────────────────────────────────────────────────
 * The vacancy cards under the team on /team.
 *
 * Same auto-fit grid as the team roster above, but with a wider minimum track
 * (280px vs 240px): these cards hold a job title and a sentence rather than a
 * portrait, so a narrow column would set a two-word title on three lines.
 *
 * The cards are text-only and left-aligned, where the team cards are centred
 * around a portrait. That difference is the point — a vacancy should not be
 * mistakeable for a colleague at a glance. */
.open-position-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-6);
}

.open-position {
  background: var(--paper);
  padding: var(--sp-6);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-paper);
  text-align: left;
  /* A column with the "read the description" line pinned to the bottom, so
   * cards of unequal teaser length still line their calls to action up. */
  display: flex;
  flex-direction: column;
}

/* --fs-22 to match the team member names on the same page. This originally
 * said --fs-20 because --fs-22 was referenced site-wide but never defined; it
 * is defined in tokens.css now, so the two headings on /team are the same size
 * again, which is the point. */
.open-position__title {
  font-family: var(--font-display);
  font-size: var(--fs-22);
  line-height: 1.2;
  margin: 0;
}

/* Inherit the ink colour rather than the link blue: the whole card is
 * clickable-looking already, and a blue heading over a blue "read the
 * description" line below it is two shouts where one will do. Underline on
 * hover keeps it discoverable as a link. */
.open-position__title a {
  color: inherit;
  text-decoration: none;
}

.open-position__title a:hover,
.open-position__title a:focus-visible {
  text-decoration: underline;
}

/* Matches the uppercase mono role label on the team cards. */
.open-position__details {
  font-family: var(--font-mono);
  font-size: var(--fs-12);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.75;
  margin-top: 0.35rem;
}

.open-position__teaser {
  font-size: var(--fs-16);
  line-height: 1.55;
  margin: var(--sp-3) 0 0;
}

/* margin-top:auto is what pins this to the bottom; see the flex column above.
 * The padding keeps it clear of the teaser on a card that is short enough
 * that there is no free space for the auto margin to absorb. */
.open-position__more {
  margin: auto 0 0;
  padding-top: var(--sp-4);
}
