/* ==========================================================================
   Innovation Grove: grove.css
   Design system for the rebuilt home and Experience pages.
   Built from the September 2026 design canvas: cream paper, forest green
   bands, hot pink display type, coral quote band, hand-lettered module tags.
   Every parent facing page loads this file; nothing links styles.css now.
   Rule for this file: no em dashes or en dashes anywhere, copy or comments.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Paper and cream, sampled from the mockup */
  --paper: #FBF5EA;
  --paper-deep: #F3E7D3;
  --cream: #FFF1D9;
  --card: #FFFBF7;

  /* Greens */
  --forest: #253D0E;
  --forest-deep: #1A2C08;
  --moss: #4F6B2A;
  --leaf: #64C466;

  /* Warm accents */
  --pink: #FF3266;
  --pink-deep: #D8174C;
  /* Ink for pink text on a pink tint, and the pressed face of a pink button.
     Darker than --pink-deep so short labels on the 10 to 12 percent tints
     clear 4.5:1. */
  --pink-text: #B8123F;
  --coral: #FF7A78;
  --marker: #B84E14;
  --butter: #F5C542;
  --sky: #4D8EF0;

  /* Ink */
  --ink: #1E2415;
  --ink-soft: rgba(30, 36, 21, 0.74);
  --ink-mute: rgba(30, 36, 21, 0.66);
  --line: rgba(37, 61, 14, 0.16);
  --line-strong: rgba(37, 61, 14, 0.32);
  /* The boundary of a form control: inputs, choice cards and their marks, the
     switch track, ghost buttons. Darker than --line-strong so an empty field
     edge clears the 3:1 minimum for a control boundary. Keep --line-strong for
     rules, tags and other decoration. */
  --control-line: rgba(37, 61, 14, 0.55);

  /* Type */
  --display: 'Jost', 'Avenir Next', 'Helvetica Neue', Arial, sans-serif;
  --body: 'Mulish', 'Avenir Next', 'Helvetica Neue', Arial, sans-serif;
  --serif: 'Fraunces', 'Iowan Old Style', 'Palatino', Georgia, serif;
  --hand: 'Caveat', 'Bradley Hand', 'Segoe Print', cursive;

  /* Rhythm */
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --measure: 62ch;
  --radius: 22px;
  --radius-lg: 30px;
  --header-h: 76px;
  --subnav-h: 61px;

  --shadow-card: 0 1px 2px rgba(37, 61, 14, 0.06), 0 18px 48px -24px rgba(37, 61, 14, 0.35);
  --shadow-lift: 0 2px 4px rgba(37, 61, 14, 0.06), 0 28px 60px -28px rgba(37, 61, 14, 0.45);

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Registration switch (see site-config.js). Default, with no JS, is closed. */
html:not([data-registration="open"]) [data-when="open"] { display: none !important; }
html[data-registration="open"] [data-when="closed"] { display: none !important; }

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}
/* Glide for in-page anchor clicks only; arriving at /program_details#winter from
   another page jumps straight there instead of animating past two sections. */
html:focus-within { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html:focus-within { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1.05rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { text-decoration-color: var(--pink); }

:focus-visible {
  outline: 3px solid var(--pink);
  outline-offset: 3px;
  border-radius: 4px;
}

h1, h2, h3, h4 { margin: 0; font-family: var(--display); line-height: 1.02; font-weight: 700; letter-spacing: 0.005em; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
/* Marker-less lists need role="list" in the markup so WebKit keeps list semantics. */
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
address { font-style: normal; }

.skip-link {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 1000;
  padding: 0.6rem 1rem;
  background: var(--forest);
  color: var(--cream);
  border-radius: 999px;
  font-family: var(--display);
  transition: top 0.2s;
}
.skip-link:focus { top: 1rem; }

.wrap { width: min(100% - 2 * var(--gutter), 1240px); margin-inline: auto; }
.wrap--narrow { width: min(100% - 2 * var(--gutter), 900px); margin-inline: auto; }

/* Type helpers */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--moss);
}
.eyebrow::before {
  content: "";
  width: 1.6rem;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  opacity: 0.7;
}
.eyebrow--pink { color: var(--pink-deep); }
.eyebrow--cream { color: var(--cream); opacity: 0.85; }

.display {
  font-size: clamp(2.2rem, 4.6vw, 3.6rem);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 0.98;
}
.display--pink { color: var(--pink); }
.display--forest { color: var(--forest); }
.display--cream { color: var(--cream); }

.lead { font-size: clamp(1.12rem, 1.5vw, 1.32rem); line-height: 1.55; color: var(--ink-soft); max-width: var(--measure); }
.copy { max-width: var(--measure); color: var(--ink-soft); }
.copy strong { color: var(--ink); font-weight: 700; }

.hand {
  font-family: var(--hand);
  font-weight: 700;
  font-size: 1.55rem;
  line-height: 1.1;
  color: var(--marker);
}

.serif-quote {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 450;
  font-variation-settings: "SOFT" 100;
  letter-spacing: -0.005em;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.95rem 1.5rem;
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.98rem;
  letter-spacing: 0.02em;
  text-decoration: none;
  line-height: 1;
  border: 2px solid transparent;
  transition: transform 0.35s var(--ease-out), background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.35s var(--ease-out);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn svg { width: 1.05em; height: 1.05em; flex: none; }

.btn--pink { background: var(--pink-deep); color: #fff; box-shadow: 0 10px 24px -12px rgba(216, 23, 76, 0.7); }
.btn--pink:hover { background: var(--pink-text); }
.btn--forest { background: var(--forest); color: var(--cream); }
.btn--forest:hover { background: var(--forest-deep); }
.btn--cream { background: var(--cream); color: var(--forest); }
.btn--cream:hover { background: #fff; }
.btn--ghost { border-color: var(--control-line); color: var(--forest); background: transparent; }
.btn--ghost:hover { border-color: var(--forest); background: rgba(37, 61, 14, 0.05); }
.btn--ghost-cream { border-color: rgba(255, 241, 217, 0.5); color: var(--cream); background: transparent; }
.btn--ghost-cream:hover { border-color: var(--cream); background: rgba(255, 241, 217, 0.08); }

.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--display);
  font-weight: 600;
  text-decoration: none;
  color: var(--forest);
  padding: 0.5rem 0;
  margin: -0.5rem 0;
}
.arrow-link svg { width: 1.1em; height: 1.1em; transition: transform 0.3s var(--ease-out); }
.arrow-link:hover svg { transform: translateX(4px); }
.arrow-link:hover { color: var(--pink-deep); }

/* Photo frames: every photo sits in a frame with a fixed aspect ratio so the
   layout is identical before and after the real photographs are dropped in. */
.photo {
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: var(--paper-deep);
  aspect-ratio: var(--ratio, 4 / 3);
}
.photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.photo--3x2 { --ratio: 3 / 2; }
.photo--4x3 { --ratio: 4 / 3; }
.photo--4x5 { --ratio: 4 / 5; }
.photo--16x9 { --ratio: 16 / 9; }
.photo--square { --ratio: 1; }

/* --------------------------------------------------------------------------
   3. Header and navigation
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(251, 245, 234, 0.88);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s, background-color 0.3s;
}
.site-header.is-scrolled { border-bottom-color: var(--line); }

.site-header__inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.brand { display: inline-flex; align-items: center; text-decoration: none; }
.brand img { height: 46px; width: auto; }

.nav { display: flex; align-items: center; gap: clamp(1.1rem, 2.2vw, 2rem); }
.nav a {
  position: relative;
  font-family: var(--display);
  font-weight: 500;
  font-size: 0.98rem;
  letter-spacing: 0.01em;
  color: var(--forest);
  text-decoration: none;
  padding: 0.75rem 0;
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--pink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease-out);
}
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a.nav__cta {
  padding: 0.6rem 1.1rem;
  border-radius: 999px;
  background: var(--pink-deep);
  color: #fff;
  font-weight: 600;
}
.nav a.nav__cta::after { display: none; }
.nav a.nav__cta:hover { background: var(--pink-text); }

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.9rem;
  border-radius: 999px;
  border: 1.5px solid transparent;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--forest);
}
.nav-toggle__lines { position: relative; width: 18px; height: 12px; }
.nav-toggle__lines::before, .nav-toggle__lines::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform 0.3s var(--ease-out), top 0.3s var(--ease-out);
}
.nav-toggle__lines::before { top: 0; }
.nav-toggle__lines::after { top: 10px; }

/* Full-screen menu on small screens */
.menu {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--forest);
  color: var(--cream);
  padding: 1.1rem var(--gutter) 1.5rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity 0.3s, transform 0.4s var(--ease-out), visibility 0s linear 0.3s;
}
.menu.is-open { opacity: 1; visibility: visible; transform: none; transition: opacity 0.3s, transform 0.4s var(--ease-out); }
.menu__top { display: flex; justify-content: space-between; align-items: center; height: calc(var(--header-h) - 2.2rem); }
.menu__top .brand img { height: 40px; filter: brightness(0) saturate(100%) invert(96%) sepia(12%) saturate(500%) hue-rotate(320deg) brightness(104%); }
.menu__close {
  padding: 0.55rem 0.95rem;
  border-radius: 999px;
  border: 1.5px solid rgba(255, 241, 217, 0.45);
  font-family: var(--display);
  font-weight: 600;
  color: var(--cream);
}
.menu__links { display: grid; align-content: safe center; gap: 0.2rem; }
.menu__links a {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.6rem, min(8vw, 9vh), 3rem);
  line-height: 1.15;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--cream);
  text-decoration: none;
  padding: 0.2rem 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.8rem;
}
.menu__links a small { font-family: var(--hand); font-size: 1.2rem; text-transform: none; color: var(--butter); font-weight: 700; }
.menu__links a[aria-current="page"] { color: var(--butter); }
.menu__foot { font-size: 0.95rem; color: rgba(255, 241, 217, 0.7); }
.menu__foot a { color: var(--cream); }

@media (max-width: 880px) {
  .nav { display: none; }
  .nav-toggle { display: inline-flex; padding: 0.7rem 1rem; }
  :root { --header-h: 68px; }
  .brand img { height: 40px; }
  /* No JavaScript: the button cannot open the menu, so show the plain links. */
  html.no-js .nav-toggle { display: none; }
  html.no-js .site-header { position: relative; }
  html.no-js .site-header__inner { height: auto; min-height: var(--header-h); flex-wrap: wrap; padding: 0.6rem 0 0.8rem; }
  html.no-js .nav { display: flex; flex-wrap: wrap; width: 100%; gap: 0 1rem; }
}

/* --------------------------------------------------------------------------
   4. Home: hero
   The copy sits straight on the drawing. The headline is on the page when it
   opens and leaves word by word as the colour goes down; the sentence arrives
   word by word once the photograph is in. grove.js wraps every word in a .w
   span numbered --i and drives two numbers on the section: --hero-p, the
   scroll progress, and --hero-intro, the first second and a half after the
   drawing appears. Each word turns those into its own opacity and offset.
   Without the script (or the live class) the copy stands still on the poster.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  min-height: min(88vh, 900px);
  display: grid;
  place-items: center;
  padding: clamp(2.5rem, 7vh, 5rem) 0 clamp(4rem, 10vh, 7rem);
  overflow: hidden;
}
.hero__backdrop {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--paper-deep);
}
.hero__backdrop img { width: 100%; height: 100%; object-fit: cover; }
.hero__backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(37, 61, 14, 0.18), rgba(37, 61, 14, 0) 30%, rgba(37, 61, 14, 0.28) 100%);
}

.hero__copy {
  display: grid;
  justify-items: center;
  gap: clamp(1.2rem, 2.6vw, 2rem);
  width: min(100% - 2 * var(--gutter), 1320px);
  text-align: center;
}
.hero__title {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(2.9rem, 7.3vw, 7.4rem);
  line-height: 1.02;
  letter-spacing: -0.015em;
  text-transform: uppercase;
  color: var(--cream);
  text-wrap: balance;
}
.hero__line { display: block; }
.hero__title em { font-style: normal; color: var(--pink); }
.hero__lead {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-style: italic;
  font-variation-settings: 'SOFT' 60, 'opsz' 96;
  font-size: clamp(1.45rem, 2.8vw, 2.7rem);
  line-height: 1.3;
  max-width: 30ch;
  color: var(--cream);
  text-shadow: 0 1px 2px rgba(10, 18, 4, 0.45), 0 2px 12px rgba(10, 18, 4, 0.35);
  text-wrap: balance;
}
.hero .w { display: inline-block; }

.hero__scroll {
  position: absolute;
  left: 50%;
  bottom: 1.4rem;
  transform: translateX(-50%);
  font-family: var(--hand);
  font-size: 1.65rem;
  color: var(--cream);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.hero__scroll svg { width: 22px; height: 22px; animation: nudge 1.8s ease-in-out infinite; }
@keyframes nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
@media (max-height: 720px) { .hero__scroll { display: none; } }

/* --------------------------------------------------------------------------
   5. Home: green band, program cards, next steps
   -------------------------------------------------------------------------- */
.band {
  background: var(--forest);
  color: var(--cream);
  padding: clamp(3.5rem, 8vw, 6rem) 0;
  position: relative;
}
.band__head { text-align: center; max-width: 56ch; margin: 0 auto 2.5rem; }
.band__title { font-size: clamp(1.7rem, 3.4vw, 2.6rem); color: var(--cream); line-height: 1.1; }
.band__title .hand { color: var(--butter); font-size: 0.72em; display: block; margin-top: 0.4rem; }
.band__note { margin-top: 1.1rem; color: rgba(255, 241, 217, 0.82); font-size: 1.08rem; }
.band__note a { color: var(--cream); text-decoration-color: rgba(255, 241, 217, 0.45); }
.band__note a:hover { text-decoration-color: var(--butter); }

.program-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
}
.pcard {
  background: var(--cream);
  color: var(--forest);
  border-radius: var(--radius-lg);
  padding: clamp(1.6rem, 3.5vw, 2.6rem) clamp(1.4rem, 3vw, 2.4rem);
  display: grid;
  gap: 1.2rem;
  align-content: start;
  position: relative;
  overflow: hidden;
}
.pcard__title { font-size: clamp(1.5rem, 2.6vw, 2.1rem); text-transform: uppercase; color: var(--forest); }
.pcard__items { display: flex; flex-wrap: wrap; gap: 0.6rem 0.75rem; }
.pcard__items a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1rem;
  border-radius: 999px;
  border: 1.5px solid var(--line-strong);
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  text-decoration: none;
  color: var(--forest);
  transition: background-color 0.2s, border-color 0.2s, transform 0.3s var(--ease-out);
}
/* One green, three steps of it, so a glance counts the programs. */
.pcard__items a { background: var(--forest); color: var(--cream); }
.pcard__items a:nth-child(2) { background: #3A5418; }
.pcard__items a:nth-child(3) { background: var(--moss); }
.pcard__items a:hover { transform: translateY(-2px); box-shadow: 0 10px 22px -14px rgba(37, 61, 14, 0.8); }
.pcard__items a svg { width: 0.9em; height: 0.9em; }
.pcard__items span { display: inline-flex; align-items: center; font-family: var(--display); font-weight: 600; font-size: 1.15rem; color: var(--forest); }
.pcard__items span + span::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--line-strong); margin: 0 0.85rem; }
.pcard__foot { font-size: 0.98rem; color: var(--ink-soft); max-width: 40ch; }

.band__cta {
  margin-top: 2.5rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 1rem 1.6rem;
  text-align: center;
}
.band__cta p { font-size: 1.05rem; color: rgba(255, 241, 217, 0.85); }

@media (max-width: 720px) {
  .program-cards { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   6. Photo strip (marquee)
   -------------------------------------------------------------------------- */
.strip {
  --tile-h: clamp(235px, 31vw, 420px);
  position: relative;
  padding: clamp(1.2rem, 2vw, 1.6rem) 0;
  background: var(--paper);
  overflow: hidden;
}
/* Spacing lives on the tile, not as a flex gap, so the cloned half is exactly 50% of the track. */
.strip__track {
  display: flex;
  width: max-content;
}
.strip.is-ready .strip__track { animation: strip-scroll 90s linear infinite; }
.strip:hover .strip__track { animation-play-state: paused; }
.strip__tile {
  height: var(--tile-h);
  flex: none;
  margin-right: 0.75rem;
  border-radius: 16px;
  overflow: hidden;
  background: var(--paper-deep);
}
.strip__tile img { height: 100%; width: auto; object-fit: cover; display: block; }
.strip__tile:nth-child(odd) { transform: translateY(6px); }
@keyframes strip-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.strip.is-paused .strip__track, .strip:focus-within .strip__track { animation-play-state: paused; }
.strip__pause {
  position: absolute;
  right: calc(var(--gutter) + 0.25rem);
  bottom: calc(clamp(1.2rem, 2vw, 1.6rem) + 0.6rem);
  z-index: 2;
  width: 34px;
  height: 34px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(37, 61, 14, 0.55);
  color: var(--cream);
  opacity: 0.55;
  transition: opacity 0.25s, background-color 0.25s;
}
.strip:hover .strip__pause, .strip__pause:focus-visible, .strip.is-paused .strip__pause { opacity: 1; background: rgba(37, 61, 14, 0.8); }
.strip__pause-icon { width: 14px; height: 14px; }
.strip__pause-icon--play { display: none; }
.strip.is-paused .strip__pause-icon--play { display: block; }
.strip.is-paused .strip__pause-icon--pause { display: none; }
.strip__pause[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .strip { overflow-x: auto; scroll-snap-type: x proximity; padding-inline: var(--gutter); }
  .strip__track { animation: none; }
  .strip__tile { scroll-snap-align: start; }
  .strip__tile:nth-child(odd) { transform: none; }
  .strip__pause { display: none; }
  .hero__scroll svg { animation: none; }
}
html.no-js .strip { overflow-x: auto; scroll-snap-type: x proximity; padding-inline: var(--gutter); }
html.no-js .strip__tile { scroll-snap-align: start; }
html.no-js .strip__tile:nth-child(odd) { transform: none; }
html.no-js .strip__pause { display: none; }

/* --------------------------------------------------------------------------
   7. Student quote band
   -------------------------------------------------------------------------- */
.quote-band {
  background: var(--coral);
  color: var(--forest-deep);
  padding: clamp(2rem, 4vw, 3.2rem) 0;
  text-align: center;
}
.quote-band figure { margin: 0 auto; max-width: 62ch; }
.quote-band blockquote { margin: 0; }
.quote-band p {
  font-size: clamp(1.5rem, 3vw, 2.35rem);
  line-height: 1.25;
  margin: 0;
}
.quote-band figcaption {
  display: block;
  margin-top: 1.2rem;
  font-style: normal;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.86rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   9. Parent quotes (speech bubbles)
   -------------------------------------------------------------------------- */
.parents { background: var(--cream); padding: clamp(3.5rem, 8vw, 6.5rem) 0 clamp(4rem, 9vw, 7rem); }
.parents__head { text-align: center; margin-bottom: clamp(2rem, 4vw, 3.2rem); }
.parents__head .display { margin-bottom: 0.6rem; }
.parents__head p { color: var(--ink-soft); font-size: 1.05rem; }

/* Filled blocks that overlap like paper cutouts. Three staggered columns fill the
   container on wide screens; each column drifts at its own pace on scroll (grove.js).
   Colours are the canvas fills. White type on the green, coral and blue blocks is the
   designer's call; ink on the yellow one. */
.parents__sub { font-size: 1.3rem; color: var(--forest); }
.collage {
  --tile-leaf: #74BF72;
  --tile-coral: #FB6B6D;
  --tile-sky: #5090FF;
  --tile-butter: #F5CE5C;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  column-gap: 0.9rem;
  padding: 1.5rem 0 3rem;
}
/* The columns keep their slight horizontal overlap, but nothing overlaps
   vertically: a card in a column never sits on the one above or below it. */
.collage__col { position: relative; display: grid; row-gap: 1rem; will-change: transform; }
.collage__col + .collage__col { margin-left: -0.55rem; }
.collage__col:nth-child(1) { z-index: 3; padding-top: 0.5rem; }
.collage__col:nth-child(2) { z-index: 2; padding-top: 5.5rem; }
.collage__col:nth-child(3) { z-index: 1; padding-top: 2.6rem; }

.tile {
  position: relative;
  margin: 0;
  padding: 1.8rem 1.9rem 1.7rem;
  border-radius: 24px;
  text-align: center;
  color: #fff;
  background: var(--tile-leaf);
  font-size: 1.04rem;
  line-height: 1.5;
  box-shadow: 0 1px 2px rgba(37, 61, 14, 0.06), 0 22px 44px -30px rgba(37, 61, 14, 0.55);
  transition: translate 0.5s var(--ease-out), box-shadow 0.5s var(--ease-out);
}
.tile:hover { translate: 0 -4px; box-shadow: 0 2px 3px rgba(37, 61, 14, 0.06), 0 30px 50px -28px rgba(37, 61, 14, 0.6); }
.tile + .tile { z-index: 1; }
.tile blockquote { margin: 0; }
.tile p { margin: 0; font-weight: 600; }
.tile figcaption { margin-top: 0.6rem; font-style: italic; font-size: 0.95rem; opacity: 0.95; }
.tile--coral { background: var(--tile-coral); }
.tile--sky { background: var(--tile-sky); }
.tile--butter { background: var(--tile-butter); color: var(--ink); }
.tile--butter figcaption { opacity: 0.85; }

/* A degree or so of tilt, alternating, so the blocks read as placed by hand */
.collage__col:nth-child(1) .tile:nth-child(1) { rotate: -1.3deg; }
.collage__col:nth-child(1) .tile:nth-child(2) { rotate: 0.7deg; }
.collage__col:nth-child(2) .tile:nth-child(1) { rotate: 0.9deg; }
.collage__col:nth-child(2) .tile:nth-child(2) { rotate: -1deg; }
.collage__col:nth-child(3) .tile:nth-child(1) { rotate: -0.6deg; }
.collage__col:nth-child(3) .tile:nth-child(2) { rotate: 1.1deg; }

@media (max-width: 1000px) {
  .collage { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem 1rem; }
  .collage__col { display: contents; }
  .tile, .tile + .tile { margin: 0; }
}
@media (max-width: 600px) {
  .collage { display: flex; flex-direction: column; gap: 1rem; max-width: 560px; margin: 0 auto; }
  .collage__col:nth-child(1) .tile:nth-child(1) { margin-right: 9%; }
  .collage__col:nth-child(1) .tile:nth-child(2) { margin-left: 9%; }
  .collage__col:nth-child(2) .tile:nth-child(1) { margin-right: 9%; }
  .collage__col:nth-child(2) .tile:nth-child(2) { margin-left: 9%; }
  .collage__col:nth-child(3) .tile:nth-child(1) { margin-right: 9%; }
  .collage__col:nth-child(3) .tile:nth-child(2) { margin-left: 9%; }
}
@media (prefers-reduced-motion: reduce) {
  .tile { transition: none; }
  .tile:hover { translate: none; }
}

/* --------------------------------------------------------------------------
   10. What's next (upcoming academies)
   -------------------------------------------------------------------------- */
.upnext { padding: clamp(4rem, 9vw, 7rem) 0; }
.upnext__head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 1rem 2rem; margin-bottom: 2rem; }
.upnext__head .display { font-size: clamp(2rem, 4vw, 3.2rem); }
.upnext__head p { max-width: 42ch; color: var(--ink-soft); }

.slate { border-top: 1px solid var(--line-strong); }
.slate__row {
  display: grid;
  grid-template-columns: 4rem minmax(0, 1.2fr) minmax(0, 2fr) auto;
  gap: 1rem 2rem;
  align-items: center;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  transition: background-color 0.2s;
}
.slate__row:hover { background: rgba(255, 241, 217, 0.6); }
.slate__num { font-family: var(--display); font-weight: 600; color: var(--pink-deep); letter-spacing: 0.08em; }
.slate__when { font-family: var(--display); font-weight: 600; font-size: 1.2rem; color: var(--forest); text-transform: uppercase; letter-spacing: 0.02em; }
.slate__what strong { display: block; font-family: var(--display); font-weight: 600; font-size: 1.15rem; color: var(--ink); }
.slate__what span { color: var(--ink-soft); font-size: 0.98rem; }
.slate__go { display: inline-flex; align-items: center; gap: 0.4rem; font-family: var(--display); font-weight: 600; color: var(--forest); }
.slate__go svg { width: 1.1em; height: 1.1em; transition: transform 0.3s var(--ease-out); }
.slate__row:hover .slate__go svg { transform: translateX(4px); }
.slate__row:hover .slate__go { color: var(--pink-deep); }

.tag {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  vertical-align: middle;
  margin-left: 0.4rem;
}
.tag--butter { background: var(--butter); color: var(--forest); }
.tag--leaf { background: var(--leaf); color: var(--forest); }
.tag--line { border: 1.5px solid var(--line-strong); color: var(--moss); }

@media (max-width: 760px) {
  .slate__row { grid-template-columns: 3rem minmax(0, 1fr); }
  .slate__what { grid-column: 2; }
  .slate__go { grid-column: 2; }
}

/* --------------------------------------------------------------------------
   11. Footer
   -------------------------------------------------------------------------- */
.site-footer { background: var(--forest); color: var(--cream); padding: clamp(3.5rem, 8vw, 6rem) 0 2rem; }
.footer-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1rem, 2.5vw, 2rem); }
.fcard {
  background: var(--cream);
  color: var(--forest);
  border-radius: var(--radius-lg);
  padding: clamp(1.6rem, 3.5vw, 2.6rem);
  display: grid;
  gap: 0.9rem;
  align-content: start;
}
.fcard__title { font-size: clamp(1.5rem, 2.6vw, 2.1rem); text-transform: uppercase; }
.fcard p { color: var(--ink-soft); max-width: 36ch; }
.fcard .btn { justify-self: start; }
.fcard__email { font-family: var(--display); font-weight: 600; font-size: 1.15rem; color: var(--forest); word-break: break-all; }

.footer-bottom {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.6rem;
  border-top: 1px solid rgba(255, 241, 217, 0.18);
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 1.5rem 3rem;
  align-items: start;
  font-size: 0.95rem;
  color: rgba(255, 241, 217, 0.72);
}
.footer-bottom .wordmark { font-family: var(--display); font-weight: 700; font-size: 1.35rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--cream); margin-bottom: 0.5rem; }
.footer-bottom .wordmark small { display: block; font-size: 0.7rem; letter-spacing: 0.32em; font-weight: 600; opacity: 0.8; }
.footer-nav { display: flex; flex-wrap: wrap; gap: 0 1.4rem; justify-content: flex-end; }
.footer-nav a { display: inline-block; padding: 0.6rem 0; color: var(--cream); text-decoration: none; font-family: var(--display); font-weight: 500; }
.footer-nav a:hover { color: var(--butter); }
.footer-legal { grid-column: 1 / -1; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem 2rem; font-size: 0.85rem; color: rgba(255, 241, 217, 0.62); }

/* Below this the five links no longer fit beside the wordmark, so the nav
   takes a full width row of its own rather than wrapping into a ragged,
   right aligned block. */
@media (max-width: 1100px) {
  .footer-bottom { grid-template-columns: 1fr; }
  .footer-nav { justify-content: flex-start; }
}
@media (max-width: 720px) {
  .footer-cards { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   12. Experience page
   -------------------------------------------------------------------------- */
.xp-hero { padding: clamp(3rem, 7vw, 5.5rem) 0 clamp(2rem, 4vw, 3rem); }
.xp-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: end;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.xp-hero__title { font-size: clamp(2.6rem, 6.4vw, 5rem); color: var(--forest); text-transform: uppercase; line-height: 0.96; }
.xp-hero__title em { font-style: normal; color: var(--pink); }
.xp-hero__title span { white-space: nowrap; }
.xp-hero .lead { margin-bottom: 0; }
.xp-hero__photo { --ratio: 16 / 9; border-radius: var(--radius-lg); }

@media (max-width: 880px) { .xp-hero__grid { grid-template-columns: 1fr; align-items: start; } }

/* Sub navigation for the three academies */
.subnav {
  position: sticky;
  top: var(--header-h);
  z-index: 90;
  background: rgba(251, 245, 234, 0.92);
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.subnav__inner { display: flex; align-items: center; gap: 0.25rem; overflow-x: auto; scrollbar-width: none; }
.subnav__inner::-webkit-scrollbar { display: none; }
.subnav__label { flex: none; font-family: var(--display); font-weight: 600; font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-mute); margin-right: 1rem; }
.subnav a {
  flex: none;
  position: relative;
  padding: 1rem 0.9rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.98rem;
  color: var(--forest);
  text-decoration: none;
  white-space: nowrap;
}
.subnav a::after {
  content: "";
  position: absolute;
  left: 0.9rem;
  right: 0.9rem;
  bottom: -1px;
  height: 3px;
  background: var(--pink);
  border-radius: 3px 3px 0 0;
  transform: scaleX(0);
  transition: transform 0.3s var(--ease-out);
}
.subnav a:hover::after, .subnav a.is-active::after, .subnav a[aria-current]::after { transform: scaleX(1); }
.subnav a small { margin-left: 0.4rem; font-family: var(--hand); font-size: 1rem; color: var(--marker); }
@media (max-width: 720px) {
  .subnav__inner { -webkit-mask-image: linear-gradient(to right, #000 88%, transparent); mask-image: linear-gradient(to right, #000 88%, transparent); padding-right: 2.5rem; }
}

/* Academy sections */
.academy { padding: clamp(4rem, 9vw, 7rem) 0; scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + 0.5rem); }
.academy:has(.coming) { padding: clamp(3rem, 6vw, 5rem) 0; }
.academy + .academy { border-top: 1px solid var(--line); }
.academy__head {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: end;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.academy__title { font-size: clamp(2rem, 4.4vw, 3.4rem); color: var(--forest); text-transform: uppercase; }
.academy__title em { font-style: normal; color: var(--pink); }
@media (max-width: 880px) { .academy__head { grid-template-columns: 1fr; } }

/* Two themed weeks */
.weeks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1rem, 2.5vw, 2rem); margin-bottom: clamp(3rem, 6vw, 5rem); }
.week {
  --accent: var(--sky);
  background: var(--card);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.4rem);
  border: 1px solid var(--line);
  display: grid;
  gap: 1rem;
  align-content: start;
  position: relative;
}
.week--science { --accent: var(--leaf); }
.week__kicker { display: flex; align-items: center; gap: 0.6rem; font-family: var(--display); font-weight: 600; font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-mute); }
.week__kicker::before { content: ""; width: 12px; height: 12px; border-radius: 50%; background: var(--accent); }
.week__title { font-size: clamp(1.5rem, 2.6vw, 2rem); text-transform: uppercase; color: var(--forest); }
.week p { color: var(--ink-soft); }
.week__list { display: grid; gap: 0.5rem; padding-top: 0.6rem; border-top: 1px solid var(--line); }
.week__list li { display: grid; grid-template-columns: auto 1fr; gap: 0.7rem; align-items: baseline; font-size: 0.98rem; }
.week__list li b { font-family: var(--display); font-weight: 600; color: var(--forest); }
.week__list li span { color: var(--ink-soft); }
.weeks__note { grid-column: 1 / -1; display: flex; gap: 0.9rem; align-items: flex-start; padding: 1.2rem 1.4rem; background: var(--cream); border-radius: 18px; color: var(--ink-soft); }
.weeks__note .hand { font-size: 1.4rem; flex: none; margin-top: -0.1rem; }
@media (max-width: 760px) { .weeks { grid-template-columns: 1fr; } }
@media (max-width: 900px) { .week__list { gap: 0.8rem; } .week__list li { grid-template-columns: 1fr; gap: 0.1rem; } }

/* Modules */
.modules__head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 1rem 2rem; margin-bottom: 2rem; }
.modules__head .display { font-size: clamp(2rem, 4vw, 3.2rem); }
.modules__head p { max-width: 46ch; color: var(--ink-soft); }

.module-feature {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.module-feature .photo { --ratio: 4 / 3; }
.module-feature .module__body { padding-right: clamp(0rem, 2vw, 1.5rem); }

.module-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: clamp(1.5rem, 3vw, 2.5rem); }
.module { display: grid; gap: 1rem; align-content: start; grid-column: span 3; }
.module .photo { --ratio: 4 / 3; }
/* Every third module runs the full width with a wider photo, so the run never reads as a card grid. */
.module:nth-child(3n) { grid-column: span 6; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
.module:nth-child(3n) .photo { --ratio: 3 / 2; }
.module:nth-child(6n) .module__body { order: -1; }
/* Module photos read as prints: tight corners, a white matte and a soft shadow, like the designer's example. */
.module .photo, .module-feature .photo {
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(37, 61, 14, 0.08), 0 14px 32px -18px rgba(37, 61, 14, 0.45);
}
.module .photo img, .module-feature .photo img { inset: 6px; width: calc(100% - 12px); height: calc(100% - 12px); border-radius: 4px; }
.module-feature .photo { rotate: -1deg; }
@media (prefers-reduced-motion: no-preference) {
  .module-feature .photo { transition: rotate 0.6s var(--ease-out); }
  .module-feature:hover .photo { rotate: 0deg; }
}
.module__body { display: grid; gap: 0.6rem; }
.module__tag { display: flex; align-items: baseline; gap: 0.7rem; font-weight: 400; line-height: 1.2; }
.module__tag .hand { font-size: clamp(1.7rem, 2.6vw, 2.2rem); }
.module__tag .num { font-family: var(--display); font-weight: 600; font-size: 0.78rem; letter-spacing: 0.16em; color: var(--ink-mute); }
.module__title { margin: 0; font-family: var(--display); font-weight: 700; font-size: 1.32rem; color: var(--forest); line-height: 1.15; }
.module p { color: var(--ink-soft); font-size: 1rem; }
.module__week { display: inline-flex; gap: 0.4rem; flex-wrap: wrap; }

@media (max-width: 880px) {
  .module-feature { grid-template-columns: 1fr; }
  .module:nth-child(3n) { grid-template-columns: 1fr; gap: 1rem; align-items: start; }
  .module:nth-child(3n) .photo { --ratio: 4 / 3; }
  .module:nth-child(6n) .module__body { order: 0; }
}
@media (max-width: 640px) {
  .module-grid { grid-template-columns: 1fr; }
  .module, .module:nth-child(3n) { grid-column: auto; }
}

/* A day at the academy */
.day { margin-top: clamp(3.5rem, 7vw, 6rem); display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(1.5rem, 4vw, 4rem); align-items: start; }
.day__intro .display { font-size: clamp(1.9rem, 3.6vw, 2.8rem); margin-bottom: 1rem; }
.day__intro p { color: var(--ink-soft); }
.timeline { border-top: 1px solid var(--line-strong); }
.timeline li { display: grid; grid-template-columns: 6rem minmax(0, 1fr); gap: 1rem 1.5rem; padding: 1rem 0; border-bottom: 1px solid var(--line); align-items: baseline; }
.timeline time { font-family: var(--display); font-weight: 600; font-size: 1.05rem; color: var(--pink-deep); letter-spacing: 0.02em; white-space: nowrap; }
.timeline b { display: block; font-family: var(--display); font-weight: 600; color: var(--forest); font-size: 1.05rem; }
.timeline span { color: var(--ink-soft); font-size: 0.96rem; }
.timeline li.is-optional time { color: var(--ink-mute); }
@media (max-width: 880px) { .day { grid-template-columns: 1fr; } }

/* The essentials */
.essentials { margin-top: clamp(3.5rem, 7vw, 6rem); display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(1.5rem, 4vw, 4rem); align-items: start; }
.essentials__photo { --ratio: 3 / 2; border-radius: var(--radius-lg); margin: 0; }
.essentials__photo figcaption { position: absolute; left: 1rem; bottom: 1rem; padding: 0.5rem 0.9rem; border-radius: 999px; background: rgba(255, 251, 247, 0.92); font-family: var(--display); font-weight: 600; font-size: 0.82rem; letter-spacing: 0.06em; color: var(--forest); }
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.4rem 2rem; }
.fact { padding-top: 0.9rem; border-top: 2px solid var(--forest); }
.fact dt { font-family: var(--display); font-weight: 600; font-size: 0.78rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--moss); margin-bottom: 0.35rem; }
.fact dd { margin: 0; font-family: var(--display); font-weight: 600; font-size: 1.22rem; color: var(--forest); line-height: 1.25; }
.fact dd small { display: block; margin-top: 0.3rem; font-family: var(--body); font-weight: 400; font-size: 0.95rem; color: var(--ink-soft); }
.fact dd a { display: inline-block; padding: 0.35rem 0; margin: -0.35rem 0; text-decoration-color: var(--line-strong); }
.fact--wide { grid-column: 1 / -1; }
.essentials__cta { margin-top: 2rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.4rem; padding: 1.4rem 1.6rem; background: var(--cream); border-radius: 20px; }
.essentials__cta p { color: var(--ink-soft); flex: 1 1 26ch; }
@media (max-width: 880px) { .essentials { grid-template-columns: 1fr; } .essentials__photo { max-width: 620px; } }
@media (max-width: 560px) { .facts { grid-template-columns: 1fr; } }

/* Coming academies (afterschool, winter) */
.coming { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: clamp(1.5rem, 4vw, 4rem); align-items: start; }
.coming--flip .coming__photo { order: -1; }
.coming__photo { --ratio: 3 / 2; border-radius: var(--radius-lg); }
.coming__line { font-size: 1.3rem; line-height: 1.35; color: var(--forest); margin: 1.4rem 0 1.6rem; }
.coming__cta { display: flex; flex-wrap: wrap; gap: 0.8rem 1rem; align-items: center; }
@media (max-width: 880px) { .coming { grid-template-columns: 1fr; } .coming--flip .coming__photo { order: 0; } }

/* Experts strip */
.experts { margin-top: clamp(3.5rem, 7vw, 6rem); padding: clamp(1.8rem, 4vw, 2.8rem); background: var(--forest); color: var(--cream); border-radius: var(--radius-lg); display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.5rem 3rem; align-items: center; }
.experts h3 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); text-transform: uppercase; color: var(--cream); margin-bottom: 0.6rem; }
.experts p { color: rgba(255, 241, 217, 0.8); max-width: 60ch; }
.experts__fields { display: block; margin-top: 0.9rem; font-family: var(--serif); font-style: italic; font-variation-settings: "SOFT" 100; font-size: 1.1rem; line-height: 1.6; color: var(--cream); }
.experts__fields li { display: inline; }
.experts__fields li:not(:last-child)::after { content: " \00B7 "; opacity: 0.6; }
.experts .btn { justify-self: start; }
@media (max-width: 760px) { .experts { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   13. Reveal on scroll (progressive, no layout shift)
   -------------------------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.7s var(--ease-out), transform 0.9s var(--ease-out); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: 0.08s; }
.reveal[data-delay="2"] { transition-delay: 0.16s; }
.reveal[data-delay="3"] { transition-delay: 0.24s; }
.reveal[data-delay="4"] { transition-delay: 0.32s; }
html.no-js .reveal, html.no-reveal .reveal { opacity: 1; transform: none; }
@media print {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}
.display, .xp-hero__title, .academy__title, .pcard__title, .fcard__title, .experts h3 { text-wrap: balance; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .btn, .arrow-link svg, .slate__go svg { transition: none; }
}

/* Hand-drawn underline accent: an inline SVG placed under a word */
.uline { position: relative; display: inline-block; white-space: nowrap; }
.uline svg { position: absolute; left: -2%; right: -2%; bottom: -0.12em; width: 104%; height: 0.32em; overflow: visible; }
.uline svg path { fill: none; stroke: var(--butter); stroke-width: 6; stroke-linecap: round; }

/* --------------------------------------------------------------------------
   14. About page
   One long editorial read on the paper: a hero beside an instant-film print,
   a drop-cap essay, one green band for the director, a numbered ledger for
   the guests, a hand-drawn stroke through the origin story, the coral
   mission band, and two partner columns joined by a hand-written ampersand.
   -------------------------------------------------------------------------- */

/* Instant-film print: white matte, caption written on the bottom band */
.print {
  margin: 0;
  background: #fff;
  border-radius: 8px;
  padding: 6px 6px 0;
  box-shadow: 0 1px 2px rgba(37, 61, 14, 0.08), 0 14px 32px -18px rgba(37, 61, 14, 0.45);
}
.print .photo { border-radius: 4px; }
.print__caption {
  min-height: 2.3rem;
  padding: 0.5rem 0.4rem 0.45rem;
  font-family: var(--hand);
  font-weight: 700;
  font-size: 1.2rem;
  line-height: 1.1;
  color: var(--marker);
  text-align: right;
}
.print--tilt-l { rotate: -1deg; }
.print--tilt-r { rotate: 1deg; }
@media (prefers-reduced-motion: no-preference) {
  .print--tilt-l, .print--tilt-r { transition: rotate 0.6s var(--ease-out); }
  .print--tilt-l:hover, .print--tilt-r:hover { rotate: 0deg; }
}

/* Portraits: one circle for everyone. The photograph fills it, background and
   all, so the edge is drawn as a deliberate ring: a hairline where the picture
   stops, a paper mount around it, and one soft shadow so the circle sits on
   the page rather than floating over it. */
.portrait {
  display: block;
  width: 120px;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 50%;
  background: var(--paper-deep);
  box-shadow:
    0 0 0 1px rgba(37, 61, 14, 0.22),
    0 0 0 4px var(--card),
    0 0 0 5px var(--line),
    0 10px 22px -12px rgba(37, 61, 14, 0.45);
}
.portrait--lg {
  width: 240px;
  box-shadow:
    0 0 0 1px rgba(37, 61, 14, 0.22),
    0 0 0 6px var(--card),
    0 0 0 7px var(--line),
    0 16px 34px -16px rgba(37, 61, 14, 0.5);
}
/* On the green band the mount is the band's own cream, and the shadow has to
   be deep enough to read against the forest. */
.band .portrait {
  box-shadow:
    0 0 0 1px rgba(26, 44, 8, 0.35),
    0 0 0 6px var(--cream),
    0 18px 34px -16px rgba(10, 20, 2, 0.6);
}

/* Hero */
.about-hero { padding: clamp(3rem, 7vw, 5.5rem) 0 clamp(4rem, 9vw, 7rem); }
.about-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.about-hero .lead { margin: 1.4rem 0 0; }
.about-hero .print { max-width: 440px; width: 100%; justify-self: end; }
@media (max-width: 880px) {
  .about-hero__grid { grid-template-columns: 1fr; align-items: start; }
  .about-hero .print { justify-self: start; max-width: 380px; }
}

/* Why we built this: the essay */
.essay { padding: clamp(4rem, 9vw, 7rem) 0; border-top: 1px solid var(--line); }
.essay__head .hand { display: block; margin-top: 0.45rem; font-size: clamp(1.5rem, 2.4vw, 2rem); }
.essay__grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}
.essay__body .copy p { font-size: 1.08rem; }
.essay__body .copy p + p { margin-top: 1rem; }
.essay__pull { margin-top: 1.8rem; }
.essay__body .copy > p:first-child::first-letter {
  float: left;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 600;
  font-variation-settings: "SOFT" 100;
  font-size: 4.1em;
  line-height: 0.8;
  color: var(--pink);
  margin: 0.1em 0.14em 0 0;
}
.aside .eyebrow { margin-bottom: 0.6rem; }
.toolbox { border-top: 1px solid var(--line-strong); }
.toolbox li {
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--line);
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--forest);
}
.aside__note { margin: 1rem 0 0; font-size: 1.4rem; max-width: 22ch; }
@media (max-width: 880px) {
  .essay__grid { grid-template-columns: 1fr; }
  .toolbox { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1.5rem; }
}
@media (max-width: 480px) {
  .toolbox { grid-template-columns: 1fr; }
  .essay__body .copy > p:first-child::first-letter { font-size: 3.6em; }
}

/* Director, on the green band */
.director {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.director__side { display: grid; justify-items: start; gap: 1.1rem; }
.director .hand { color: var(--butter); font-size: 1.4rem; max-width: 18ch; }
.director .band__note { max-width: 60ch; margin-top: 1.2rem; }
.director__pull {
  font-size: clamp(1.35rem, 2.4vw, 1.7rem);
  line-height: 1.3;
  color: var(--cream);
  margin: 1.4rem 0 2rem;
  max-width: 30ch;
}
.facts--cream .fact { border-top-color: rgba(255, 241, 217, 0.9); }
.facts--cream dt { color: rgba(255, 241, 217, 0.72); }
.facts--cream dd { color: var(--cream); }
/* A link inside a fact on the green band needs an underline that survives it. */
.facts--cream dd a { color: var(--cream); text-decoration-color: rgba(255, 241, 217, 0.55); }
.facts--cream dd a:hover { text-decoration-color: var(--butter); }
.facts--cream dd small a { color: rgba(255, 241, 217, 0.92); }
.facts--cream dd small { color: rgba(255, 241, 217, 0.78); }
/* The co-founder sits on paper below the director's green band, portrait on
   the other side, so the two read as a pair rather than the same block twice. */
.founders { padding: clamp(3.5rem, 8vw, 6rem) 0; }
.founder {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.founder__side { grid-column: 2; grid-row: 1; display: grid; justify-items: start; gap: 1.1rem; }
.founder__body { grid-column: 1; grid-row: 1; }
.founder .hand { color: var(--marker); font-size: 1.4rem; max-width: 20ch; }
.founder__note { margin-top: 1.2rem; max-width: 60ch; color: var(--ink-soft); font-size: 1.08rem; }
.founder__pull {
  font-size: clamp(1.35rem, 2.4vw, 1.7rem);
  line-height: 1.3;
  color: var(--forest);
  margin: 1.4rem 0 2rem;
  max-width: 34ch;
}

@media (max-width: 880px) {
  .director { grid-template-columns: 1fr; }
  .founder { grid-template-columns: 1fr; }
  .founder__side { grid-column: 1; grid-row: 1; }
  .founder__body { grid-column: 1; grid-row: 2; }
  .portrait--lg { width: 180px; }
}

/* Guest instructors: a ledger, not a card grid */
.guests { padding: clamp(4rem, 9vw, 7rem) 0; border-top: 1px solid var(--line); }
/* The guests lead is a paragraph, not a caption, so it takes half the head and
   runs further left. The Experience page keeps the 7fr and 4fr head. */
.guests .academy__head { grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); }
@media (max-width: 880px) { .guests .academy__head { grid-template-columns: 1fr; } }
.guests__print { margin: clamp(1rem, 2vw, 1.5rem) 0 clamp(2.5rem, 5vw, 4rem); }
.roster { border-top: 1px solid var(--line-strong); }
.roster__row {
  display: grid;
  grid-template-columns: 3rem 120px minmax(0, 5fr) minmax(0, 7fr);
  gap: 1.25rem 2rem;
  align-items: start;
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--line);
}
.roster__num { font-family: var(--display); font-weight: 600; color: var(--pink-deep); letter-spacing: 0.08em; padding-top: 0.4rem; }
.roster__who h3 { font-size: 1.3rem; line-height: 1.15; color: var(--forest); }
.role { margin: 0.3rem 0 0; font-size: 1.02rem; line-height: 1.4; color: var(--ink-soft); }
.roster__bio { max-width: 62ch; font-size: 1rem; color: var(--ink-soft); }
.roster__signoff { margin: 1.6rem 0 0 calc(3rem + 2rem); font-size: 1.4rem; }
@media (max-width: 600px) {
  .roster__row {
    grid-template-columns: 72px minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    gap: 0.35rem 1.1rem;
    padding: 1.4rem 0;
  }
  .roster .roster__portrait { grid-column: 1; grid-row: 1 / 3; width: 72px; }
  .roster__num { grid-column: 2; grid-row: 1; padding: 0; font-size: 0.78rem; letter-spacing: 0.16em; }
  .roster__who { grid-column: 2; grid-row: 2; }
  .roster__bio { grid-column: 1 / -1; grid-row: 3; margin-top: 0.6rem; }
  .roster__signoff { margin-left: 0; }
}

/* The roster fold: the page opens on the first three guests and a sliver of
   the fourth fading into the paper; the button below shows the rest. The
   fold height is measured by grove.js and set as --fold-h, so without
   JavaScript, or in print, the whole ledger is simply there. */
.fold { position: relative; }
.fold--closed { max-height: var(--fold-h, none); overflow: hidden; }
.fold--moving { overflow: hidden; transition: max-height 0.7s var(--ease-out); }
.fold__fade {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: clamp(6rem, 10vw, 8rem);
  background: linear-gradient(to bottom, rgba(251, 245, 234, 0) 0%, rgba(251, 245, 234, 0.85) 55%, var(--paper) 100%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--ease-out);
}
.fold--closed .fold__fade { opacity: 1; }
.fold__more { display: flex; justify-content: center; margin: 1.5rem 0 0; }
.fold__btn svg { transition: transform 0.35s var(--ease-out); }
.fold__btn[aria-expanded="true"] svg { transform: rotate(180deg); }
html.no-js .fold__more { display: none; }
@media (prefers-reduced-motion: reduce) {
  .fold--moving, .fold__fade, .fold__btn svg { transition: none; }
}
@media print {
  .fold--closed { max-height: none; overflow: visible; }
  .fold__fade, .fold__more { display: none; }
}

/* Origins: three beats on one hand-drawn stroke */
.origins { background: var(--cream); padding: clamp(4rem, 9vw, 7rem) 0; }
.origins .parents__head { margin-bottom: clamp(2rem, 4vw, 3rem); }
.beats { --gutter-w: 3.5rem; max-width: 720px; margin: 0 auto; }
.beat {
  position: relative;
  display: grid;
  grid-template-columns: var(--gutter-w) minmax(0, 1fr);
  gap: 0 1.5rem;
  padding-bottom: clamp(2rem, 4vw, 3rem);
}
.beat:last-child { padding-bottom: clamp(1rem, 2vw, 1.5rem); }
/* The stroke is one segment per beat, from this mark's centre to the next one's,
   so it lands on the marks however many lines the text takes. */
.beat__link {
  position: absolute;
  left: calc(var(--gutter-w) / 2 - 12px);
  top: 1.2rem;
  bottom: -1.2rem;
  width: 24px;
  height: auto;
  overflow: visible;
}
.beat__link path {
  fill: none;
  stroke: var(--butter);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1s var(--ease-out) 0.2s;
}
.beat:nth-child(2) .beat__link path { transition-delay: 1s; }
.beats.is-in .beat__link path { stroke-dashoffset: 0; }
html.no-js .beat__link path, html.no-reveal .beat__link path { stroke-dashoffset: 0; transition: none; }
.beat__mark {
  position: relative;
  z-index: 1;
  width: 2.4rem;
  height: 2.4rem;
  margin-left: calc(var(--gutter-w) / 2 - 1.2rem);
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--cream);
  border: 2px solid var(--butter);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--pink-deep);
}
.beat__line { font-size: clamp(1.35rem, 2.6vw, 1.9rem); line-height: 1.3; color: var(--forest); margin: 0.2rem 0 0; }
/* The print and the closing line share the beats' box and start under the beat text */
.origins__tail { max-width: 720px; margin: 0 auto; padding-left: calc(3.5rem + 1.5rem); }
.origins__print { max-width: 520px; }
.origins__close { margin-top: clamp(1.5rem, 3vw, 2.2rem); }
@media (max-width: 600px) {
  .beats { --gutter-w: 2.8rem; }
  .beat__mark { width: 2rem; height: 2rem; margin-left: calc(var(--gutter-w) / 2 - 1rem); font-size: 0.7rem; }
  .beat__link { top: 1rem; bottom: -1rem; }
  .origins__tail { padding-left: 0; }
}

/* Partners: the idea, then two names on the door */
.partners { padding: clamp(4rem, 9vw, 7rem) 0; border-top: 1px solid var(--line); }
.partners .academy__head { align-items: start; }
.partners .lead { margin-bottom: 0.4rem; }
.experts__fields--ink { color: var(--forest); font-size: 1.35rem; margin: 0.2rem 0 1rem; }
.partners__kicker { margin-top: clamp(1rem, 2vw, 1.5rem); }
.twoup {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
  padding-top: clamp(1.5rem, 3vw, 2.5rem);
  border-top: 1px solid var(--line);
}
.twoup h3 { font-size: 1.5rem; line-height: 1.15; color: var(--forest); }
.twoup .role { margin-bottom: 0.9rem; }
.twoup .copy { max-width: 44ch; }
.twoup .arrow-link { margin-top: 0.6rem; }
.twoup__amp { align-self: center; font-size: clamp(2.6rem, 5vw, 3.6rem); line-height: 1; rotate: -6deg; }
.partners__note { margin-top: clamp(2rem, 4vw, 3rem); }
.partners__cta {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.partners__cta .print { max-width: 480px; width: 100%; }
.partners__ask .coming__line { margin: 0 0 1.4rem; max-width: 30ch; }
@media (max-width: 880px) {
  .partners__cta { grid-template-columns: 1fr; }
  .partners__cta .print { max-width: 460px; }
}
@media (max-width: 720px) {
  .twoup { grid-template-columns: 1fr; gap: 1.5rem; }
  .twoup__amp { justify-self: center; rotate: -4deg; }
}
@media (max-width: 480px) {
  .weeks__note { flex-direction: column; gap: 0.2rem; }
}
@media (prefers-reduced-motion: reduce) {
  .beat__link path { stroke-dashoffset: 0; transition: none; }
}
@media print {
  .beat__link path { stroke-dashoffset: 0 !important; }
}

/* The guests section closes on two prints side by side. */
.guests__closing {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(1rem, 2.5vw, 2rem);
  align-items: start;
}
@media (max-width: 720px) {
  .guests__closing { grid-template-columns: 1fr; gap: 1.5rem; }
}

/* --------------------------------------------------------------------------
   15. App surfaces and forms
   The parent-facing working pages (FAQ, Parent Portal, registration, the
   family forms and the survey) share these. Same tokens, same type, same
   corners as the rest of the site, so a form feels like part of the place
   rather than a different product.
   -------------------------------------------------------------------------- */

/* The page scripts (portal.js, signup.js) still reference the old token
   names in a few inline styles. They resolve to the grove palette here. */
:root {
  --color-primary: var(--forest);
  --color-primary-dark: var(--forest-deep);
  --color-secondary: var(--leaf);
  --color-dark: var(--ink);
  --color-text: var(--ink);
}

/* Page frame */
.app { padding: clamp(2.5rem, 6vw, 4.5rem) 0 clamp(4rem, 9vw, 7rem); }
.app--tight { padding-bottom: clamp(3rem, 6vw, 5rem); }
.app__head { max-width: 62ch; margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.app__head .display { font-size: clamp(2rem, 4vw, 3rem); }
.app__head .lead { margin-top: 1rem; }
.app__head--center { text-align: center; margin-inline: auto; }
.app__head--center .eyebrow { justify-content: center; }
.app__head--center .eyebrow::before { display: none; }
.app__head--center .lead { margin-inline: auto; }

/* Panels */
.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3.5vw, 2.5rem);
  box-shadow: var(--shadow-card);
}
.panel--cream { background: var(--cream); border-color: transparent; box-shadow: none; }
.panel--narrow { max-width: 480px; margin-inline: auto; }
.panel--form { max-width: 760px; margin-inline: auto; }
/* The same measure without the card, for a head that sits above its panel. */
.col--form { max-width: 760px; margin-inline: auto; }
.panel--wide { max-width: 900px; margin-inline: auto; }
.panel + .panel { margin-top: 1.5rem; }
.panel__title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.3rem;
  line-height: 1.15;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--forest);
}
.panel__title + p { margin-top: 0.5rem; color: var(--ink-soft); }
.panel__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 0.75rem 1rem; margin-bottom: 1.25rem; }
.panel__foot { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }

/* Forms */
fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
legend { padding: 0; }
.form { display: grid; gap: 1.4rem; }
.form__section { display: grid; gap: 1.1rem; padding-top: 1.6rem; border-top: 1px solid var(--line); }
.form__section:first-child { padding-top: 0; border-top: 0; }
.form__section-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.15rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--forest);
}
.form__section-title + p, .form__section-intro { color: var(--ink-soft); font-size: 0.98rem; }
.form__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.25rem; }
.form__grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form__grid > .field--wide { grid-column: 1 / -1; }
.field { display: grid; gap: 0.4rem; align-content: start; }
.field__label { font-family: var(--display); font-weight: 600; font-size: 0.95rem; color: var(--forest); }
.field__label small { font-family: var(--body); font-weight: 400; font-size: 0.85rem; color: var(--ink-mute); margin-left: 0.35rem; }
.field__hint { font-size: 0.9rem; line-height: 1.5; color: var(--ink-soft); }
.field__error { font-size: 0.9rem; font-weight: 600; color: var(--pink-deep); }
.input, .select, .textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1.5px solid var(--control-line);
  border-radius: 14px;
  background: #fff;
  font: inherit;
  font-size: 1rem;
  line-height: 1.4;
  color: var(--ink);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.input::placeholder, .textarea::placeholder { color: var(--ink-mute); }
.input:focus-visible, .select:focus-visible, .textarea:focus-visible {
  outline: none;
  border-color: var(--forest);
  box-shadow: 0 0 0 4px rgba(37, 61, 14, 0.12);
}
.input[aria-invalid="true"], .select[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--pink-deep); }
.input:disabled, .select:disabled, .textarea:disabled { background: var(--paper-deep); color: var(--ink-mute); cursor: not-allowed; }
.select {
  appearance: none;
  padding-right: 2.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23253D0E' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 1.1rem;
  cursor: pointer;
}
.textarea { min-height: 7rem; resize: vertical; }
.input--sm { padding: 0.6rem 0.85rem; font-size: 0.95rem; border-radius: 10px; }
.input-group { display: flex; gap: 0.6rem; align-items: stretch; }
.input-group .input { flex: 1 1 auto; min-width: 0; }
.input-group .btn { flex: none; }

/* Checkbox and radio rows */
.check { display: flex; gap: 0.7rem; align-items: flex-start; font-size: 0.98rem; line-height: 1.5; color: var(--ink-soft); cursor: pointer; }
.check input { width: 1.25rem; height: 1.25rem; margin: 0.15rem 0 0; accent-color: var(--forest); flex: none; cursor: pointer; }
.check strong, .check a { color: var(--ink); }
.check-list { display: grid; gap: 0.7rem; }

/* Selectable cards, for session pickers and single-choice questions */
.choice {
  position: relative;
  display: flex;
  gap: 1rem;
  align-items: center;
  padding: 1rem 1.2rem;
  border: 1.5px solid var(--control-line);
  border-radius: 18px;
  background: #fff;
  cursor: pointer;
  transition: border-color 0.2s, background-color 0.2s, box-shadow 0.2s, transform 0.3s var(--ease-out);
}
.choice input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.choice:hover { border-color: var(--forest); transform: translateY(-1px); }
.choice:has(input:checked) { border-color: var(--forest); background: var(--cream); box-shadow: inset 0 0 0 1px var(--forest); }
/* The real input is 1px and transparent, so the card wears the site ring.
   Outline, not box-shadow, so a checked card keeps its inset forest ring. */
.choice:has(input:focus-visible) { outline: 3px solid var(--pink); outline-offset: 3px; }
.choice--disabled, .choice:has(input:disabled) { opacity: 0.5; cursor: not-allowed; transform: none; }
.choice__body { flex: 1 1 auto; min-width: 0; display: grid; gap: 0.15rem; }
.choice__title { font-family: var(--display); font-weight: 600; font-size: 1.05rem; color: var(--forest); }
.choice__meta { font-size: 0.92rem; color: var(--ink-soft); }
.choice__mark {
  flex: none;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  border: 1.5px solid var(--control-line);
  display: grid;
  place-items: center;
  transition: background-color 0.2s, border-color 0.2s;
}
.choice__mark::after { content: ""; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--cream); transform: scale(0); transition: transform 0.2s var(--ease-out); }
.choice:has(input:checked) .choice__mark { background: var(--forest); border-color: var(--forest); }
.choice:has(input:checked) .choice__mark::after { transform: scale(1); }
/* Multi select cards get a square mark, so a card that takes more than one
   answer never wears the round radio affordance. The survey's own
   survey-option--check is the same modifier under an older name. */
.choice--check .choice__mark, .survey-option--check .choice__mark { border-radius: 7px; }
.choice--check .choice__mark::after, .survey-option--check .choice__mark::after { border-radius: 2px; }
.choice-list { display: grid; gap: 0.75rem; }

/* Toggle switch */
.switch { position: relative; display: inline-block; width: 50px; height: 28px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switch__slider { position: absolute; inset: 0; border-radius: 999px; background: var(--control-line); cursor: pointer; transition: background-color 0.25s; }
.switch__slider::before { content: ""; position: absolute; left: 3px; bottom: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); transition: transform 0.25s var(--ease-out); }
.switch input:checked + .switch__slider { background: var(--forest); }
.switch input:checked + .switch__slider::before { transform: translateX(22px); }
.switch input:focus-visible + .switch__slider { outline: 3px solid var(--pink); outline-offset: 3px; }

/* Actions, status lines, buttons the scripts inject */
.form__actions { display: flex; flex-wrap: wrap; gap: 0.8rem 1rem; align-items: center; }
.form__actions--end { justify-content: flex-end; }
.form__status { font-family: var(--display); font-weight: 600; min-height: 1.5rem; color: var(--ink-soft); }
/* An empty status line stays in the accessibility tree, so a script may write
   into it and have the message announced, but it leaves the flow and holds no
   row (and no gap) open until it has something to say. */
.form__status:empty, .submit-status:empty { position: absolute; min-height: 0; margin: 0; }
.form__status--error, .is-error { color: var(--pink-deep); }
.form__status--ok, .is-ok { color: var(--moss); }
.btn--block { width: 100%; justify-content: center; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; transform: none; box-shadow: none; }
.btn--sm { padding: 0.6rem 1.05rem; font-size: 0.88rem; }
.cta-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.95rem 1.5rem;
  border-radius: 999px;
  border: 2px solid transparent;
  background: var(--pink-deep);
  color: #fff;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.98rem;
  letter-spacing: 0.02em;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 10px 24px -12px rgba(216, 23, 76, 0.7);
  transition: transform 0.35s var(--ease-out), background-color 0.2s;
}
.cta-button:hover { background: var(--pink-text); transform: translateY(-2px); }
.cta-button:disabled { opacity: 0.55; cursor: not-allowed; transform: none; box-shadow: none; }
.link-button { background: none; border: 0; padding: 0; font: inherit; color: var(--forest); text-decoration: underline; text-decoration-color: var(--line-strong); cursor: pointer; }
.link-button:hover { color: var(--pink-deep); }

/* Notices */
.notice { display: flex; gap: 0.9rem; align-items: flex-start; padding: 1rem 1.25rem; border-radius: 18px; background: var(--cream); color: var(--ink-soft); line-height: 1.5; }
.notice .hand { flex: none; font-size: 1.35rem; margin-top: -0.1rem; }
.notice strong { color: var(--ink); }
.notice--ok { background: rgba(100, 196, 102, 0.2); color: var(--forest-deep); }
.notice--warn { background: rgba(245, 197, 66, 0.25); color: #4a3800; }
.notice--error { background: rgba(255, 50, 102, 0.1); color: var(--pink-text); }
.notice--info { background: rgba(77, 142, 240, 0.12); color: #1d3f7a; }

/* Status pills */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.28rem 0.7rem;
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  background: rgba(37, 61, 14, 0.08);
  color: var(--forest);
}
.pill--paid, .pill--ok { background: rgba(100, 196, 102, 0.25); color: var(--forest-deep); }
.pill--partial, .pill--warn { background: rgba(245, 197, 66, 0.35); color: #4a3800; }
.pill--pending, .pill--error { background: rgba(255, 50, 102, 0.12); color: var(--pink-text); }
.pill--muted { background: rgba(37, 61, 14, 0.06); color: var(--ink-mute); }

/* Key and value rows */
.kv { display: grid; }
.kv__row { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; padding: 0.65rem 0; border-bottom: 1px solid var(--line); }
.kv__row:last-child { border-bottom: 0; }
.kv__label { font-family: var(--display); font-weight: 600; font-size: 0.8rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-mute); flex: none; }
.kv__value { text-align: right; color: var(--ink); }
.kv__value strong { font-family: var(--display); font-weight: 600; color: var(--forest); }
@media (max-width: 480px) { .kv__row { flex-direction: column; gap: 0.15rem; } .kv__value { text-align: left; } }

/* Modal */
.modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 2rem 1rem;
  overflow-y: auto;
  background: rgba(26, 44, 8, 0.55);
  backdrop-filter: blur(4px);
}
.modal__card {
  width: 100%;
  max-width: 440px;
  margin: auto 0;
  background: var(--card);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  box-shadow: var(--shadow-lift);
}
.modal__card--wide { max-width: 600px; }
.modal__head { position: relative; margin-bottom: 1.25rem; padding-bottom: 1rem; padding-right: 5.25rem; border-bottom: 1px solid var(--line); }
.modal__head p { color: var(--ink-soft); font-size: 0.95rem; margin-top: 0.25rem; }
/* The close control sits with the title, quiet enough to stay out of the way. */
.modal__close {
  position: absolute; top: -0.2rem; right: 0;
  padding: 0.32rem 0.72rem;
  font-family: var(--display); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-soft); background: transparent;
  border: 1.5px solid var(--control-line); border-radius: 999px;
  cursor: pointer;
  transition: color 0.2s var(--ease-out), border-color 0.2s var(--ease-out), background 0.2s var(--ease-out);
}
.modal__close:hover { color: var(--forest); border-color: var(--forest); background: rgba(37, 61, 14, 0.05); }
.modal__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.5rem; }

/* Gate, loading and error screens.
   The "not signed in", "loading", "invalid link" and "load failed" states on
   the medical form, the phone use policy form, the survey and the dashboard
   are one block, centred inside a .panel.panel--narrow under the page's normal
   head. The medform__ and portal- names are the older spellings of the same
   thing and are kept so nothing breaks while the pages move over. */
.state, .medform__state, .portal-state { text-align: center; color: var(--ink-soft); }
.state .state__title, .medform__state .medform__state-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.15rem;
  line-height: 1.25;
  color: var(--forest);
  margin: 0 0 0.4rem;
}
.state--error .state__title { color: var(--pink-deep); }
.state__text, .medform__state p, .portal-state p { max-width: 44ch; margin: 0 auto; color: var(--ink-soft); }
.state__text + .state__text, .state__actions + .state__text, .medform__state p + p, .portal-state p + p { margin-top: 0.6rem; }
.state__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin: 1.2rem 0 0; }
.state > .btn, .medform__state .btn, .portal-state .btn { margin-top: 1.2rem; }
.state__foot {
  margin: 1.4rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.state a:not(.btn), .portal-state a:not(.btn) { color: var(--forest); font-weight: 600; text-decoration-color: var(--line-strong); }
.state a:not(.btn):hover, .portal-state a:not(.btn):hover { color: var(--pink-text); }
.spinner, .medform__spinner, .portal-spinner {
  display: block;
  width: 2.25rem;
  height: 2.25rem;
  margin: 0 auto 1rem;
  border-radius: 50%;
  border: 3px solid var(--line);
  border-top-color: var(--forest);
  animation: grove-spin 0.85s linear infinite;
}
@keyframes grove-spin { to { transform: rotate(360deg); } }

/* Utilities */
/* Read by a screen reader, drawn nowhere. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Accordion, built on details and summary so it works without JavaScript */
.acc { border-top: 1px solid var(--line); }
.acc:last-of-type { border-bottom: 1px solid var(--line); }
.acc > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.2rem 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.1rem;
  line-height: 1.3;
  color: var(--forest);
}
.acc > summary::-webkit-details-marker { display: none; }
.acc > summary::after {
  content: "";
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  margin-top: 0.05rem;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23253D0E' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 6v12M6 12h12'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 0.8rem;
  transition: transform 0.3s var(--ease-out), background-color 0.2s, border-color 0.2s;
}
.acc > summary:hover::after { background-color: var(--cream); border-color: var(--forest); }
.acc[open] > summary::after { transform: rotate(45deg); }
.acc > summary:focus-visible { outline: 2px solid var(--forest); outline-offset: 4px; border-radius: 4px; }
.acc__body { padding: 0 0 1.4rem; max-width: 64ch; color: var(--ink-soft); line-height: 1.6; }
.acc__body p + p, .acc__body p + ul, .acc__body ul + p { margin-top: 0.8rem; }
.acc__body ul { padding-left: 1.2rem; list-style: disc; }
.acc__body li + li { margin-top: 0.35rem; }
.acc__body a { color: var(--forest); }

/* Simple table */
.table { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
.table th { text-align: left; font-family: var(--display); font-weight: 600; font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-mute); padding: 0.6rem 0; border-bottom: 1.5px solid var(--line-strong); }
.table td { padding: 0.7rem 0; border-bottom: 1px solid var(--line); vertical-align: top; }

/* Card payment host (Stripe mounts inside) */
.pay-box { padding: 1.25rem; border: 1.5px solid var(--line); border-radius: 18px; background: #fff; }

/* Quiet nav action, for Log out on the portal */
.nav__quiet { border: 1.5px solid var(--line-strong) !important; background: transparent !important; color: var(--forest) !important; }
.nav__quiet:hover { border-color: var(--forest) !important; background: rgba(37, 61, 14, 0.05) !important; }

@media (max-width: 600px) {
  .form__grid, .form__grid--3 { grid-template-columns: 1fr; }
  .choice { padding: 0.9rem 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .choice, .switch__slider, .switch__slider::before, .acc > summary::after, .cta-button { transition: none; }
  .spinner, .medform__spinner, .portal-spinner { animation-duration: 1.7s; }
}

/* --------------------------------------------------------------------------
   16. FAQ page
   The questions sit in a ledger: each group's title in the margin, its
   accordions beside it, both starting on the same rule. Built on the .acc
   accordion and .form__section-title from section 15.
   -------------------------------------------------------------------------- */
.faq-groups { display: grid; gap: clamp(2.5rem, 5vw, 4rem); margin-top: clamp(0.5rem, 2vw, 1.5rem); }
.faq-group {
  display: grid;
  grid-template-columns: minmax(200px, 3fr) minmax(0, 9fr);
  gap: 0.75rem clamp(2rem, 5vw, 5rem);
  align-items: start;
}
/* The margin column stays in view while its questions scroll past */
.faq-group__side {
  position: sticky;
  top: calc(var(--header-h) + 1.5rem);
  padding-top: 1.25rem;
  border-top: 1.5px solid var(--forest);
}
.faq-group__intro { margin: 0.45rem 0 0; max-width: 24ch; }
.faq-group .acc > summary { font-size: 1.15rem; }
.faq-group .acc__body p:last-child { margin-bottom: 0; }

/* The closing note lines up with the answers, not the margin */
.faq-group--tail { margin-top: clamp(0.5rem, 2vw, 1rem); }
.faq-ask { grid-column: 2; }
.faq-ask .hand { font-size: 1.5rem; }
.faq-ask p { margin: 0.2rem 0 0; }
.faq-ask a { color: var(--forest); font-weight: 600; }

@media (max-width: 880px) {
  .faq-group { grid-template-columns: 1fr; gap: 0.75rem; }
  .faq-group__side { position: static; padding-top: 0; border-top: 0; }
  .faq-group__intro { max-width: var(--measure); }
  .faq-ask { grid-column: auto; }
}
@media (max-width: 480px) {
  .faq-group .acc > summary { font-size: 1.05rem; }
  .faq-ask { flex-direction: column; gap: 0.35rem; }
  .faq-ask .hand { margin-top: 0; }
}

/* --------------------------------------------------------------------------
   17. Registration page
   Two states share the page. Closed: one centred card with the winter notice.
   Open: the form in a single panel under a left aligned head. Class names
   signup.js reads or writes (session-option, session-card, session-full,
   spots-full) are kept on the choice cards and styled here under a page
   prefixed ancestor.
   -------------------------------------------------------------------------- */
.signup-frame { max-width: 760px; margin-inline: auto; }

/* Closed notice */
.signup-closed { text-align: center; padding-block: clamp(2rem, 4vw, 3rem); }
.signup-closed .eyebrow { justify-content: center; }
.signup-closed .eyebrow::before { display: none; }
.signup-closed .display { font-size: clamp(1.8rem, 3.2vw, 2.25rem); margin-bottom: 1rem; }
.signup-closed p { color: var(--ink-soft); }
.signup-closed .btn { margin-top: 0.4rem; max-width: 100%; }
.signup-closed__links { display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 0.3rem 0.5rem; margin-top: 1.5rem; font-size: 0.95rem; }
.signup-closed__links a { font-family: var(--display); font-weight: 600; color: var(--forest); text-decoration-color: var(--line-strong); }
.signup-closed__links span { color: var(--ink-mute); }

/* The form: paragraphs inside the grid sections space themselves with the grid gap */
.signup-form .form__section > p, .signup-form .field__hint { margin: 0; }
.signup-form .form__section-intro strong { color: var(--ink); }

/* Session cards: dates and theme, then the spots pill, then the mark, so the
   dates start on the same edge as every other card on the site. The card keeps
   the flex layout of .choice, so a pill the script hides leaves no gap. */
.signup-spots { flex: none; }
.signup-sessions .spots-full { background: rgba(255, 50, 102, 0.12); color: var(--pink-text); }
.signup-sessions .session-full { opacity: 0.5; cursor: not-allowed; transform: none; }
.signup-sessions__note { font-size: 1.4rem; margin: 0; }

/* Yes or no cards for the extended hours questions */
.signup-yesno { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; margin-top: 0.15rem; }
.signup-yesno .choice { padding: 0.75rem 1rem; gap: 0.7rem; }
.signup-yesno .choice__title { font-size: 1rem; }

/* Policy text inside the accordions */
.signup-policy h3 { font-size: 1rem; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase; line-height: 1.3; color: var(--forest); margin-bottom: 0.5rem; }
.signup-policy h4 { font-size: 0.98rem; font-weight: 600; line-height: 1.3; color: var(--forest); margin: 1.15rem 0 0.35rem; }
.signup-policy em { color: var(--ink-mute); }
.signup-policy strong { color: var(--ink); }

/* Promo code */
.signup-promo__input { text-transform: uppercase; letter-spacing: 0.12em; font-family: var(--display); font-weight: 600; }
.signup-promo__input::placeholder { text-transform: none; letter-spacing: 0; font-family: var(--body); font-weight: 400; }
.signup-promo__status { font-size: 0.92rem; min-height: 1.4rem; margin: 0; }
/* signup.js reveals the price line with display block, so its parts are inline */
.signup-price { margin-top: 0.4rem; padding: 0.85rem 1.15rem; border-radius: 18px; background: var(--cream); line-height: 1.3; }
.signup-price > * { display: inline-block; vertical-align: baseline; margin-right: 0.75rem; }
.signup-price > :last-child { margin-right: 0; }
.signup-price__label { font-family: var(--display); font-weight: 600; font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-mute); }
.signup-price__was { text-decoration: line-through; color: var(--ink-mute); }
.signup-price__now { font-family: var(--display); font-weight: 700; font-size: 1.5rem; color: var(--forest); }

/* Payment */
.signup-pay__loading { text-align: center; color: var(--ink-mute); padding: 2rem 0; margin: 0; }
.signup-pay__message { text-align: center; margin: 1rem 0 0; }
.signup-status { text-align: center; margin: 0; }

/* Registration complete, injected by signup.js after Stripe returns */
.signup-done { text-align: center; padding-block: clamp(1rem, 3vw, 2rem); }
.signup-done .eyebrow { justify-content: center; }
.signup-done .eyebrow::before { display: none; }
.signup-done .display { font-size: clamp(1.9rem, 3.6vw, 2.6rem); margin-bottom: 1rem; }
.signup-done .lead { margin: 0 auto 1.75rem; }

@media (max-width: 600px) {
  /* The pill drops under the dates, the mark stays beside them. A pill the
     script hides takes its row with it, so no gap is left behind. */
  .signup-sessions .choice { display: grid; grid-template-columns: minmax(0, 1fr) auto; row-gap: 0.45rem; }
  .signup-sessions .choice__body { grid-column: 1; grid-row: 1; }
  .signup-sessions .choice__mark { grid-column: 2; grid-row: 1; }
  .signup-spots { grid-column: 1; grid-row: 2; justify-self: start; }
}
@media (max-width: 480px) {
  .signup-closed .btn { padding-inline: 1.2rem; }
}

/* --------------------------------------------------------------------------
   18. Parent portal
   The login (portal.html), the dashboard (dashboard.html) and the markup
   portal.js injects: registration cards, the forms and survey rows, the
   referral box, the lunch and laptop section and the add-ons modal body.
   Everything here builds on section 15; the JavaScript hooks (ids, the
   addon-laptop-toggle, addon-lunch-select, pay-balance-btn, copy-referral-btn
   and configure-addon-btn classes, and the active, selected and is-copied
   states) are left unstyled on purpose and only the portal-* classes carry
   the look.
   -------------------------------------------------------------------------- */
/* Login */
.portal-login { min-height: 62vh; display: grid; align-content: center; padding-top: clamp(3rem, 7vw, 5.5rem); }
.modal .form > .modal__actions { margin-top: 0.2rem; }
.portal-login .app__head { margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem); }
.portal-pw { position: relative; }
.portal-pw .input { padding-right: 4.9rem; }
.portal-pw__toggle {
  position: absolute;
  top: 50%;
  right: 0.55rem;
  transform: translateY(-50%);
  padding: 0.45rem 0.75rem;
  border-radius: 999px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--forest);
  transition: background-color 0.2s;
}
.portal-pw__toggle:hover { background: var(--cream); }
.portal-login__foot { display: grid; gap: 0.6rem; font-size: 0.95rem; color: var(--ink-soft); }
.portal-login__foot a { color: var(--forest); font-weight: 600; text-decoration-color: var(--line-strong); }
.portal-login__foot a:hover { color: var(--pink-deep); }
.portal-login__aside { margin: 1.5rem auto 0; max-width: 24ch; text-align: center; font-size: 1.4rem; }

/* Dashboard head and states */
.nav .nav__quiet { white-space: nowrap; }
.portal-who { margin-top: 0.9rem; color: var(--ink-soft); }
.portal-who strong { font-family: var(--display); font-weight: 600; color: var(--forest); overflow-wrap: anywhere; }
/* The gate, loading and error screens are the shared .state block in
   section 15; .portal-state and .portal-spinner are kept there as aliases. */
.portal-state { padding: clamp(2rem, 5vw, 3.5rem) 1rem; }
.portal-state .serif-quote { font-size: clamp(1.3rem, 2.2vw, 1.6rem); line-height: 1.3; color: var(--forest); margin-bottom: 0.7rem; }
.portal-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.75rem 1.2rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.portal-foot a { color: var(--forest); text-decoration-color: var(--line-strong); }
.portal-foot a:hover { color: var(--pink-deep); }
.portal-foot__sep { width: 5px; height: 5px; border-radius: 50%; background: var(--line-strong); }

/* Registration cards */
.portal-cards { display: flex; flex-direction: column; gap: 1.5rem; }
.portal-cards > .panel + .panel { margin-top: 0; }
.portal-banner { margin-bottom: 1.5rem; }
.portal-card__head { align-items: center; }
.portal-card__kicker { margin: 0 0 0.35rem; font-family: var(--display); font-weight: 600; font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-mute); }
.portal-card__name { font-size: clamp(1.5rem, 2.6vw, 1.9rem); }
.portal-kv .kv__value div + div { margin-top: 0.15rem; }
.portal-kv .kv__value .pill { vertical-align: middle; margin-right: 0.3rem; }
.portal-code { font-family: var(--display); font-weight: 700; letter-spacing: 0.12em; padding: 0.15rem 0.55rem; border-radius: 8px; background: var(--cream); color: var(--forest); margin-right: 0.3rem; }
.portal-due strong { color: var(--pink-deep); }

/* Forms and surveys: one row each, open or complete */
.portal-tasks { display: grid; gap: 0.6rem; margin-top: 1.4rem; }
.portal-tasks:empty { display: none; }
.portal-task {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding: 0.85rem 1.1rem;
  border-radius: 16px;
  border: 1.5px solid var(--line-strong);
  background: #fff;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.98rem;
  line-height: 1.35;
  color: var(--forest);
  text-decoration: none;
  transition: border-color 0.2s, background-color 0.2s, transform 0.3s var(--ease-out);
}
a.portal-task:hover { border-color: var(--forest); background: var(--cream); transform: translateY(-1px); }
.portal-task > span:first-child { flex: 1 1 18ch; }
.portal-task__go {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  flex: none;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pink-deep);
  text-decoration: none;
}
.portal-task__go::after { content: ""; width: 0.55rem; height: 0.55rem; border-top: 2px solid currentColor; border-right: 2px solid currentColor; transform: rotate(45deg); margin-left: 0.1rem; }
a.portal-task:hover .portal-task__go::after { transform: translateX(3px) rotate(45deg); }
.portal-task.is-done { border-color: transparent; background: rgba(100, 196, 102, 0.16); color: var(--forest-deep); }
.portal-task.is-done .portal-task__go { color: var(--forest); padding: 0.3rem 0; margin: -0.3rem 0; }
.portal-task.is-done .portal-task__go:hover { color: var(--pink-deep); }

/* Referral code */
.portal-referral { display: grid; gap: 0.55rem; margin-top: 1.4rem; padding: 1.1rem 1.25rem; border-radius: 18px; background: var(--cream); }
.portal-referral__label { margin: 0; font-family: var(--display); font-weight: 600; font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--moss); }
.portal-referral__row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 0.8rem; }
.portal-referral__code {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: 0.18em;
  color: var(--forest);
  padding: 0.45rem 0.9rem 0.45rem 1.05rem;
  border-radius: 12px;
  background: #fff;
  border: 1.5px dashed var(--line-strong);
}
.portal-referral__note { margin: 0; font-size: 0.92rem; color: var(--ink-soft); }
.portal-referral .btn.is-copied { background: var(--leaf); border-color: var(--leaf); color: var(--forest-deep); }

/* Pay the balance */
.portal-pay { margin-top: 1.4rem; font-size: 1.02rem; }

/* Lunch and laptop options, at the foot of each card */
.portal-addons { margin-top: 1.6rem; padding-top: 1.4rem; border-top: 1px solid var(--line); }
.portal-addons__title { font-family: var(--display); font-weight: 600; font-size: 1.05rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--forest); }
.portal-addons__note { margin: 0.5rem 0 0.9rem; font-size: 0.95rem; line-height: 1.55; color: var(--ink-soft); }
.portal-addons__note strong { color: var(--ink); }
.portal-addons .notice { font-size: 0.95rem; padding: 0.8rem 1.1rem; margin-bottom: 0.9rem; }
.portal-addons__weeks .kv__row { padding: 0.55rem 0; align-items: center; }
.portal-addons__week { font-family: var(--display); font-weight: 600; color: var(--forest); }
.portal-addons__week small { display: block; font-family: var(--body); font-weight: 400; font-size: 0.9rem; color: var(--ink-soft); }
.portal-addons__action { margin-top: 1rem; }
.portal-addons__action .notice { margin: 0; }

/* Add-ons modal body: the specs, then one block per week */
.modal .pay-box { margin-top: 1.1rem; }
.modal .notice { margin-top: 1rem; }
.portal-specs { margin-bottom: 0.5rem; }
.portal-specs > summary { padding: 0.85rem 0; font-size: 1rem; }
.portal-specs .acc__body { max-width: none; padding-bottom: 1.2rem; }
.portal-specs__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.8rem; }
.portal-specs__col { padding: 1rem 1.1rem; border-radius: 16px; background: var(--cream); }
.portal-specs__col h4 { margin: 0 0 0.6rem; font-family: var(--display); font-weight: 600; font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--moss); }
.portal-specs__col ul { padding: 0; list-style: none; display: grid; gap: 0.35rem; font-size: 0.88rem; line-height: 1.45; color: var(--ink-soft); }
.portal-specs__col li + li { margin: 0; }
.portal-specs__col b { color: var(--ink); }

.portal-week { padding-top: 1.25rem; margin-top: 1.25rem; border-top: 1px solid var(--line); }
.portal-week__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.8rem; margin-bottom: 0.9rem; }
.portal-week__label { margin: 0; font-family: var(--display); font-weight: 600; font-size: 1.15rem; text-transform: uppercase; letter-spacing: 0.02em; color: var(--forest); }
.portal-week__type { font-size: 0.92rem; color: var(--ink-soft); }
.portal-week__head .pill { margin-left: auto; }
.portal-week__locked { margin: 0; font-size: 0.95rem; color: var(--ink-mute); }

.portal-item {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.9rem 1rem;
  border-radius: 16px;
  border: 1.5px solid var(--line);
  background: #fff;
  transition: border-color 0.2s, background-color 0.2s;
}
.portal-item + .portal-item { margin-top: 0.75rem; }
.portal-item.active { border-color: var(--forest); background: var(--cream); }
.portal-item--lunch { display: grid; gap: 0.9rem; }
.portal-item__row { display: flex; align-items: center; gap: 0.9rem; }
.portal-item__img { width: 52px; height: 52px; object-fit: cover; border-radius: 10px; flex: none; background: var(--paper-deep); }
.portal-item__body { flex: 1 1 auto; min-width: 0; }
.portal-item__title { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.6rem; font-family: var(--display); font-weight: 600; font-size: 1rem; color: var(--forest); }
.portal-item__price { font-size: 0.86rem; letter-spacing: 0.02em; color: var(--pink-deep); }
.portal-item__meta { margin: 0.15rem 0 0; font-size: 0.9rem; line-height: 1.45; color: var(--ink-soft); }
.portal-item__meta strong { color: var(--ink); }

.portal-days { display: grid; gap: 0.45rem; padding-top: 0.75rem; border-top: 1px solid var(--line); }
.portal-day { display: grid; grid-template-columns: minmax(6.5rem, 1fr) minmax(0, 1.5fr); align-items: center; gap: 0.75rem; }
.portal-day__label { position: relative; padding-left: 1rem; font-family: var(--display); font-weight: 600; font-size: 0.95rem; color: var(--forest); }
.portal-day__label::before { content: ""; position: absolute; left: 0; top: 0.55em; width: 7px; height: 7px; border-radius: 50%; background: var(--line-strong); transition: background-color 0.2s; }
.portal-day__label small { display: block; font-family: var(--body); font-weight: 400; font-size: 0.8rem; color: var(--ink-mute); }
.portal-day.selected .portal-day__label::before { background: var(--pink); }
.portal-day .select { padding-right: 2.5rem; }

/* Price summary at the foot of the add-ons modal */
.portal-sum { margin-top: 1.25rem; padding: 0.9rem 1.25rem; border-radius: 18px; background: var(--cream); }
.portal-sum .kv__row { padding: 0.4rem 0; border-bottom: 0; }
.portal-sum .kv__label { color: var(--ink-soft); }
.portal-sum .price { font-family: var(--display); font-weight: 600; color: var(--forest); }
.portal-sum__total { margin-top: 0.3rem; padding-top: 0.75rem !important; border-top: 1.5px solid var(--line-strong); }
.portal-sum__total .kv__label { color: var(--forest); font-size: 0.86rem; }
.portal-sum__total .price { font-size: 1.35rem; color: var(--pink-deep); }

@media (max-width: 600px) {
  .portal-specs__grid { grid-template-columns: 1fr; }
  .portal-item { padding: 0.8rem 0.85rem; gap: 0.7rem; }
  .portal-item__img { width: 44px; height: 44px; }
}
@media (max-width: 480px) {
  .portal-sum .kv__row, .portal-addons__weeks .kv__row { flex-direction: row; align-items: baseline; gap: 0.75rem; }
  .portal-sum .kv__value, .portal-addons__weeks .kv__value { text-align: right; }
  .portal-day { grid-template-columns: 6.75rem minmax(0, 1fr); gap: 0.5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .portal-task, .portal-item, .portal-pw__toggle { transition: none; }
}

/* --------------------------------------------------------------------------
   19. Medical form
   medical-form.html and medical-form-success.html, on top of section 15.
   New classes are prefixed medform.
   The form script toggles four hooks by name (conditional-block, visible,
   active and submit-status), so those keep their old names here.
   -------------------------------------------------------------------------- */
/* The page is one 760px column, so the head lines up with the form */
.medform__col { width: min(100% - 2 * var(--gutter), 760px); }

/* Page head. The child's name is written in by the script, so the line
   takes no room while it is empty. */
.medform__for { margin: 0.5rem 0 0; }
.medform__for:empty { display: none; }
.medform .app__head .lead { margin-top: 0.9rem; }

/* The loading, sign-in and error screens are the shared .state block in
   section 15; .medform__state and .medform__spinner are kept there as
   aliases. */

/* Intro notice and the required mark */
.medform__intro { margin-bottom: 1.6rem; }
.req { color: var(--pink-deep); font-weight: 700; }

/* Section heads, lettered the way the About page numbers its roster */
.medform__sec-num {
  display: block;
  margin-bottom: 0.4rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pink-deep);
}
.medform__sub {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: -0.3rem;
}
.medform__sub small { font-family: var(--body); font-weight: 400; font-size: 0.86rem; letter-spacing: 0; text-transform: none; margin-left: 0.3rem; }
.medform__rule { border: 0; border-top: 1px solid var(--line); margin: 0.2rem 0; }

/* Yes or no questions: the question on the left, two pill buttons on the
   right. The script marks the chosen button with the active class. */
.medform-yn { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.7rem 1.5rem; }
.medform-yn__q { flex: 1 1 28ch; margin: 0; color: var(--ink); font-weight: 700; line-height: 1.5; }
.medform-yn__q small { display: block; margin-top: 0.2rem; font-size: 0.9rem; font-weight: 400; color: var(--ink-soft); }
.medform-yn__q .req { font-weight: 700; }
.medform-yn__btns { display: flex; flex-wrap: wrap; flex: 0 1 auto; gap: 0.5rem; }
.medform-yn__btn {
  padding: 0.62rem 1.25rem;
  border-radius: 999px;
  border: 1.5px solid var(--control-line);
  background: #fff;
  color: var(--forest);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.02em;
  line-height: 1;
  white-space: nowrap;
  transition: background-color 0.2s, border-color 0.2s, color 0.2s, transform 0.3s var(--ease-out);
}
.medform-yn__btn:hover { border-color: var(--forest); background: rgba(37, 61, 14, 0.05); transform: translateY(-1px); }
.medform-yn__btn.active { background: var(--forest); border-color: var(--forest); color: var(--cream); }

/* No single child (a long question, a pair of wide buttons) may widen a
   section track past the panel */
.medform .form__section > *, .medform__cond > * { min-width: 0; }

/* Blocks that open after a yes or a no. The script sets display inline and
   adds the visible class; the inner wrapper carries the layout. */
.conditional-block { display: none; }
.conditional-block.visible { display: block; }
.medform__cond { display: grid; gap: 1rem; padding-left: 1.1rem; border-left: 2px solid var(--line-strong); }
.medform__cond .medform__cond { padding-left: 0.9rem; }

/* Groups of checkboxes in two columns */
.medform__checks { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* One card per medication */
.medform__med { display: grid; gap: 0.8rem; padding: 1rem 1.1rem; border: 1px solid var(--line); border-radius: 18px; background: #fff; }
.medform__med .medform__sub { margin-bottom: 0; }

/* Waiver, release and certification text, set as readable prose */
.medform__prose {
  padding: 1.35rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: #fff;
  color: var(--ink-soft);
  font-size: 0.97rem;
  line-height: 1.65;
}
.medform__prose h3 { margin-bottom: 0.6rem; font-family: var(--display); font-weight: 600; font-size: 1rem; line-height: 1.3; color: var(--forest); }
.medform__prose p + p, .medform__prose p + ul, .medform__prose ul + p { margin-top: 0.8rem; }
.medform__prose ul { padding-left: 1.2rem; list-style: disc; }
.medform__prose li + li { margin-top: 0.3rem; }
.medform__prose strong { color: var(--ink); }
.medform__prose a { color: var(--forest); }

/* Submit status. The script writes the text and the error class. */
.submit-status { margin-bottom: 1rem; font-family: var(--display); font-weight: 600; color: var(--ink-soft); }
.submit-status.error { color: var(--pink-deep); }
.submit-status.success { color: var(--moss); }

/* Success page */
.medform-done .app__head .hand { margin: 0.6rem 0 0; }
.medform-done__title { margin-top: 1.5rem; font-size: 1.05rem; }
.medform-done__list { counter-reset: medform-step; margin-top: 0.8rem; }
.medform-done__list li { position: relative; padding: 0.7rem 0 0.7rem 2.4rem; border-top: 1px solid var(--line); color: var(--ink-soft); }
.medform-done__list li::before {
  counter-increment: medform-step;
  content: counter(medform-step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0.95rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.12em;
  color: var(--pink-deep);
}
/* The success script still fills this container; the paper flecks are not
   part of the grove look, so it stays out of view. */
.medform-done__confetti { display: none; }

@media (max-width: 600px) {
  .medform__checks { grid-template-columns: 1fr; }
  .medform-yn { flex-direction: column; align-items: flex-start; }
  .medform-yn__q { flex: 0 0 auto; }
  .medform__cond { padding-left: 0.9rem; }
  .medform__cond .medform__cond { padding-left: 0.7rem; }
}
@media (prefers-reduced-motion: reduce) {
  .medform-yn__btn { transition: none; }
}

/* --------------------------------------------------------------------------
   20. Parent survey
   The end of week feedback form on parent-survey.html: the four state
   screens, the question blocks, a star row, a compact 1 to 10 scale, the
   option cards and the rating matrix. Built on the section 15 form pieces.
   The inline script keeps its own hooks (star, nps-btn, option-item,
   option-list, other-input, matrix-dot, rating-matrix and the active,
   selected and visible states); those stay unstyled on purpose and only the
   survey- classes carry the look.
   -------------------------------------------------------------------------- */
/* State screens: the script switches them on with display flex */
.survey-state { flex-direction: column; align-items: stretch; }
.survey-state .panel { text-align: center; color: var(--ink-soft); }
.survey-state .panel p { max-width: 40ch; margin-inline: auto; }
.survey-state .panel a:not(.btn) { color: var(--forest); font-weight: 600; text-decoration-color: var(--line-strong); }
.survey-state .panel a:not(.btn):hover { color: var(--pink-deep); }
.survey-state .serif-quote { font-size: clamp(1.25rem, 2.2vw, 1.5rem); line-height: 1.3; color: var(--forest); }
.survey-state .panel__foot { font-size: 0.95rem; }

/* Head: the hand aside under the lead, then the week and child tags */
.app__head .survey-hand { margin: 0.6rem 0 0; }

/* Section titles carry their count as a small line above the words */
.survey-section__num {
  display: block;
  margin-bottom: 0.35rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pink-deep);
}

/* One question: the numbered prompt, an optional hint, then its control */
.survey-q { display: grid; gap: 0.8rem; }
.survey-q + .survey-q { margin-top: 0.6rem; }
.survey-q__text {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.08rem;
  line-height: 1.35;
  color: var(--ink);
}
.survey-q__num { flex: none; font-size: 0.8rem; letter-spacing: 0.12em; color: var(--pink-deep); font-variant-numeric: tabular-nums; }
.survey-q__text small { margin-left: 0.35rem; font-family: var(--body); font-weight: 400; font-size: 0.85rem; color: var(--ink-mute); white-space: nowrap; }
.survey-q__hint { margin: -0.4rem 0 0; font-size: 0.9rem; color: var(--ink-mute); }

/* Stars: the row fills up to the one chosen, or the one under the pointer */
.survey-rating { display: grid; gap: 0.3rem; width: max-content; max-width: 100%; }
.survey-stars { display: flex; gap: 0.2rem; }
/* The glyph in the markup is replaced by a drawing, so a chosen star differs
   from an empty one in shape and not only in hue: empty is an outline, chosen
   is a butter star inside the same forest stroke. */
.survey-star {
  --star-empty: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23253D0E' stroke-width='1.7' stroke-linejoin='round'%3E%3Cpath d='M12 2.6l2.94 5.96 6.58.96-4.76 4.64 1.12 6.55L12 17.61l-5.88 3.1 1.12-6.55L2.48 9.52l6.58-.96z'/%3E%3C/svg%3E");
  --star-full: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23F5C542' stroke='%23253D0E' stroke-width='1.7' stroke-linejoin='round'%3E%3Cpath d='M12 2.6l2.94 5.96 6.58.96-4.76 4.64 1.12 6.55L12 17.61l-5.88 3.1 1.12-6.55L2.48 9.52l6.58-.96z'/%3E%3C/svg%3E");
  width: 3rem;
  height: 3rem;
  border-radius: 12px;
  font-size: 0;
  line-height: 1;
  background-image: var(--star-empty);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 2.15rem 2.15rem;
  transition: transform 0.3s var(--ease-out);
}
.survey-star.active { background-image: var(--star-full); }
.survey-stars:hover .survey-star { background-image: var(--star-full); }
.survey-stars .survey-star:hover ~ .survey-star { background-image: var(--star-empty); }
.survey-star:hover { transform: scale(1.12); }

/* Compact scale, 1 to 10 */
.survey-scale { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 0.4rem; }
.survey-scale__btn {
  height: 2.8rem;
  border: 1.5px solid var(--control-line);
  border-radius: 12px;
  background: #fff;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1rem;
  color: var(--forest);
  transition: border-color 0.2s, background-color 0.2s, color 0.2s, transform 0.3s var(--ease-out);
}
.survey-scale__btn:hover { border-color: var(--forest); background: var(--cream); transform: translateY(-1px); }
.survey-scale__btn.active { background: var(--forest); border-color: var(--forest); color: var(--cream); }
.survey-scale__ends { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.85rem; color: var(--ink-mute); }

/* Option cards, tighter than the session picker on the registration form */
.survey-options { gap: 0.5rem; }
.survey-options--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.survey-option { padding: 0.75rem 1rem; gap: 0.85rem; }
.survey-option .choice__title { font-size: 0.98rem; }
.survey-option .choice__mark { width: 1.3rem; height: 1.3rem; }
.survey-option .other-input { position: static; opacity: 1; width: 100%; height: auto; margin-top: 0.4rem; }
/* The square mark for the multi select cards is .choice--check in section 15,
   with survey-option--check kept there as its older name. */

/* Follow up the script reveals when expectations fell short */
.survey-followup:not(.visible) { display: none; }

/* Rating matrix: one row per aspect, five marks each */
.survey-matrix { width: 100%; border-collapse: collapse; }
.survey-matrix thead th {
  padding: 0 0.2rem 0.55rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-align: center;
  vertical-align: bottom;
}
.survey-matrix tbody th, .survey-matrix td { padding: 0.45rem 0.2rem; border-top: 1px solid var(--line); vertical-align: middle; }
.survey-matrix td { text-align: center; }
.survey-matrix tbody th { text-align: left; padding-right: 0.75rem; font-weight: 400; font-size: 0.95rem; line-height: 1.35; color: var(--ink); }
.survey-dot {
  width: 2.15rem;
  height: 2.15rem;
  margin: 0 auto;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1.5px solid var(--control-line);
  background: #fff;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.8rem;
  color: var(--ink-mute);
  transition: border-color 0.2s, background-color 0.2s, color 0.2s;
}
.survey-dot span { display: none; }
.survey-dot:hover { border-color: var(--forest); background: var(--cream); color: var(--forest); }
.survey-dot.active { background: var(--forest); border-color: var(--forest); color: var(--cream); }
.survey-matrix__key { display: none; justify-content: space-between; margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--ink-mute); }

@media (max-width: 600px) {
  .survey-options--2 { grid-template-columns: 1fr; }
  /* The matrix stacks: each aspect on its own line, five marks beneath it */
  .survey-matrix thead { display: none; }
  .survey-matrix, .survey-matrix tbody { display: block; }
  .survey-matrix tr { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.3rem; padding: 0.75rem 0; border-top: 1px solid var(--line); }
  .survey-matrix tr:first-child { border-top: 0; padding-top: 0; }
  .survey-matrix tbody th, .survey-matrix td { display: block; padding: 0; border: 0; }
  .survey-matrix tbody th { grid-column: 1 / -1; padding-bottom: 0.45rem; }
  .survey-dot { width: 100%; height: 2.5rem; border-radius: 10px; }
  .survey-dot span { display: inline; }
  .survey-matrix__key { display: flex; }
}
@media (max-width: 480px) {
  .survey-scale { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .survey-star { width: 2.6rem; height: 2.6rem; background-size: 1.9rem 1.9rem; }
  .survey-q__text { font-size: 1.02rem; }
}
@media (prefers-reduced-motion: reduce) {
  .survey-star, .survey-scale__btn, .survey-dot { transition: none; }
  .survey-star:hover, .survey-scale__btn:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   21. Information session page
   A landing page for families who came to an information session: one
   app head, two paths side by side (new families and registered families),
   a promo code chip and the discount claim form. The paths stack to one
   column below 880px. Prefix for everything here is .info.
   -------------------------------------------------------------------------- */
/* The two paths */
.info-paths {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
  max-width: 1040px;
}
.info-paths > .panel + .panel { margin-top: 0; }
.info-path { display: flex; flex-direction: column; }
.info-path > .eyebrow { margin-bottom: 0.75rem; }
.info-path__body { flex: 1 1 auto; margin-top: 0.6rem; color: var(--ink-soft); }
.info-path__body strong { color: var(--ink); }
.info-path__foot { margin-top: 1.5rem; }
.info-path__foot .btn { align-self: flex-start; }

/* The hand written discount line under the lead */
.app__head .info-hand { margin: 1rem 0 0; }

/* Promo code, set like a coupon stub, as wide as the input on the other path */
.info-code {
  display: grid;
  gap: 0.3rem;
  margin: 1.25rem 0 0;
  padding: 1rem 1.25rem 1.05rem;
  border: 1.5px dashed var(--line-strong);
  border-radius: 18px;
  background: var(--cream);
}
.info-code__label {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.info-code__value {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.6rem, 2.4vw, 1.9rem);
  line-height: 1;
  letter-spacing: 0.16em;
  color: var(--forest);
}

/* The line shown while registration is closed */
.info-closed { font-size: 0.98rem; line-height: 1.55; color: var(--ink-soft); }
.info-closed a { color: var(--forest); }

/* Claim form. The button label is long, so the group stacks at every width. */
.info-claim { display: grid; gap: 0.5rem; }
.info-claim .input-group { flex-direction: column; gap: 0.7rem; }
.info-claim .form__status { font-size: 0.95rem; line-height: 1.5; }
.info-claim .form__status--warn { color: var(--marker); }

/* Success notice, hidden until the script adds .visible */
.info-success { display: none; }
.info-success.visible { display: flex; }
.info-success__title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--forest);
  margin-bottom: 0.35rem;
}

/* Fine print under the two paths */
.info-fine {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  max-width: 62ch;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--ink-mute);
}
.info-fine a { color: var(--forest); }

@media (max-width: 880px) {
  .info-paths { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   22. The almanac: ribbon, city spread, ledger, field notes
   The shared layer for the rebuilt Experience page and the Afterschool page.
   Paper and forest ink, colour used as a thread of meaning rather than a fill.
   Two rules for this block: no opacity is ever applied to text (every text
   colour is a token measured against the background it actually sits on),
   and no dashes of any kind appear in a comment or a content string.
   Fraunces is loaded in its italic axis only, so every serif figure here
   carries font-style: italic, which is also how the serif is set everywhere
   else on the site.
   -------------------------------------------------------------------------- */

/* --- The moving line ---------------------------------------------------- */
/* One list in the markup. grove.js clones it until the track is wider than
   twice the viewport and translates by exactly one list width, so the loop
   cannot show a gap at any window size. With no JavaScript, or with reduced
   motion, the same single list is a static wrapped line. */
.ribbon {
  position: relative;
  padding: 0.95rem 0;
  background: var(--cream);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.ribbon__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to left, transparent, #000 3rem);
  mask-image: linear-gradient(to left, transparent, #000 3rem);
}
.ribbon__track {
  display: flex;
  width: max-content;
}
.ribbon.is-ready .ribbon__track {
  animation: ribbon-run var(--ribbon-duration, 24s) linear infinite;
}
@keyframes ribbon-run {
  from { transform: translateX(0); }
  to { transform: translateX(calc(-1 * var(--ribbon-w, 0px))); }
}
.ribbon__list {
  display: flex;
  align-items: center;
  flex: none;
}
.ribbon__list li {
  flex: none;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--forest);
  white-space: nowrap;
}
/* The separator is drawn, not typed: a small coral lozenge. Every item gets
   one, the last included, so the loop never shows a missing mark at the seam. */
.ribbon__list li::after {
  content: "";
  display: inline-block;
  vertical-align: middle;
  width: 6px;
  height: 6px;
  margin-inline: 1.6rem;
  background: var(--coral);
  transform: rotate(45deg);
}

/* Four ways to stop it: a pointer resting on the band, keyboard focus inside
   it, the control, and the band leaving the viewport. */
.ribbon:hover .ribbon__track,
.ribbon:focus-within .ribbon__track,
.ribbon.is-paused .ribbon__track,
.ribbon.is-off .ribbon__track { animation-play-state: paused; }

.ribbon__pause {
  position: absolute;
  right: calc(var(--gutter) + 0.25rem);
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 34px;
  height: 34px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(37, 61, 14, 0.55);
  color: var(--cream);
  opacity: 0.55;
  transition: opacity 0.25s, background-color 0.25s;
}
.ribbon:hover .ribbon__pause,
.ribbon__pause:focus-visible,
.ribbon.is-paused .ribbon__pause { opacity: 1; background: rgba(37, 61, 14, 0.8); }
.ribbon__pause-icon { width: 14px; height: 14px; }
.ribbon__pause-icon--play { display: none; }
.ribbon.is-paused .ribbon__pause-icon--play { display: block; }
.ribbon.is-paused .ribbon__pause-icon--pause { display: none; }
.ribbon__pause[hidden] { display: none; }

/* --- The two city index tabs -------------------------------------------- */
/* Plain anchor links, not tabs: nothing is hidden behind them, so there is no
   role that claims a behaviour the page does not have. */
.cities { margin-bottom: clamp(3rem, 6vw, 5rem); }
.cities__tabs {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0 0.5rem;
  padding-left: clamp(0.6rem, 2vw, 1.6rem);
}
.cities__label {
  flex: none;
  margin: 0 0.6rem 0.75rem 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--moss);
}
.cities__label::before { display: none; }

.cities__tab {
  --tab-mark: var(--line-strong);
  flex: none;
  margin-bottom: -1px;
  padding: 0.6rem 1.1rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.2;
  color: var(--forest);
  text-decoration: none;
  background: var(--paper);
  border: 1.5px solid var(--control-line);
  border-radius: 10px 10px 0 0;
  box-shadow: inset 0 4px 0 var(--tab-mark);
  transition: background-color 0.25s, border-color 0.25s, box-shadow 0.25s;
}
.cities__tab--champaign { --tab-mark: var(--leaf); }
.cities__tab--chicago { --tab-mark: var(--sky); }
.cities__tab:hover { background: var(--card); border-color: var(--forest); }
.cities__tab[aria-current="true"] {
  --tab-mark: var(--coral);
  background: var(--card);
  border-color: var(--forest);
  border-bottom-color: var(--card);
}

/* --- The spread and its two leaves -------------------------------------- */
.spread {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}
.spread.is-chicago { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
@media (prefers-reduced-motion: no-preference) {
  .spread { transition: grid-template-columns 0.45s var(--ease-out); }
}

.leaf {
  --leaf-bg: var(--paper);
  position: relative;
  background: var(--leaf-bg);
  padding: clamp(1.6rem, 3vw, 2.6rem);
  scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + 0.5rem);
  transition: background-color 0.3s;
}
.leaf.is-chosen {
  --leaf-bg: var(--card);
  box-shadow: inset 0 2px 0 var(--forest);
}
.leaf + .leaf { border-left: 1px solid var(--line); }

/* The bookmark: a coral ribbon hanging from the top edge of the chosen leaf.
   A pseudo element, so assistive technology never meets it. */
.leaf.is-chosen::before {
  content: "";
  position: absolute;
  top: 0;
  right: 1.6rem;
  width: 14px;
  height: 46px;
  background: var(--coral);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 78%, 0 100%);
}
@media (prefers-reduced-motion: no-preference) {
  .leaf.is-chosen::before { animation: leaf-bookmark 0.35s var(--ease-out) both; }
}
@keyframes leaf-bookmark {
  from { transform: translateY(-46px); }
  to { transform: translateY(0); }
}

/* Running head. The right padding keeps the mark clear of the bookmark on a
   narrow leaf, where the leaf padding is thinner than the bookmark inset. */
.leaf__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.2rem 1rem;
  padding: 0 1.2rem 0.7rem 0;
  margin-bottom: clamp(1.2rem, 2.5vw, 1.8rem);
  border-bottom: 1px solid var(--line-strong);
}
.leaf__folio {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--moss);
}
.leaf__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--forest);
}
.leaf__role {
  display: block;
  margin: 0.5rem 0 clamp(1.2rem, 2.5vw, 1.8rem);
  font-size: 1.15rem;
  line-height: 1.35;
  color: var(--ink-soft);
}
.leaf__line {
  font-size: clamp(1.2rem, 2vw, 1.4rem);
  line-height: 1.35;
  color: var(--forest);
  margin: clamp(1.4rem, 3vw, 2rem) 0 0;
}
.leaf--chicago .leaf__line { font-size: clamp(1.35rem, 2.2vw, 1.7rem); }

.leaf__grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 2.5rem;
  align-items: start;
}
/* Inside a city leaf the ledger has the card to itself, since the school
   photo now hangs under the dates stub, so it runs the full width. The
   Afterschool page keeps the two column arrangement for its own ledger. */
.leaf .leaf__grid { grid-template-columns: minmax(0, 1fr); }
/* The school photo, under the stub: a print on the page, not the half of the
   card it used to be. */
.leaf > .print {
  max-width: 380px;
  width: 100%;
  margin-top: clamp(1.4rem, 3vw, 2rem);
}
.leaf__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.8rem 1rem;
  margin-top: clamp(1.4rem, 3vw, 2rem);
}
/* The hand aside sits beside the stub while both fit on one line and drops
   under it when they do not, which is the behaviour asked for at 390. */
.leaf__note {
  display: inline-block;
  vertical-align: top;
  max-width: 12ch;
  margin: clamp(1.4rem, 3vw, 2rem) 0 0 1.2rem;
}

/* --- The ledger ---------------------------------------------------------- */
.ledger { margin: 0; border-top: 1px solid var(--line-strong); }
.ledger__row {
  position: relative;
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 0.3rem 1.2rem;
  align-items: baseline;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
}
/* Her colour, back on the page: a marker stroke down the left margin, in the
   colour of the tile she drew for that one fact. Decoration only; the label
   beside it always carries the meaning. */
.ledger__row--mark::before {
  content: "";
  position: absolute;
  left: -1rem;
  top: 0.85rem;
  bottom: 0.85rem;
  width: 4px;
  border-radius: 2px;
  background: var(--mark, var(--line-strong));
}
.ledger dt {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--moss);
}
.ledger dd {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.15rem;
  line-height: 1.3;
  color: var(--forest);
}
.ledger dd small {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--body);
  font-weight: 400;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.ledger dd a {
  display: inline-block;
  padding: 0.3rem 0;
  margin: -0.3rem 0;
  text-decoration-color: var(--line-strong);
}
.ledger__figure {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-variation-settings: "SOFT" 100;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--forest);
}

/* --- The dates stub ------------------------------------------------------ */
.stub {
  display: inline-block;
  vertical-align: top;
  width: min(100%, 20rem);
  margin-top: clamp(1.4rem, 3vw, 2rem);
  padding: 1.1rem 1.3rem;
  background: var(--butter);
  border-radius: 12px;
}
.stub__row { display: grid; gap: 0.15rem; margin: 0; }
.stub__label {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--forest);
}
.stub__value {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 500;
  font-variation-settings: "SOFT" 100;
  font-size: 1.35rem;
  line-height: 1.2;
  color: var(--ink);
}
/* The perforation: a dashed rule with a notch cut out of each end in whatever
   paper the leaf is showing, which is why the leaf carries --leaf-bg. */
.stub__perf {
  position: relative;
  height: 0;
  margin: 0.9rem -1.3rem;
  border-top: 1.5px dashed rgba(30, 36, 21, 0.35);
}
.stub__perf::before,
.stub__perf::after {
  content: "";
  position: absolute;
  top: -6px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--leaf-bg);
}
.stub__perf::before { left: -7px; }
.stub__perf::after { right: -7px; }

/* --- The lined page ------------------------------------------------------ */
/* Empty paper stays the honest state where there is nothing yet to say, but
   it is drawn rather than left as a hole. */
.ruled { margin-top: clamp(1.6rem, 3vw, 2.2rem); }
.ruled__line,
.ruled__rule {
  display: flex;
  align-items: flex-end;
  min-height: 2.2rem;
  margin: 0;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--line);
}
.ruled__line {
  font-size: 1.25rem;
  line-height: 1.3;
  color: var(--forest);
}

/* --- The sneak peek: head, index, rail ----------------------------------- */
.notes {
  padding: clamp(2rem, 4.5vw, 3.5rem) 0 clamp(4rem, 9vw, 7rem);
  scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + 0.5rem);
}
.notes__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 2.5rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.2rem);
}
.notes__head .display { font-size: clamp(2rem, 4vw, 3.2rem); margin-bottom: 0.7rem; }
.notes__head p { max-width: 52ch; color: var(--ink-soft); }
.notes__nav { display: grid; gap: 0.9rem; justify-items: end; }
.notes__index { display: flex; flex-wrap: wrap; gap: 0 0.9rem; }
.notes__index a {
  display: inline-block;
  padding: 0.3rem 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  color: var(--pink-deep);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: border-color 0.25s;
}
.notes__index a:hover,
.notes__index a[aria-current="true"] { border-bottom-color: var(--coral); }

.notes__band { background: var(--cream); }
.rail {
  --rail-pad: max(var(--gutter), calc((100% - 1240px) / 2));
  display: flex;
  align-items: stretch;
  gap: 1.5rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--rail-pad);
  padding: 1.75rem var(--rail-pad) 2.25rem;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }

.rail__nav { display: flex; align-items: center; gap: 0.8rem; }
.rail__btn {
  width: 40px;
  height: 40px;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  border: 2px solid var(--control-line);
  background: transparent;
  color: var(--forest);
  transition: border-color 0.2s, background-color 0.2s, opacity 0.2s;
}
.rail__btn:hover { border-color: var(--forest); background: rgba(37, 61, 14, 0.05); }
.rail__btn svg { width: 1.15em; height: 1.15em; }
/* The previous button reuses the site arrow, mirrored. The first control in
   the group is the previous one whether or not it carries the modifier. */
.rail__btn--prev svg,
.rail__nav > .rail__btn:first-child svg { transform: scale(-1, 1); }
.rail__btn--next svg,
.rail__nav > .rail__btn:last-child svg { transform: none; }
.rail__btn[aria-disabled="true"] { opacity: 0.35; cursor: default; }
.rail__btn[aria-disabled="true"]:hover { border-color: var(--control-line); background: transparent; }
.rail__count {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  color: var(--moss);
  font-variant-numeric: tabular-nums;
}

/* --- One field note ------------------------------------------------------ */
.note {
  position: relative;
  flex: none;
  width: 380px;
  scroll-snap-align: start;
  scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + 0.5rem);
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: 0.9rem;
  padding: 1.2rem 1.2rem 1.5rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 12px;
}
/* The thread. Three colours across the whole rail, and each one says which
   themed week the project belongs to. Every card also names its weeks in
   text, so the colour never carries the information on its own. */
.note::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  border-radius: 12px 12px 0 0;
  background: var(--thread, var(--line-strong));
}
.note--tech { --thread: var(--sky); --accent: var(--sky); }
.note--science { --thread: var(--leaf); --accent: var(--leaf); }
.note--both { --thread: var(--butter); --accent: var(--butter); }

.note__head { display: grid; gap: 0.3rem; }
.note__num {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  color: var(--pink-deep);
}
.note__title {
  margin: 0;
  font-family: var(--hand);
  font-weight: 700;
  font-size: clamp(1.65rem, 2.2vw, 2rem);
  line-height: 1.05;
  color: var(--marker);
}
.note__when {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--moss);
}
.note__when::before {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent, var(--moss));
}
.note__print {
  background: #fff;
  border-radius: 8px;
  padding: 6px;
  box-shadow: 0 1px 2px rgba(37, 61, 14, 0.08), 0 14px 32px -18px rgba(37, 61, 14, 0.45);
}
.note__print .photo { border-radius: 4px; }
.note__prints { display: grid; gap: 0.7rem; }
.note__body {
  align-self: start;
  margin: 0;
  max-width: none;
  font-family: var(--body);
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

/* The Afterschool variant: the same head, a lined page, and no rail until
   there are field notes to put in one. */
.notes--soon .notes__head { justify-content: flex-start; margin-bottom: clamp(2rem, 4vw, 3rem); }
.notes--soon .ruled { max-width: 720px; margin-inline: auto; }

/* --- Header and menu ----------------------------------------------------- */
/* Three real indented sub links under Experience in the mobile menu, which is
   where a level two destination belongs. */
.menu__sub {
  display: grid;
  gap: 0.1rem;
  margin: 0.1rem 0 0.6rem;
  padding-left: 1.2rem;
}
.menu__links .menu__sub a {
  font-size: 0.95rem;
  line-height: 1.4;
  text-transform: none;
  letter-spacing: 0;
  padding: 0.35rem 0;
}
.menu__links .menu__sub a:not([aria-current]) { color: var(--cream); }

/* You are inside this section, without claiming aria-current="page" on a URL
   where that would be false. The bottom margin gives back the padding the
   rule takes, so the item stays on the header's centre line. */
.nav a.is-section {
  text-decoration: none;
  border-bottom: 2px dotted var(--moss);
  padding-bottom: 2px;
  margin-bottom: calc(0.75rem - 2px);
}

/* .letter is reserved for the director's note on the About page and is not
   written in this round. */

/* --- Reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .ribbon { padding-inline: var(--gutter); }
  .ribbon__viewport { -webkit-mask-image: none; mask-image: none; }
  .ribbon__track { animation: none; width: auto; }
  .ribbon__list { flex-wrap: wrap; justify-content: center; row-gap: 0.35rem; }
  .ribbon__list li:last-child::after { display: none; }
  .ribbon__pause { display: none; }
  .spread, .spread.is-chicago { transition: none; }
  .leaf { transition: none; }
  .leaf.is-chosen::before { animation: none; }
  .cities__tab, .rail__btn, .notes__index a { transition: none; }
}

/* --- No JavaScript ------------------------------------------------------- */
html.no-js .ribbon { padding-inline: var(--gutter); }
html.no-js .ribbon__viewport { -webkit-mask-image: none; mask-image: none; }
html.no-js .ribbon__track { animation: none; width: auto; }
html.no-js .ribbon__list { flex-wrap: wrap; justify-content: center; row-gap: 0.35rem; }
html.no-js .ribbon__list li:last-child::after { display: none; }
html.no-js .ribbon__pause { display: none; }
html.no-js .rail__nav { display: none; }

/* --- Breakpoints: 1440, 1024, 820, 390 ----------------------------------- */
@media (max-width: 1100px) {
  .note { width: 340px; }
}
@media (max-width: 900px) {
  .note { width: 320px; }
}
@media (max-width: 880px) {
  .spread, .spread.is-chicago { grid-template-columns: 1fr; transition: none; }
  .leaf + .leaf { border-left: 0; border-top: 1px solid var(--line); }
  .leaf__grid { grid-template-columns: 1fr; gap: 1.6rem; }
}
@media (max-width: 760px) {
  .notes__head { flex-direction: column; align-items: flex-start; }
  .notes__nav { justify-items: start; }
}
@media (max-width: 700px) {
  .note { width: min(84vw, 330px); }
}
@media (max-width: 600px) {
  .ledger__row { grid-template-columns: 1fr; }
  .ledger__row--mark::before { left: -0.85rem; }
  .leaf__note { display: block; max-width: 24ch; margin-left: 0; }
}
@media (max-width: 560px) {
  .ribbon__list li { font-size: 0.74rem; letter-spacing: 0.16em; }
  .ribbon__list li::after { margin-inline: 1.1rem; }
  .cities__label { flex: 1 0 100%; margin: 0 0 0.5rem; }
}

/* --- Print --------------------------------------------------------------- */
@media print {
  .ribbon { padding-inline: 0; break-inside: avoid; }
  .ribbon__viewport { -webkit-mask-image: none; mask-image: none; }
  .ribbon__track { animation: none; width: auto; }
  .ribbon__list { flex-wrap: wrap; justify-content: center; row-gap: 0.35rem; }
  .ribbon__list li:last-child::after { display: none; }
  .ribbon__pause { display: none; }
  .rail__nav { display: none; }
  .rail {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    overflow: visible;
    padding: 1rem 0;
    gap: 1rem;
  }
  .rail .note { width: auto; break-inside: avoid; }
  .spread, .spread.is-chicago { grid-template-columns: 1fr; }
  .leaf + .leaf { border-left: 0; border-top: 1px solid var(--line); }
}

/* --------------------------------------------------------------------------
   23. Home hero: the scroll animation
   A coloured pencil sketch of the grove turns into the photograph as the page
   scrolls. grove.js blends the three layers (scripts/build-hero-layers.py) on
   the canvas and adds .hero-scroll--live; without it, which means JavaScript
   off, no canvas, or a reader who asked for less motion, the photo stands in
   as a poster and the section is one screen tall like any other hero.
   -------------------------------------------------------------------------- */
.hero-scroll {
  /* The paper of the drawing, so nothing else shows before it arrives. */
  --hero-paper: #FCECD3;
  position: relative;
  background: var(--hero-paper);
}
.hero-scroll .hero { min-height: 100vh; }
.hero-scroll .hero__backdrop { background: var(--hero-paper); }
.hero-scroll__canvas { display: none; width: 100%; height: 100%; }
.hero-scroll__poster { width: 100%; height: 100%; object-fit: cover; }
.hero-scroll__poster[hidden] { display: none; }

/* Live: the section is a tall track and the stage is pinned inside it, so the
   scroll distance becomes the length of the move. */
html.js .hero-scroll--live { height: 360vh; }
html.js .hero-scroll--live .hero-scroll__stage { position: sticky; top: 0; height: 100vh; overflow: hidden; }
html.js .hero-scroll--live .hero { min-height: 100vh; height: 100vh; }
html.js .hero-scroll--live .hero-scroll__canvas { display: block; }
html.js .hero-scroll--live .hero-scroll__poster { display: none; }
/* The green wash is for photographs; the drawing brings its own tone. */
html.js .hero-scroll--live .hero__backdrop::after { display: none; }
/* Live, the headline and the sentence share one spot and take turns. */
html.js .hero-scroll--live .hero__copy { place-items: center; gap: 0; }
html.js .hero-scroll--live .hero__title,
html.js .hero-scroll--live .hero__lead { grid-area: 1 / 1; }
html.js .hero-scroll--live .hero__title { color: var(--forest); }
html.js .hero-scroll--live .hero__lead { pointer-events: none; }
/* Every word moves on its own compositor layer: only transform and opacity
   change per frame, never anything that repaints text. */
html.js .hero-scroll--live .hero .w { will-change: transform, opacity; }
/* Headline words: rise in on load, then lift, swell and go as the colour
   finishes, one after another from the first word. */
/* The butter stroke under "making." and "exploring." draws itself in once
   its word has settled, and leaves with the word. */
.hero__title .uline svg { height: 0.3em; bottom: -0.16em; }
.hero__title .uline svg path { stroke-width: 7; }
html.js .hero-scroll--live .hero__title .uline svg path {
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - clamp(0, calc((var(--hero-intro, 1) - 0.45 - var(--i) * 0.05) / 0.25), 1));
}
html.js .hero-scroll--live .hero__title .w {
  --kin: clamp(0, calc((var(--hero-intro, 1) - var(--i) * 0.08) / 0.5), 1);
  --ko: clamp(0, calc((var(--hero-p, 0) - 0.3 - var(--i) * 0.02) / 0.1), 1);
  opacity: calc(var(--kin) * (1 - var(--ko)));
  transform: translateY(calc((1 - var(--kin)) * 0.35em - var(--ko) * 0.5em)) scale(calc(1 + var(--ko) * 0.08));
}
/* Sentence words: settle in one after another over the photograph. */
html.js .hero-scroll--live .hero__lead .w {
  --k: clamp(0, calc((var(--hero-p, 0) - 0.62 - var(--i) * 0.01) / 0.08), 1);
  opacity: var(--k);
  transform: translateY(calc((1 - var(--k)) * 0.5em));
}
/* The cue opens on cream paper here, not on a dark photograph, and leaves
   with the first scroll. */
html.js .hero-scroll--live .hero__scroll {
  color: var(--forest);
  text-shadow: none;
  opacity: calc(var(--hero-intro, 1) * clamp(0, calc(1 - (var(--hero-p, 0) - 0.1) / 0.1), 1));
}

@media (max-width: 700px) {
  html.js .hero-scroll--live { height: 300vh; }
}
