/* ==========================================================================
   MedLit — health made understandable.
   One stylesheet. No frameworks, no build step, no JavaScript required to
   read anything on the page.

   THE IDEA
   MedLit's whole argument is that a document should be readable. So the page
   is built out of MedLit's own materials:

     - Pharmacy amber, at full strength, as a field. It is the one colour
       nobody else in this category owns, because it is the colour of the
       bottle in the logo.
     - The numbered callout disc from the printed guide. A navy circle with a
       white numeral, pointing at something and saying what it means.
     - Every word set in Schibsted Grotesk, a newspaper face with open
       apertures and a tall x-height. Body copy and the 124px headline alike.

   The page states what MedLit does and shows the guide that proves it. It
   does not demonstrate the product on itself. An interactive prescription
   label and a before/after panel were both built here and both removed —
   twice — because the guides already do that job on paper, reviewed, and
   printable. See the note at the top of index.html before rebuilding either.

   Rules worth keeping:
     1. Two faces, no more. DM Sans for headings and big figures, Schibsted
        Grotesk for everything else.
     2. Amber carries dark ink only. White on amber is 1.7:1.
     3. No decorative bars. Amber is a FIELD — the hero and the measure band —
        never a 4px slab stuck above a heading. Hierarchy comes from size,
        weight and space. Hairlines are 1px and neutral.
     4. Motion is opacity and transform, and it runs every time a block
        passes through the viewport, in and out.
     5. Nothing needs JavaScript to be read.

   Contents
   1.  Fonts
   2.  Tokens
   3.  Base and type scale
   4.  The callout disc — the repeating mark
   5.  Accessibility and motion
   6.  Widths
   7.  Masthead
   8.  Hero — the amber field
   9.  Three doors
   10. Our why
   11. What we do
   12. The work so far — counts
   13. What we measure — the comprehension promise
   14. The guides
   14b. Testimonials
   15. The workshops
   16. How we check it
   17. Host
   18. Volunteer
   19. Photography slots
   20. Facts, actions
   21. Footer
   22. Responsive
   ========================================================================== */

/* ---------- 1. Fonts ------------------------------------------------------
   One family, self-hosted, latin subset, about 97 KB. That matters: this
   loads on an old phone on library wifi.

   Schibsted Grotesk, a variable face on a 400–900 weight axis. A Scandinavian
   newspaper grotesque: open apertures, a tall x-height, a single-storey 'g'
   and an 'a' that stays distinct at 18px, which is what the readers here need.
   The wide weight axis is the whole reason the page can hold an extreme type
   scale without a second display family — 400 for body, 900 for the headline,
   one set of letterforms across both.

   Atkinson Hyperlegible Next was here before it and is still in
   assets/fonts/ if it ever comes back. DM Sans, below, sets the headings.
   Two families is the ceiling: a third and the page starts performing
   instead of reading.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Schibsted';
  src: url('assets/fonts/schibsted-grotesk-var.woff2') format('woff2');
  font-weight: 400 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Schibsted';
  src: url('assets/fonts/schibsted-grotesk-italic.woff2') format('woff2');
  font-weight: 400 900; font-style: italic; font-display: swap;
}
/* DM Sans, for headings and the big figures only. Rounder and lighter than
   Schibsted at display sizes, so headings can sit at 600-700 and still
   lead. Variable, with an optical-size axis the browser sets on its own. */
@font-face {
  font-family: 'DM Sans';
  src: url('assets/fonts/dm-sans-var.woff2') format('woff2');
  font-weight: 100 1000; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('assets/fonts/dm-sans-italic.woff2') format('woff2');
  font-weight: 100 1000; font-style: italic; font-display: swap;
}
/* ---------- 2. Tokens ----------------------------------------------------
   The navy and the amber are the logo's own. Everything else is stock, ink
   and rules.

   Every pair used on this page was measured in a rendered browser. The floor
   is AA and most clear AAA:

     ink  on stock  18.1     navy      on stock     9.5
     ink  on amber   9.1     navy-deep on amber     7.2
     ink2 on stock   8.2     amber     on navy-deep 7.2
     white on navy   9.5     amber     on ink       9.1

   Ruled out by construction: white is never text on amber (1.7:1), and
   --ink-2 is never text on amber (4.1:1) — on amber the secondary voice is
   --navy-deep instead.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  --stock:    #ffffff;
  --stock-2:  #f6f5f1;

  --ink:      #14161c;
  --ink-2:    #4a4f5c;

  --navy:     #0b3ea0;
  --navy-deep:#062563;
  --amber:    #f4a838;
  --amber-lt: #ffe0a8;
  --amber-dk: #a05a04;

  --rule:     #dcdde2;
  --rule-firm:#a9adb8;

  --on-navy:     #e8ecf7;
  --on-navy-dim: #b6c1de;

  /* Extreme scale contrast, which is where the personality lives when there
     is only one typeface for language. --t1 is about six times body. */
  --t1: clamp(2.6rem, 1rem + 6vw, 5.4rem);
  --t2: clamp(1.6rem, 1.1rem + 1.9vw, 2.5rem);
  --t3: 1.2rem;

  --wide:   82rem;
  --read:   44rem;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);

  --sans: 'Schibsted', 'Schibsted Grotesk', 'Helvetica Neue', Arial, system-ui, sans-serif;
  --display: 'DM Sans', 'Helvetica Neue', Arial, system-ui, sans-serif;

  --r: 4px;
  --ease: cubic-bezier(.16, 1, .3, 1);
}

/* ---------- 3. Base and type scale --------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  /* 18px minimum body text — readers include older adults, and this is a
     hard floor. Everything scales from here in rem. */
  font-size: 18px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--stock);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* overflow-wrap is a safety net, not a layout choice. With the real face
   loaded no word on this page is ever wider than its line box — swept at every
   5px from 320 to 1920. But `font-display: swap` paints the FALLBACK face
   first, and the fallback stack runs wider, which is enough to push
   "Understanding" past the edge of a 320-450px phone and let the page scroll
   sideways until the real font arrives. On library wifi that is not a flicker,
   it is a few seconds. This costs nothing when the font is loaded and it never
   triggers. */
h1, h2, h3 { margin: 0; color: var(--ink); text-wrap: balance; overflow-wrap: break-word; }
/* Headings are DM Sans at 700, not 800 — confident without shouting. */
h1, h2, h3 { font-family: var(--display); }
h1 { font-size: var(--t1); font-weight: 700; line-height: 1.04; letter-spacing: -0.015em; }
h2 { font-size: var(--t2); font-weight: 700; line-height: 1.12; letter-spacing: -0.01em; }
h3 { font-size: 1.2rem; font-weight: 600; line-height: 1.3; letter-spacing: 0; }
h1 em, h2 em, h3 em { font-style: italic; font-weight: inherit; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

img { max-width: 100%; height: auto; display: block; }
ul, ol { padding: 0; margin: 0; }
dl, dd { margin: 0; }

a { color: var(--navy); text-underline-offset: .2em; }
a:hover { color: var(--navy-deep); }

::selection { background: var(--amber-lt); color: var(--ink); }

/* The kicker. A small label above a heading, set in sentence case.
   No letterspaced capitals anywhere on this page: they read as a template
   and they are harder to read for exactly the people the page is for. No
   amber bars either. Weight and colour do the work. */
.kicker {
  display: block;
  font-size: .95rem; font-weight: 600; line-height: 1.3;
  color: var(--ink-2); margin: 0 0 1rem;
}
.host .kicker { color: var(--amber); }

/* The section mark. The same device for a section whose body copy is the
   display type. It is a real <h2>: the outline is honest, and nothing on
   this page is a heading hidden off-screen. */
.section-mark {
  display: block;
  font-size: 1rem; font-weight: 600; line-height: 1.3;
  color: var(--navy); margin: 0 0 1.2rem;
}

/* ---------- 4. The callout disc — the repeating mark ---------------------
   Lifted straight from the printed guide: a navy disc with a white numeral,
   pointing at a piece of real document text and pairing it with the plain
   version.

   It has one home now: the two commitments in "How we check it". It used to
   also mark every line of the interactive label and both halves of the
   before/after panel, and both of those are gone.

   One use is thin for a repeating mark. If a section ever arrives that
   genuinely points at something and says what it means, this is the mark for
   it. Do not sprinkle it on things that are neither a document nor a claim
   just to make it recur — that is how a mark becomes wallpaper.
   -------------------------------------------------------------------------- */
.callout {
  display: inline-grid;
  place-items: center;
  width: 1.85rem; height: 1.85rem;
  flex: none;
  border-radius: 50%;
  background: var(--navy);
  color: var(--stock);
  font-size: .76rem;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
/* Reversed out of navy, the disc flips to amber with dark ink. White on
   amber would be 1.7:1; navy-deep on amber is 7.2:1. */
.host .callout {
  background: var(--amber);
  color: var(--navy-deep);
}

/* ---------- 5. Accessibility and motion ----------------------------------- */
.skip {
  position: absolute;
  left: 50%; top: 0;
  transform: translate(-50%, -140%);
  z-index: 200;
  background: var(--navy-deep);
  color: var(--stock);
  padding: .85rem 1.6rem;
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 var(--r) var(--r);
}
.skip:focus { transform: translate(-50%, 0); color: var(--stock); }

:focus-visible { outline: 3px solid var(--navy); outline-offset: 3px; }
.hero :focus-visible,
.host :focus-visible,
.foot :focus-visible { outline-color: var(--amber); }

.hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Passing motion.
   Blocks settle in as they enter the viewport and let go as they leave, both
   directions, every time. Two details make that read as considered:

     1. The transition lives on the base rule, not only on `.is-in`, so the
        way out is as smooth as the way in.
     2. --rv is the direction, set from JavaScript on every crossing. A block
        leaving past the top carries on upward; one leaving past the bottom
        goes down. The movement always agrees with the scroll.

   Gated on the `js` class, which the page only sets once it knows the
   observer will run. Without JavaScript — or if the script throws — nothing
   is ever hidden. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(var(--rv, 20px));
    transition: opacity .55s var(--ease), transform .55s var(--ease);
  }
  .js [data-reveal].is-in { opacity: 1; transform: none; }
  /* Instant, not transitioned. Tabbing into a block that has scrolled out
     should put it on screen now. */
  .js [data-reveal]:focus-within { opacity: 1; transform: none; transition: none; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* Print, and anything that behaves like print.
   Because a block now fades back out once it leaves the viewport, every
   section that is off-screen at the moment of printing would come out of the
   printer blank. An activity director handing this page round a staff meeting
   is a real thing that happens, so print gets the whole page, always. */
@media print {
  .js [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .masthead, .hero, .tally, .measure, .host, .foot { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ---------- 6. Widths ---------------------------------------------------- */
.wide {
  width: 100%; max-width: var(--wide);
  margin-inline: auto; padding-inline: var(--gutter);
}
/* ONE LEFT RAIL. Every section on this page starts at the same x, from the
   masthead to the footer, and the only thing that varies is how far right the
   content runs.

   .read used to be a narrow box centred in the VIEWPORT, which put its left
   edge 266px inside everything above and below it. Centred is not the same as
   aligned: next to a run of flush-left sections it reads as shoved right, with
   a dead strip down the left of the page. So .read now has exactly the
   geometry of .wide — same max-width, same gutter — and caps its CHILDREN at
   the reading measure instead. Narrow column, flush left, air on the right.

   If you add a child that should run full width inside a .read section, give
   it `max-width: none`. */
.read {
  width: 100%; max-width: var(--wide);
  margin-inline: auto; padding-inline: var(--gutter);
}
.read > * { max-width: var(--read); }

/* ---------- 7. Masthead --------------------------------------------------
   White, so the navy-and-amber wordmark reads at full strength before the
   amber field starts underneath it. Not sticky: a sticky bar costs a strip
   of a small screen permanently and buys little on a page this short.
   -------------------------------------------------------------------------- */
.masthead { background: var(--stock); }
.masthead__inner {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: .75rem 2rem; padding-block: 1.15rem;
}
.brand { display: flex; align-items: center; gap: .9rem; text-decoration: none; }
.brand__mark { width: auto; height: 3rem; flex: none; }
.brand__tagline {
  font-size: .96rem; font-weight: 500; color: var(--ink-2);
  padding-left: .15rem;
}
.topnav ul {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 1.75rem; list-style: none;
}
.topnav a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 1rem; font-weight: 700; color: var(--ink); text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color .16s var(--ease), border-color .16s var(--ease);
}
.topnav a:hover, .topnav a:focus-visible {
  color: var(--navy); border-bottom-color: var(--amber);
}

/* ---------- 8. Hero — photograph with the claim over it ------------------
   A real <img>, not a CSS background, so it gets fetchpriority and a
   width/height the browser can reserve space for. It is absolutely
   positioned behind the text and cropped with object-fit.

   The headline sits bottom-left. In the current photo the faces are all in
   the upper half, so text down there never lands on anyone's face. If the
   photo changes, check that again and move object-position before moving
   the type.

   Legibility comes from a navy scrim, darkest at the bottom-left where the
   text is and clear over the faces. White on the darkest part of the scrim
   is well over 7:1; the navy also keeps the photo inside the brand's colours
   instead of looking like a stock image dropped in.

   Without the photo — file missing, or still loading on slow wifi — the
   section is plain navy-deep and reads exactly the same.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  min-height: clamp(26rem, 72vh, 44rem);
  background: var(--navy-deep);
  /* Bottom padding kept tight so the headline sits as low as it can: every
     pixel it drops is a pixel further from the faces. */
  padding-block: clamp(3rem, 7vw, 5.5rem) clamp(2.25rem, 4vw, 4rem);
}
.hero__photo {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Near the bottom: on a wide screen the crop is vertical, and taking most
     of it off the top lifts the faces clear of the headline. Centred, the
     first line ran straight across the child's face; fully bottom-anchored,
     a 1920px screen cut off the tops of everyone's heads. */
  object-position: 50% 80%;
  /* Softened so the headline is the sharpest thing in the frame. The scale
     hides the blur's soft edge, which would otherwise show as a pale rim. */
  filter: blur(3px) saturate(.85);
  transform: scale(1.04);
}
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(rgba(6, 37, 99, .42), rgba(6, 37, 99, .42)),
    linear-gradient(to top, rgba(6, 37, 99, .9) 0%, rgba(6, 37, 99, .55) 32%, rgba(6, 37, 99, 0) 62%),
    linear-gradient(to right, rgba(6, 37, 99, .45) 0%, rgba(6, 37, 99, 0) 55%);
}
/* The site-wide --t1 is sized for a headline that owns a whole amber field.
   Over a photograph it has to leave room for the photograph, so it comes
   down a step and holds to about three lines on desktop. */
.hero h1 {
  color: var(--stock);
  font-size: clamp(2.4rem, 1rem + 3.6vw, 4rem);
  max-width: 13ch;
}
.hero h1 em { color: var(--amber); }

/* ---------- 8b. Three doors — one strip under the photograph -------------
   Three columns split by hairlines: a bold title, one line of who it is
   for, and an arrow on the right. The whole cell is the link; on hover it
   lightens and an amber underline runs along its bottom edge.
   -------------------------------------------------------------------------- */
.doors {
  background: linear-gradient(180deg, var(--stock-2), #f1efe9);
  border-bottom: 1px solid var(--rule);
}
/* The middle door has the longest words, so it gets the widest column —
   with three equal thirds its title and line both wrapped at 1440px. */
.doors ul {
  list-style: none; display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) minmax(0, 1fr);
}
.doors li + li { border-left: 1px solid var(--rule); }
.doors a {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: .3rem 1rem; min-height: 48px;
  padding: clamp(1.1rem, 2vw, 1.5rem) clamp(1rem, 1.8vw, 1.5rem) clamp(1.1rem, 2vw, 1.5rem) 0;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: background-color .16s var(--ease), border-color .16s var(--ease);
}
.doors li + li a { padding-left: clamp(1rem, 1.8vw, 1.5rem); }
.doors a:hover, .doors a:focus-visible { background: var(--stock); border-bottom-color: var(--amber); }
.doors__what {
  font-family: var(--display);
  font-size: clamp(1.05rem, .95rem + .3vw, 1.2rem);
  font-weight: 700; line-height: 1.25; color: var(--navy-deep);
}
.doors__who { grid-column: 1; font-size: .95rem; color: var(--ink-2); }
.doors a::after {
  content: ''; grid-column: 2; grid-row: 1 / span 2;
  width: .6rem; height: .6rem; margin-right: .3rem;
  border-right: 3px solid var(--navy); border-bottom: 3px solid var(--navy);
  transform: rotate(-45deg);
}

/* ---------- 8c. Intro — who we are -------------------------------------- */
.intro {
  padding-block: clamp(2rem, 4vw, 3rem);
  text-align: center;
}
.intro__inner { display: flex; flex-direction: column; align-items: center; }
.intro__text {
  max-width: 44rem;
  font-size: clamp(1rem, .95rem + .3vw, 1.12rem);
  line-height: 1.65;
  color: var(--ink);
  text-wrap: pretty;
}
.intro__hl { color: var(--navy); font-weight: 600; }
.intro__action { margin-top: 1.4rem; }

/* ---------- 10. Our why -------------------------------------------------
   The problem told twice: a big heading and a short statement beside a
   photograph, then three sourced figures on navy cards underneath.
   -------------------------------------------------------------------------- */
.why { padding-block: clamp(2.75rem, 5vw, 4.25rem); }
.why__grid {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem); align-items: center;
}
.why h2 { font-size: clamp(2.2rem, 1.3rem + 3vw, 3.6rem); margin-bottom: 1.1rem; }
.why__statement {
  font-size: clamp(1.05rem, 1rem + .35vw, 1.25rem);
  line-height: 1.6; color: var(--ink); text-wrap: pretty;
}
.why__turn {
  font-family: var(--display);
  font-size: clamp(1.1rem, 1rem + .5vw, 1.35rem);
  font-weight: 600; line-height: 1.4; color: var(--navy-deep);
  margin-top: 1em; text-wrap: pretty;
}
.why__photo { margin: 0; }
.why__photo img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(20, 22, 28, .1), 0 24px 44px -24px rgba(6, 37, 99, .5);
}

/* The figures. White cards lifted off the blue ground, the number in navy
   at medium weight rather than bold, and the source pinned to the bottom so
   every card's source lines up whatever the length of its sentence. */
.why__facts {
  list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem); margin-top: clamp(2rem, 4vw, 3rem);
}
.why__facts > li {
  display: flex; flex-direction: column; gap: .5rem;
  padding: clamp(1.4rem, 2.4vw, 1.9rem);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--stock), #fbfaf7);
  border: 1px solid rgba(11, 62, 160, .1);
  box-shadow: 0 1px 2px rgba(20, 22, 28, .05), 0 16px 32px -22px rgba(6, 37, 99, .35);
}
.why__n {
  margin: 0; font-family: var(--display);
  font-size: clamp(2.2rem, 1.5rem + 2.2vw, 3.2rem);
  font-weight: 500; line-height: 1; letter-spacing: -0.02em; color: var(--navy);
}
.why__label { margin: 0; font-size: 1rem; line-height: 1.5; color: var(--ink-2); }
.why__src { margin: auto 0 0; padding-top: .6rem; font-size: .88rem; font-weight: 500; }
.why__src a { color: var(--navy); text-decoration: underline; text-decoration-color: rgba(11, 62, 160, .3); }
.why__src a:hover { text-decoration-color: currentColor; }

/* ---------- 11. What we do ----------------------------------------------- */
.does { border-top: 1px solid var(--rule); padding-block: clamp(2.5rem, 4.5vw, 3.75rem); }
.does__head { max-width: 42rem; margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.does__lede { font-size: var(--t3); color: var(--ink-2); margin-top: 1.1rem; }
.does__list {
  list-style: none; display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.75rem, 3.5vw, 3rem);
}
/* A hairline, not the 5px amber slab that used to sit here. It is enough to
   make the three read as one set rather than three loose paragraphs. */
.does__list > li { border-top: 1px solid var(--rule); padding-top: 1.15rem; }
.does__list h3 { margin-bottom: .5rem; }
.does__list p { font-size: 1rem; color: var(--ink-2); }

/* ---------- 12. The work so far — counts -------------------------------
   Counts, and only counts. The numeral column is `auto`, which in CSS Grid
   sizes to the widest content across every row — so figures stay aligned
   down the column as events are added, without hard-coding a width that a
   four-digit number would blow out.
   -------------------------------------------------------------------------- */
/* Our impact: a navy band, centred, each event a row of big white figures
   with an amber icon over each. The total and its parts are set the same
   size on purpose — the split is as much the point as the total. */
.tally {
  color: var(--stock);
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem);
  text-align: center;
}
.tally__head { max-width: 42rem; margin: 0 auto clamp(1.5rem, 3vw, 2.25rem); }
.tally h2 { color: var(--stock); }

.tally__list { list-style: none; }
.tally__list > li {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2rem clamp(1.25rem, 4vw, 3rem);
  align-items: start;
  max-width: 60rem; margin-inline: auto;
}
.tally__list > li + li {
  margin-top: 3rem; padding-top: 3rem;
  border-top: 1px solid rgba(255, 255, 255, .2);
}
.tally__stat { display: flex; flex-direction: column; align-items: center; gap: .5rem; }
.tally__icon { width: 2.1rem; height: 2.1rem; color: var(--amber); margin-bottom: .3rem; }
/* The language badges: an amber speech bubble with the code in navy. */
.tally__icon--lang { width: 2.7rem; height: 2.35rem; }
.tally__n, .tally__part {
  font-family: var(--display);
  font-size: clamp(2.6rem, 1.6rem + 3.4vw, 4.4rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--stock);
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.tally__label { margin: 0; font-size: 1.06rem; color: var(--on-navy); }
.tally__where {
  grid-column: 1 / -1; margin: .25rem 0 0;
  font-family: var(--display); font-style: italic; font-weight: 600;
  font-size: clamp(1.1rem, 1rem + .6vw, 1.4rem); color: var(--amber);
}

/* ---------- 13. What we measure — the comprehension promise -------------
   This band is about SCORES, not counts. Counts live in "The work so far"
   above. Keeping them in separate sections is what stops a number of guides
   reading as a number of people helped.

   THE RULE THAT MUST SURVIVE: every number published here carries its
   denominator. "16 of 23", never "70%". A percentage without its bottom
   number is a claim the work has not earned.
   -------------------------------------------------------------------------- */
.measure {
  background: var(--amber);
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem);
}
/* Nested inside .wide, never sharing its class. A max-width on the container
   itself overrides .wide's own and then `margin-inline: auto` centres the
   whole block away from the left rail — the same trap the hero head fell into
   once. Keep the width cap on an inner element. */
.measure__inner { max-width: 54rem; }
.measure__figure {
  font-family: var(--display);
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.4rem);
  font-weight: 600; line-height: 1.22; letter-spacing: -0.01em;
  color: var(--ink); margin: 0; text-wrap: pretty;
}
/* The number itself, when there is one. */
.measure__figure b { color: var(--navy-deep); font-weight: 800; }
.measure__note {
  font-size: 1.06rem;
  color: var(--navy-deep);
  max-width: 42rem;
  margin: 1.8rem 0 0;
}

/* ---------- 14. The guides ----------------------------------------------- */
.guides {
  background: var(--stock-2); border-top: 1px solid var(--rule);
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem);
}
.guides__head { max-width: 40rem; margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.guides__lede { font-size: var(--t3); color: var(--ink-2); margin-top: 1rem; }
.shelf {
  list-style: none; display: grid;
  /* min() is doing real work: a bare minmax(26rem, 1fr) track cannot shrink
     below its own minimum and would force a 468px column onto a 360px
     phone. */
  grid-template-columns: repeat(auto-fill, minmax(min(26rem, 100%), 1fr));
  gap: clamp(1.75rem, 3.5vw, 3rem);
}
.guide {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: 1.6rem; align-items: start;
  background: var(--stock); border: 1px solid var(--rule);
  border-radius: var(--r); padding: clamp(1.35rem, 2.5vw, 2.25rem);
}
.guide__cover {
  display: block; max-width: 15rem;
  border: 1px solid var(--rule);
  box-shadow: 0 1px 2px rgba(20, 22, 28, .12), 0 16px 34px -16px rgba(20, 22, 28, .4);
  transition: transform .28s var(--ease), box-shadow .28s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .guide__cover:hover {
    transform: translateY(-3px);
    box-shadow: 0 1px 2px rgba(20, 22, 28, .14), 0 24px 44px -18px rgba(20, 22, 28, .45);
  }
}
.guide__text > h3 { margin-bottom: .65rem; }
/* The padding is a touch target, not spacing: on an inline box it grows the
   hit area past 44px without moving a single line of type. */
.guide__text > h3 a { color: var(--ink); text-decoration: none; padding-block: .5rem; }
.guide__text > h3 a:hover { color: var(--navy); text-decoration: underline; }
.guide__blurb { font-size: 1rem; color: var(--ink-2); }

@supports selector(:has(*)) {
  @media (min-width: 60rem) {
    .shelf:has(> li:nth-child(1):last-child) { grid-template-columns: minmax(0, 1fr); }
    .shelf:has(> li:nth-child(1):last-child) > .guide {
      grid-template-columns: 21rem minmax(0, 1fr);
      gap: clamp(2.25rem, 4.5vw, 4rem);
      align-items: center;
      padding: clamp(1.75rem, 3vw, 2.75rem);
    }
    .shelf:has(> li:nth-child(1):last-child) .guide__cover { max-width: none; }
    .shelf:has(> li:nth-child(1):last-child) .guide__text > h3 { font-size: 1.9rem; }
    .shelf:has(> li:nth-child(1):last-child) .guide__blurb { font-size: 1.06rem; }
  }
}

/* ---------- 14b. Testimonials -------------------------------------------- */
.voices {
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem);
  background:
    radial-gradient(36rem 22rem at 0% 100%, rgba(244, 168, 56, .12), transparent 70%),
    linear-gradient(180deg, #eef3fc, #e8eefa);
  border-top: 1px solid rgba(11, 62, 160, .14);
}
.quotes { list-style: none; margin-top: clamp(1.5rem, 3vw, 2.25rem); }
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-top: clamp(1.75rem, 3.5vw, 2.5rem);
  border-top: 1px solid rgba(11, 62, 160, .14);
}
.quote blockquote { margin: 0; }
.quote blockquote p {
  font-size: var(--t3); color: var(--ink); margin: 0; text-wrap: pretty;
}
.quote__who { margin: .9rem 0 0; font-size: 1rem; }
.quote__name { display: block; font-weight: 700; color: var(--navy-deep); }
.quote__role { display: block; color: var(--ink-2); }

/* ---------- 15. The workshops -------------------------------------------- */
.workshops { padding-block: clamp(2.5rem, 4.5vw, 3.75rem); }
.workshops__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: start;
}
.workshops__lede { font-size: var(--t3); color: var(--ink-2); margin-top: 1.15rem; }

/* ---------- 16. How we check it ------------------------------------------ */
.review { border-top: 1px solid var(--rule); padding-block: clamp(2.5rem, 4.5vw, 3.5rem); }
.checks { list-style: none; margin-top: 2.25rem; }
.checks > li {
  display: grid;
  grid-template-columns: 1.85rem minmax(0, 1fr);
  gap: .4rem 1.1rem;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--rule);
}
.checks > li:first-child { border-top: 1px solid var(--rule); }
.checks > li > h3 { grid-column: 2; grid-row: 1; }
.checks > li > p  { grid-column: 2; grid-row: 2; margin: 0; font-size: 1rem; color: var(--ink-2); }
.checks .callout { grid-column: 1; grid-row: 1; margin-top: .12em; }

/* ---------- 17. Host ----------------------------------------------------- */
.host {
  background: var(--navy-deep); color: var(--on-navy);
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem);
}
.host__grid {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 4rem); align-items: start;
}
.host h2 { color: var(--stock); }
.host__body p { color: var(--on-navy); }

/* ---------- 18. Volunteer ------------------------------------------------ */
.volunteer {
  background: var(--stock-2); border-top: 1px solid var(--rule);
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem);
}
.volunteer__grid {
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: start;
}
.volunteer__lede { font-size: var(--t3); color: var(--ink-2); margin-top: 1.15rem; }

/* ---------- 19. Photography slots ----------------------------------------
   There are no photographs on this site yet, and there is no placeholder
   pretending to be one. What exists is the layout that will hold them, so
   that adding the first real photograph is a markup change with no CSS to
   write.

   Two slots, both marked in index.html with a commented <figure class="shot">
   and instructions:

     - inside .workshops__grid   a session actually happening
     - inside .host__grid        a room, wide, from the back

   Each section is a two-column grid today. Uncomment a .shot and it becomes
   a three-part layout — the :has() rules below do that automatically, so
   nothing needs editing here when the photographs arrive. A browser without
   :has() keeps the two-column layout and simply stacks the figure, which is
   a perfectly good outcome.
   -------------------------------------------------------------------------- */
.shot { margin: 0; }
.shot img {
  width: 100%;
  border-radius: var(--r);
  box-shadow: 0 1px 2px rgba(20, 22, 28, .1), 0 18px 40px -20px rgba(20, 22, 28, .4);
}
.shot figcaption {
  font-size: .92rem;
  color: var(--ink-2);
  margin-top: .8rem;
}
.host .shot figcaption { color: var(--on-navy-dim); }

@supports selector(:has(*)) {
  @media (min-width: 62rem) {
    .workshops__grid:has(.shot) { grid-template-columns: minmax(0, 1fr) minmax(0, .9fr) minmax(0, 1fr); }
    .host__grid:has(.shot) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, .9fr); }
  }
}

/* ---------- 20. Facts, actions ------------------------------------------- */
.facts { border-top: 1px solid var(--rule); }
.facts > div {
  display: grid; grid-template-columns: 11rem minmax(0, 1fr);
  gap: .3rem 1.5rem; padding: .85rem 0; border-bottom: 1px solid var(--rule);
}
.facts dt {
  font-size: .95rem; font-weight: 600; color: var(--ink-2);
}
.facts dd { color: var(--ink); }
.facts dd strong { font-weight: 800; }
.facts--wide > div { grid-template-columns: 12rem minmax(0, 1fr); }
.host .facts { border-top-color: rgba(255, 255, 255, .2); }
.host .facts > div { border-bottom-color: rgba(255, 255, 255, .2); }
.host .facts dt { color: var(--amber); }
.host .facts dd { color: var(--on-navy); }

.action {
  display: inline-flex; align-items: center; gap: .65rem;
  min-height: 3rem; padding: .85rem 1.7rem;
  border: 3px solid var(--navy); border-radius: var(--r);
  font-size: 1.02rem; font-weight: 800; letter-spacing: -0.01em;
  text-align: center; text-decoration: none;
  transition: background-color .16s var(--ease), color .16s var(--ease),
              border-color .16s var(--ease), transform .1s var(--ease);
}
.action::after {
  content: ''; width: .42rem; height: .42rem;
  border-right: 3px solid currentColor; border-top: 3px solid currentColor;
  transform: rotate(45deg);
}
.action:active { transform: translateY(1px); }
.action--solid { background: var(--navy); color: var(--stock); }
.action--solid:hover, .action--solid:focus-visible {
  background: var(--navy-deep); border-color: var(--navy-deep); color: var(--stock);
}
/* Amber carries dark ink, never white — white on amber is 1.7:1. */
.action--amber { background: var(--amber); border-color: var(--amber); color: var(--ink); }
.action--amber:hover, .action--amber:focus-visible {
  background: var(--amber-lt); border-color: var(--amber-lt); color: var(--ink);
}
.act { display: flex; flex-wrap: wrap; align-items: center; gap: .9rem 1.4rem; margin-top: 1.9rem; }
.act__fine { font-size: .92rem; color: var(--ink-2); }
.host .act__fine { color: var(--on-navy-dim); }

/* ---------- 21. Footer --------------------------------------------------- */
.foot {
  background: var(--navy-deep); color: var(--stock);
  padding-block: clamp(2.25rem, 4vw, 3rem) 1.5rem;
}
.foot__inner {
  display: flex; flex-wrap: wrap; gap: 2.25rem 4rem;
  justify-content: space-between; align-items: flex-start;
}
.foot__brand { display: flex; flex-direction: column; align-items: flex-start; gap: 1rem; }
/* The wordmark is navy, so it sits on white rather than straight on the navy
   footer, where it would disappear. */
.foot__chip { display: inline-flex; background: var(--stock); padding: .85rem 1.15rem; border-radius: var(--r); }
.foot__chip img { width: auto; height: 3.2rem; }
.foot__tagline { font-size: .96rem; color: var(--stock); }
.foot__contact h2 {
  font-size: 1rem; font-weight: 600; color: var(--amber); margin: 0 0 .8rem;
}
.foot__contact ul { list-style: none; display: grid; gap: .25rem; }
/* The same safety net as the headings, for the same reason: the email address
   is 28 unbreakable characters, and in the wider fallback face it does not fit
   a 320px screen, so the footer pushes the page sideways until the face loads.

   `anywhere`, not `break-word`, and the difference is the whole fix.
   `break-word` breaks a long word visually but leaves the element's
   MIN-CONTENT width unchanged — so the flex and grid items above still refuse
   to shrink and the overflow survives. `anywhere` reduces min-content too,
   which is what actually lets the column narrow. The min-width: 0 below does
   the same job for the flex item, since a flex item defaults to
   min-width: auto and will not go under its content otherwise. */
.foot__brand, .foot__contact { min-width: 0; }
.foot__contact ul, .foot__contact li { min-width: 0; }
.foot__contact a {
  display: inline-flex; align-items: center; gap: .7rem; min-height: 44px;
  min-width: 0; overflow-wrap: anywhere;
  color: var(--stock); text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, .4);
}
.foot__contact a:hover { color: var(--amber); text-decoration-color: var(--amber); }
.foot__icon {
  flex: none; width: 1.15rem; height: 1.15rem; color: var(--amber);
  transition: color .16s var(--ease);
}
.foot__contact a:hover .foot__icon { color: var(--stock); }
.foot__note {
  margin-top: 2.6rem; padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, .22);
  color: var(--stock); font-size: .95rem; max-width: 46rem;
}

/* ---------- 21b. Section grounds ----------------------------------------
   No section is a flat colour. Each gets a soft gradient in its own family —
   two faint glows, one amber and one blue, in opposite corners — and one
   quiet ornament: a fading dot grid on the light sections, concentric rings
   on the navy and amber ones.

   Every ornament is a ::before at z-index -1 inside an isolated section, so
   it sits behind the content and can never take a click. The glows are kept
   faint enough that the contrast pairs in the tokens block still hold on the
   darkest and lightest point of each gradient.

   This block sits after the sections on purpose: it overrides their plain
   backgrounds by source order, so each section's own rule stays about
   layout.
   -------------------------------------------------------------------------- */
.intro, .why, .does, .workshops, .review, .guides, .volunteer,
.tally, .measure, .host { position: relative; isolation: isolate; overflow: clip; }

/* Light sections: white warming to cream, the glows swapped between pairs
   so neighbouring sections never mirror each other. */
/* "We check the work" follows "So we teach people to read them" directly,
   so it gets a cool ground and a rule above it rather than more off-white. */
.review {
  background:
    radial-gradient(36rem 22rem at 100% 100%, rgba(244, 168, 56, .12), transparent 70%),
    linear-gradient(180deg, #eef3fc, #e8eefa);
}
.intro {
  background:
    radial-gradient(38rem 22rem at 100% 0%, rgba(244, 168, 56, .12), transparent 70%),
    radial-gradient(34rem 22rem at 0% 100%, rgba(11, 62, 160, .07), transparent 70%),
    linear-gradient(180deg, var(--stock), #fbfaf7);
}
/* Intro, Our why and What we do sit back to back, so each gets a ground of
   its own — white, then a cool blue, then a warm cream — and a faint rule
   where it starts. Three near-identical off-whites read as one long section. */
.why {
  background:
    radial-gradient(36rem 24rem at 100% 100%, rgba(244, 168, 56, .14), transparent 70%),
    linear-gradient(180deg, #eef3fc, #e5ecf9);
}
.does {
  background:
    radial-gradient(40rem 24rem at 100% 0%, rgba(244, 168, 56, .16), transparent 70%),
    linear-gradient(180deg, #f9f6ee, #f3efe4);
}
.workshops {
  background:
    radial-gradient(40rem 26rem at 0% 0%, rgba(11, 62, 160, .08), transparent 70%),
    radial-gradient(36rem 24rem at 100% 100%, rgba(244, 168, 56, .14), transparent 70%),
    linear-gradient(180deg, #fbfaf7, var(--stock));
}
.guides, .volunteer {
  background:
    radial-gradient(44rem 26rem at 100% 0%, rgba(11, 62, 160, .09), transparent 70%),
    radial-gradient(40rem 26rem at 0% 100%, rgba(244, 168, 56, .18), transparent 70%),
    linear-gradient(180deg, #f7f5ef, #f1eee6);
}
/* The gradients already separate these; a hairline on top would be a
   second divider doing the same job. */
.does, .review, .guides, .volunteer { border-top: 0; }
.why, .review { border-top: 1px solid rgba(11, 62, 160, .14); }
.does { border-top: 1px solid rgba(160, 90, 4, .14); }

.intro::before, .why::before, .does::before, .workshops::before,
.review::before, .guides::before, .volunteer::before {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  width: 15rem; height: 11rem; top: 1.5rem; right: 1.5rem;
  background-image: radial-gradient(rgba(11, 62, 160, .2) 1.3px, transparent 1.7px);
  background-size: 18px 18px;
  -webkit-mask-image: radial-gradient(closest-side, #000, transparent);
          mask-image: radial-gradient(closest-side, #000, transparent);
}
.does::before, .guides::before, .review::before {
  top: auto; right: auto; bottom: 1.5rem; left: 1.5rem;
}

/* Navy sections: deep to royal, with a warm glow low on one side. */
.tally, .host, .foot {
  background:
    radial-gradient(46rem 28rem at 88% 0%, rgba(11, 62, 160, .85), transparent 70%),
    radial-gradient(36rem 24rem at 0% 100%, rgba(244, 168, 56, .12), transparent 70%),
    linear-gradient(160deg, var(--navy-deep), #08307f);
}
.tally::before, .host::before, .measure::before {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  width: 30rem; height: 30rem; right: -9rem; top: -12rem;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .09);
  box-shadow: 0 0 0 2.5rem rgba(255, 255, 255, .025), 0 0 0 5rem rgba(255, 255, 255, .02);
}
.host::before { right: auto; top: auto; left: -10rem; bottom: -14rem; }

/* Amber: lit from the top right, deepening toward the bottom left. The
   deepest point still carries navy-deep text at over 6:1. */
.measure {
  background:
    radial-gradient(40rem 24rem at 100% 0%, rgba(255, 224, 168, .75), transparent 70%),
    radial-gradient(40rem 26rem at 0% 100%, rgba(214, 130, 20, .35), transparent 70%),
    var(--amber);
}
.measure::before {
  border-color: rgba(255, 255, 255, .35);
  box-shadow: 0 0 0 2.5rem rgba(255, 255, 255, .1), 0 0 0 5rem rgba(255, 255, 255, .06);
}

/* ---------- 22. Responsive ----------------------------------------------
   Fluid by default; these are the places that need help. Overflow is
   measured, not eyeballed — scrollWidth against innerWidth at 320, 360, 390,
   414, 768, 1024, 1280, 1440 and 1920px.
   -------------------------------------------------------------------------- */
@media (max-width: 60rem) {
  .workshops__grid, .volunteer__grid, .host__grid,
  .why__grid, .why__facts { grid-template-columns: minmax(0, 1fr); }
  .does__list { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; }

  .doors ul { grid-template-columns: minmax(0, 1fr); }
  .doors li + li { border-left: 0; border-top: 1px solid var(--rule); }
  .doors a, .doors li + li a { padding: 1rem 0; }
}

@media (max-width: 40rem) {
  /* Three across still fits a phone once the figures come down a size. */
  .tally__list > li { gap: 1.5rem .75rem; }
  .tally__n, .tally__part { font-size: 2.2rem; }
  .tally__label { font-size: .92rem; }

  .brand__mark { height: 2.6rem; }
  .brand__tagline { font-size: .9rem; padding-left: .75rem; }
  .topnav ul { gap: 0 1.2rem; }

  .facts > div, .facts--wide > div { grid-template-columns: minmax(0, 1fr); gap: .1rem; }
  .facts dt { padding-top: 0; }
}

@media (max-width: 34rem) {
  .guide__cover { max-width: 12rem; }
  .action { width: 100%; justify-content: center; }
  .act { flex-direction: column; align-items: stretch; }
  .act__fine { text-align: center; }
  .foot__inner { gap: 2rem; }
  .foot__chip img { height: 2.8rem; }
}

/* THIS BREAKPOINT IS IN PIXELS ON PURPOSE, and changing it to rem will
   quietly break the page.

   Inside a media query, `rem` always resolves against the browser's INITIAL
   root font size — 16px — and ignores `html { font-size: 18px }` above.
   So `max-width: 22.5rem` here meant 360px, not the 405px it looks like,
   and every phone between 361px and 400px fell through the gap: the
   headline kept its full size and overran its own box by up to 18px.
   Measured at 360, 375, 390, 405 and 414px, not eyeballed.

   Below this width the clamp's own floor is wider than the screen can hold,
   so the floor comes down. */
@media (max-width: 400px) {
  :root { --t1: 2.3rem; }
  .hero h1 { font-size: var(--t1); }
}

/* On a portrait phone the crop is narrow, and centred it lands between the
   parent and the doctor. Shifted right it keeps the child and the doctor's
   hands and guide in frame. */
@media (max-width: 40rem) {
  .hero { min-height: clamp(28rem, 78svh, 40rem); }
  .hero__photo { object-position: 62% 30%; }
}
