/* ==========================================================================
   Hebrew School of the Arts — Chabad Jewish Center of Troy
   Design system. See design-digest.md for the rules that govern these tokens.

   Hairline elevation: there is no shadow scale, on purpose. Do not add one.
   Depth comes from 1px hairlines, tonal contrast, and flat offset silhouettes.
   ========================================================================== */

:root {
  /* --- Canvas and ink --- */
  --paper:      #FBF7F0;   /* never pure white */
  --paper-2:    #F2EBDF;
  --paper-3:    #E9DFCE;
  --ink:        #1A1712;
  --ink-2:      #6A6055;
  --hair:       #E2D8C8;

  /* --- The single UI accent. CTA, links, focus ring, brand mark. Nothing else. --- */
  --accent:     #17706A;
  --accent-ink: #10534E;
  --accent-rgb: 23, 112, 106;

  /* --- Reserved ceremony color. Three approved locations only. --- */
  --ceremony:   #B4832A;

  /* --- Division blocks -------------------------------------------------
     Deep and rich rather than bright and primary. Earlier revision used
     mid-saturation brights (#3E7235 / #E0A32E / #2E6FA7 / #B4335F); against
     the ten-color Aleph Champ ladder that read kindergarten, not premium.
     These are the same hue families pushed darker so the ladder is the one
     bright moment on the page. All four verified >= 4.5:1 with white.
     -------------------------------------------------------------------- */
  --blk-sprouts: #2F5D3A;
  --blk-roots:   #8F5A12;
  --blk-crew:    #24476E;
  --blk-club:    #8A2B48;
  --on-blk:      #FFFFFF;

  /* Light tints of the same four, for stat tiles and quiet surfaces. */
  --tint-sprouts: #E6EDE5;
  --tint-roots:   #F6EBD6;
  --tint-crew:    #E4EAF1;
  --tint-club:    #F5E3E8;

  /* --- Aleph Champ level colors ---------------------------------------
     The program's real ten levels, taken from the client's own chart.
     These are program data, not brand palette: they appear in the level
     ladder and nowhere else on the site.
     -------------------------------------------------------------------- */
  --ac-white:  #FFFFFF; --ac-red:    #E1252B; --ac-orange: #EE7A17;
  --ac-yellow: #FBD914; --ac-green:  #17A24A; --ac-blue:   #1F3F94;
  --ac-purple: #9B4FA0; --ac-brown:  #8B4A1E; --ac-grey:   #9A9A9A;
  --ac-black:  #141414;

  /* --- Type ---
     Display is Bespoke Slab 700, body is Switzer, both from Fontshare rather
     than Google Fonts. The source matters: the "AI website" typographic
     signature comes from the Google top-fifty, the set every agent defaults to.
     A slab was chosen over the previous literary serif because at 96px a text
     serif reads *magazine* and this is a children's school — slabs carry
     bakery-and-signage associations that suit a culinary program, friendly
     without tipping into a cartoon face. Deliberately unlike the two sibling
     camp sites (Bangers, Boogaloo). Suez One remains solely for the Hebrew
     letters in the Aleph Champ ladder. See design-digest.md. */
  --font-d:  'Bespoke Slab', Georgia, serif;
  --font-b:  'Switzer', system-ui, -apple-system, sans-serif;
  --font-he: 'Suez One', Georgia, serif;

  --text-sm:         clamp(0.875rem, 0.85rem + 0.15vw, 0.9375rem);
  --text-base:       clamp(1rem, 0.95rem + 0.28vw, 1.1875rem);
  --text-lg:         clamp(1.125rem, 1rem + 0.55vw, 1.4375rem);
  --text-xl:         clamp(1.375rem, 1.05rem + 1.4vw, 2rem);
  --text-display-sm: clamp(2rem, 1.3rem + 3.2vw, 3.5rem);
  /* 9.3vw (~192px at 1920) overshot: it filled the column but pushed the stat
     row off the first screen. Budget for a 1000px window at 1920 is
     1000 - 80 header - 110 stat row = 810px of hero. The fixed parts of the
     left column (eyebrow, sub, buttons, note and their gaps) come to ~367px,
     and three headline lines run ~2.58x the font size, so with 44px of padding
     top and bottom the headline can be ~128px and still clear it.
     1rem + 5.85vw = ~128px at 1920, ~91px at 1280. */
  --text-display:    clamp(2.5rem, 1rem + 5.5vw, 7.5rem);
  --text-display-xl: clamp(3.25rem, 1.4rem + 9vw, 7.5rem);

  /* --- Space. Every value divisible by 8. --- */
  --s-1: 8px;  --s-2: 16px; --s-3: 24px; --s-4: 32px;
  --s-5: 40px; --s-6: 48px; --s-8: 64px; --s-10: 80px; --s-12: 96px;
  /* Floor was 4.5rem, so every phone sat at 72px - the same air as a laptop.
     PostHog drops section padding from 80px to 48px at mobile; 3.5rem is that
     move, eased slightly because our sections carry tint bands where theirs
     run on one continuous canvas. Only bites below ~654px, where 11vw < the
     floor, so desktop rhythm is untouched. */
  --section-pad:    clamp(3.5rem, 11vw, 9rem);
  --section-pad-lg: clamp(6rem, 14vw, 12rem);

  /* --- Radius ---
     Rounded up across the board. The rectangular-sober lane was an
     over-correction to avoid resembling the sibling camp sites; softer corners
     read friendlier, which is right for a program for three-to-thirteens. */
  --r-xs: 6px; --r-sm: 10px; --r-md: 14px;
  --r-lg: 18px; --r-xl: 24px; --r-full: 9999px;

  /* --- Tilt ---
     Applied to photographs only, never to cards, text blocks or buttons. Both
     camp sites tilt everything; here the tilt language is specifically
     "photographs pinned to a wall", which keeps it distinct and stops the whole
     page feeling askew. Kept under 1.5deg so nothing overflows. */
  --tilt-a: -1.3deg; --tilt-b: 1.1deg; --tilt-c: -0.8deg;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Grain. 3% opacity fractal noise, used on the hero and the dark band only —
   not as a divider on every section, which is its own tell. Breaks the
   too-perfect flatness that reads as machine-made. */
:root {
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

/* ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  font-kerning: normal;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color-scheme: light;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-b);
  font-weight: 400;
  font-size: var(--text-base);
  line-height: 1.62;
  text-wrap: pretty;
}

h1, h2, h3, h4 {
  font-family: var(--font-d);
  font-weight: 700;
  margin: 0;
  text-wrap: balance;
  line-height: 1.03;
  letter-spacing: -0.022em;
}

p { margin: 0; }
/* figure carries a default UA margin of 1em 40px, which silently ate 80px off
   every reel card. Reset globally rather than per-component. */
figure { margin: 0; }
img, svg { max-width: 100%; display: block; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }

[id] { scroll-margin-top: 88px; }

::selection { background: rgba(var(--accent-rgb), 0.16); color: var(--ink); }

::-webkit-scrollbar       { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--hair); border-radius: var(--r-full); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

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

/* Hebrew. Only appears in the Aleph Champ ladder. Negative tracking,
   synthesized italic and uppercase are all wrong for Hebrew, not merely
   undesirable, so these carry !important as a guard rail against any later
   single-class rule winning on source order. */
.he {
  font-family: var(--font-he);
  letter-spacing: 0 !important;
  font-style: normal !important;
  text-transform: none !important;
  line-height: 1.5;
}

/* ---------- Layout ---------- */

.container        { width: min(1280px, 100% - 3rem); margin-inline: auto; }
.container-narrow { width: min(760px,  100% - 3rem); margin-inline: auto; }

.section { padding-block: var(--section-pad); }
.section--tint { background: var(--paper-2); }

/* ---------- Pale tint bands ----------
   Copied wholesale from the PostHog system on getdesign.md: a cream floor with
   soft tinted panels doing the sectioning, rather than one flat canvas broken up
   by heavy saturated blocks. These are the same four hue families as the
   division colors, at roughly 12% strength, so the page reads as one family.
   Text on all four is --ink, which clears AA on every one by a wide margin. */
.section--mint   { background: var(--tint-sprouts); }
.section--butter { background: var(--tint-roots); }
.section--sky    { background: var(--tint-crew); }
.section--blush  { background: var(--tint-club); }

/* ---------- Callout ----------
   PostHog's banner-tip pattern: a soft tinted side-rail panel carrying a note,
   prefixed with an icon. Theirs uses an emoji; this uses a cut-paper mark, since
   emoji in headings is on the anti-slop list and this site already has a mark
   vocabulary. Flat fill, hairline border, no shadow. */
.callout {
  display: grid; grid-template-columns: 56px 1fr; gap: var(--s-3);
  align-items: start;
  background: var(--paper); border: 1px solid var(--hair);
  border-inline-start: 4px solid var(--accent);
  border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4);
  margin-top: var(--s-5);
}
.callout--mint   { border-inline-start-color: var(--blk-sprouts); background: var(--tint-sprouts); }
.callout--butter { border-inline-start-color: var(--blk-roots);   background: var(--tint-roots); }
.callout--sky    { border-inline-start-color: var(--blk-crew);    background: var(--tint-crew); }
.callout h3 {
  font-family: var(--font-d); font-weight: 700; font-size: var(--text-base);
  letter-spacing: -0.015em; margin-bottom: 4px;
}
.callout p { font-size: var(--text-sm); color: var(--ink-2); max-width: 60ch; }
.callout .spot { margin-bottom: 0; width: 56px; height: 56px; }
@media (max-width: 560px) {
  .callout { grid-template-columns: 1fr; }
  .callout .spot { width: 48px; height: 48px; }
}

/* ---------- Illustrated section head ----------
   PostHog pairs each feature row with a character vignette. Same idea: the mark
   gets real size and sits beside the heading instead of floating above it. */
.s-illus { display: grid; grid-template-columns: 200px 1fr; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
.s-illus .spot--xl { width: 200px; height: 200px; margin-bottom: 0; }
@media (max-width: 760px) {
  .s-illus { grid-template-columns: 1fr; gap: var(--s-3); }
  .s-illus .spot--xl { width: 132px; height: 132px; }
}

/* Section headers get a consistent editorial structure: a hairline, a tracked
   label, a large heading, and a lede at a controlled measure. */
.s-head { max-width: 40ch; }
.s-head--wide { max-width: 62ch; }

.eyebrow {
  display: flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-b); font-weight: 500;
  font-size: 0.75rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-2); margin: 0 0 var(--s-3);
}
.eyebrow::before {
  content: ""; width: 32px; height: 1px; background: currentColor;
  flex: none; opacity: 0.6;
}

/* ---------- Spot marks ----------
   Flat cut-paper objects placed as marginalia above section eyebrows. Taken as
   a principle from the PostHog breakdown on getdesign.md: its playfulness comes
   from scattered hand-drawn characters over flat surfaces, not from CSS effects,
   big radii or a decorative typeface. Objects are drawn from what the school
   actually makes — challah, a bowl, a palette, a menorah — so they carry
   meaning rather than decorating. Flat fills only, native aspect, never framed
   or cropped. Hidden from assistive tech; the heading carries the meaning. */
.spot { width: 104px; height: 104px; margin-bottom: var(--s-2); }
.spot--sm { width: 56px; height: 56px; }
@media (max-width: 640px) { .spot { width: 76px; height: 76px; } }

h2.s-title { font-size: var(--text-display-sm); }

.lede {
  font-size: var(--text-lg); color: var(--ink-2);
  max-width: 56ch; line-height: 1.55; margin-top: var(--s-3);
}
.fine { font-size: var(--text-sm); color: var(--ink-2); max-width: 62ch; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex; align-items: center; gap: var(--s-1);
  font-family: var(--font-b); font-weight: 500; font-size: var(--text-sm);
  letter-spacing: 0.01em;
  min-height: 48px; padding-inline: var(--s-3);
  border-radius: var(--r-sm); border: 1.5px solid transparent;
  text-decoration: none; cursor: pointer;
  transition:
    background-color 0.14s var(--ease),
    border-color     0.14s var(--ease),
    color            0.14s var(--ease),
    transform        0.10s var(--ease);
}
.btn:active { transform: scale(0.97); }

.btn--primary { background: var(--accent); color: #fff; }
.btn--primary:hover { background: var(--accent-ink); }

.btn--ghost { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: var(--paper); }

/* Inside a color block, buttons invert rather than reaching for the teal —
   the accent stays scarce. */
.btn--oncolor { background: var(--paper); color: var(--ink); }
.btn--oncolor:hover { background: transparent; color: var(--paper); border-color: var(--paper); }

.btn[aria-disabled="true"] { cursor: not-allowed; opacity: 0.45; }

/* Text link with a moving underline — a small, cheap piece of polish. */
.tlink {
  font-weight: 500; font-size: var(--text-sm); color: inherit;
  text-decoration: none; padding-bottom: 3px;
  border-bottom: 1.5px solid currentColor;
  transition: opacity 0.14s var(--ease);
}
.tlink:hover { opacity: 0.62; }

/* ---------- Nav ---------- */

.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(251, 247, 240, 0.92);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--hair);
}
.nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); padding-block: var(--s-2);
}

.wordmark {
  display: inline-flex; align-items: center; min-height: 32px;
  font-family: var(--font-d); font-weight: 700;
  font-size: clamp(1.0625rem, 0.9rem + 0.7vw, 1.3125rem);
  line-height: 1.1; letter-spacing: -0.02em;
  color: var(--ink); text-decoration: none;
}
/* The one intentional echo of camp.jewishtroy.com, requested in writing. */
.wordmark em { font-style: italic; color: var(--accent); }

.nav-links { display: flex; gap: var(--s-3); list-style: none; margin: 0; padding: 0; }
/* Hit area, not just text height. WCAG 2.2 target-size wants 24px minimum, and
   the inline-in-prose exception does not apply to a navigation list. */
.nav-links a {
  display: inline-flex; align-items: center; min-height: 32px;
  font-weight: 500; font-size: 0.875rem; color: var(--ink-2); text-decoration: none;
  transition: color 0.14s var(--ease);
}
.nav-links a:hover { color: var(--ink); }

.nav-cta { min-height: 44px; }

.nav-toggle {
  display: none; background: none; border: 0; cursor: pointer; color: var(--ink);
  /* 44px minimum touch target - it is the only nav control on a phone. */
  min-width: 44px; min-height: 44px; padding: var(--s-1);
  align-items: center; justify-content: center;
}

@media (max-width: 940px) {
  .nav-links { display: none; }
  .nav-toggle { display: inline-flex; }
  .nav-links--open a { min-height: 44px; width: 100%; }
  .nav-links--open {
    display: flex; flex-direction: column; position: absolute;
    inset-inline: 0; top: 100%; background: var(--paper);
    border-bottom: 1px solid var(--hair); padding: var(--s-3); gap: var(--s-2);
  }
}

/* ---------- Hero ----------
   Same skeleton as camp.jewishtroy.com: copy column on the left carrying a
   tilted tag chip, a big per-word-coloured headline, a tilted sub, a 2x2 facts
   grid, buttons and a note; one image on the right with tilted text cards laid
   over it. Structure borrowed, everything else this site's own. */

.hero {
  position: relative;
  /* Was 1.05fr 0.95fr with a clamp gap up to 3.5rem. At 1920 that left 334px
     of dead cream between the end of the sub-headline and the photo: 278px
     unused inside an over-wide text column plus a 56px gap. The photo now
     takes the larger share and the gap is gone - the fade below does the
     separating instead of empty space. */
  /* 0.92/1.08 left the headline filling only ~53% of its column at 1440.
     Narrowing the text column closes that dead space without growing the
     type back - which is what pushed the stat row off the first screen -
     and hands the extra width to the photograph. */
  display: grid; grid-template-columns: 0.78fr 1.22fr;
  gap: 0;
  align-items: center;
  /* padding-block lives on .hero-left now, so the photo can fill the band
     top to bottom instead of floating with cream above and below it. */
  padding-block: 0;
  padding-inline: max(1.5rem, calc((100vw - 1280px) / 2)) clamp(1.5rem, 4vw, 3rem);
  overflow: hidden;
}
/* Was up to 80px top / 88px bottom, which alone cost 168px of the first
   screen and pushed the stat row under the fold. */
.hero-left { padding-block: clamp(1.5rem, 2.2vw, 2.5rem) clamp(1.5rem, 2.2vw, 2.5rem); }
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: var(--grain); opacity: 0.03; mix-blend-mode: multiply;
}
.hero-left { position: relative; z-index: 1; }

/* Tag chip, tilted like a sticker. */
.hero-tag {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--tint-roots); color: #573809;
  border: 1px solid rgba(143, 90, 18, .3); border-radius: var(--r-full);
  padding: 8px 16px; rotate: -1.2deg; margin-bottom: var(--s-3);
  font-family: var(--font-b); font-weight: 500; font-size: 0.75rem;
  letter-spacing: 0.1em; text-transform: uppercase;
}

/* One word per line, one colour per word, each tilted a hair. All three are
   verified past 4.5:1 on the canvas, well beyond the 3:1 large text needs. */
.hero-h1 {
  font-size: var(--text-display);
  /* Tighter at the larger size - tracking scales with size, and -0.03em
     that suited 96px is loose at 120px. */
  letter-spacing: -0.038em; margin-bottom: var(--s-3);
}
.hero-h1 .hw { display: block; line-height: 0.9; }
.hero-h1 .hw1 { color: #146B64; rotate: -1deg; }
.hero-h1 .hw2 { color: #B4560F; rotate: 0.6deg; }
.hero-h1 .hw3 { color: #A32351; rotate: -0.4deg; }

.hero-sub {
  font-size: var(--text-lg); color: var(--ink-2);
  max-width: 40ch; line-height: 1.5; margin-bottom: var(--s-4);
  rotate: -0.3deg;
}

/* Facts live inside the hero, 2x2, each tinted. */
.hero-facts {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px; margin-bottom: var(--s-4); max-width: 30rem;
}
.hero-fact {
  padding: 12px 14px; border-radius: var(--r-md);
  border: 1px solid rgba(26, 23, 18, .1);
}
.hero-fact.f1 { background: var(--tint-sprouts); rotate: -0.6deg; }
.hero-fact.f2 { background: var(--tint-roots);   rotate: 0.5deg; }
.hero-fact.f3 { background: var(--tint-club);    rotate: 0.4deg; }
.hero-fact.f4 { background: var(--tint-crew);    rotate: -0.5deg; }
.hero-fact strong {
  display: block; font-family: var(--font-d); font-weight: 700;
  font-size: 1rem; letter-spacing: -0.015em; margin-bottom: 2px;
  font-variant-numeric: tabular-nums;
}
.hero-fact span {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-2);
}

.hero-btns { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.hero-note {
  margin-top: var(--s-3); font-size: var(--text-sm);
  color: var(--ink-2); max-width: 46ch;
}
.hero-note strong { color: var(--ink); }

/* --- Right column: image with tilted text cards over it --- */

.hero-right { position: relative; z-index: 1; padding-block: var(--s-4); }

.hero-right { display: grid; place-items: center; }
.hero-action-img {
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover;
  border: 10px solid var(--paper); border-radius: var(--r-lg);
  rotate: var(--tilt-b);
}

.hero-action-title {
  position: absolute; inset-inline-start: -6px; inset-block-start: -6px;
  background: var(--paper); border: 1px solid var(--hair);
  border-radius: var(--r-md); padding: 12px 16px; rotate: -2deg;
  font-family: var(--font-d); font-weight: 700;
  font-size: clamp(1.05rem, 0.85rem + 0.7vw, 1.5rem);
  line-height: 1.05; letter-spacing: -0.02em;
}
.hero-action-title span { display: block; }
.hero-action-title .ha1 { color: #146B64; }
.hero-action-title .ha2 { color: #B4560F; }
.hero-action-title .ha3 { color: #A32351; }

.hero-action-note {
  position: absolute; inset-inline-end: -4px; inset-block-end: 6px;
  max-width: 17rem;
  background: var(--ink); color: var(--paper);
  border-radius: var(--r-md); padding: 14px 16px; rotate: 2deg;
}
.hero-action-note strong {
  display: block; font-family: var(--font-d); font-weight: 700;
  font-size: 1.0625rem; letter-spacing: -0.015em; margin-bottom: 3px;
}
.hero-action-note span { font-size: 0.8125rem; line-height: 1.45; color: #C6BCAB; }

.hero-action-chip {
  position: absolute; inset-inline-end: 10px; inset-block-start: 0;
  background: var(--blk-sprouts); color: #fff;
  border-radius: var(--r-full); padding: 7px 14px; rotate: 3deg;
  font-family: var(--font-b); font-weight: 500; font-size: 0.6875rem;
  letter-spacing: 0.1em; text-transform: uppercase;
}

@media (max-width: 940px) {
  .hero {
    grid-template-columns: 1fr;
    padding-inline: clamp(1.25rem, 5vw, 2rem);
    /* Was var(--s-6) = 48px. With the photo stacked directly above the copy
       that row gap was most of the 69px sitting between them. Zero here; the
       16px of padding on .hero-left below is the whole separation, and the
       bottom fade carries the rest. */
    gap: 0;
  }
  /* padding-block removed: the panel has a fixed height below 940px, so this
     padding did nothing but widen the gap between photo and copy. */
  .hero-right { order: -1; padding-block: 0; }
  .hero-action-title { inset-inline-start: -2px; font-size: 1.05rem; padding: 10px 13px; }
  .hero-action-note { max-width: 15rem; inset-inline-end: -2px; inset-block-end: -14px; }
  .hero-facts { max-width: none; }
}
@media (max-width: 560px) {
  .hero-facts { grid-template-columns: 1fr 1fr; gap: 8px; }
  .hero-action-note { position: static; rotate: 0deg; max-width: none; margin-top: var(--s-3); }
  .hero-action-chip { inset-block-start: -6px; }
}

/* ---------- Dark band ---------- */

.band { position: relative; background: var(--ink); color: var(--paper); padding-block: var(--s-10); overflow: hidden; }
.band::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: var(--grain); opacity: 0.05;
}
.band > * { position: relative; z-index: 1; }
.band h2 { font-size: var(--text-display-sm); max-width: 22ch; margin-bottom: var(--s-3); }
.band p { color: #C6BCAB; max-width: 58ch; font-size: var(--text-lg); line-height: 1.5; }
.band .eyebrow { color: #A79C8A; }

/* ---------- Photo strip ---------- */

.strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; background: var(--ink); }
.strip figure { margin: 0; position: relative; overflow: hidden; }
.strip img { width: 100%; height: auto; object-fit: cover; aspect-ratio: 4 / 5; transition: transform 0.6s var(--ease); }
.strip figure:hover img { transform: scale(1.045); }
/* One honest credit line under the strip, rather than a caption per image
   asserting things the photographs do not actually show. */
.photo-credit {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-2);
  padding-block: var(--s-2);
}
@media (max-width: 760px) { .strip { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Reels ----------
   The school's own weekly Sunday videos, shot vertically on a phone at 480x848.
   Presented in their native 9:16 as a horizontal snap-scroll row, which is the
   format they were filmed for. Click to play — never autoplay: eight videos
   autoplaying is a bandwidth and accessibility problem, and muted autoplay on a
   school site reads as an ad. */
.reels {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(232px, 232px);
  gap: var(--s-2); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; padding-block: var(--s-2) var(--s-3);
  scrollbar-width: thin;
}
.reel { scroll-snap-align: start; position: relative; }
.reel video {
  width: 100%; aspect-ratio: 9 / 16; height: auto;
  object-fit: cover; display: block;
  background: var(--ink);
  border: 6px solid var(--paper); border-radius: var(--r-md);
  cursor: pointer;
}
.reel figcaption {
  margin-top: 10px; font-size: 0.75rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2);
}

/* Arrows sit ON the row, vertically centred against the cards — the
   conventional carousel position. They were previously stacked above it, which
   read as unrelated controls. Solid fill so they stay legible over video. */
.reels-wrap { position: relative; }
.reels-btn {
  position: absolute; top: calc(50% - 22px); z-index: 2;
  width: 48px; height: 48px; border-radius: var(--r-full);
  border: 1px solid var(--hair); background: var(--paper); color: var(--ink);
  display: grid; place-items: center; cursor: pointer;
  transition: background-color 0.14s var(--ease), color 0.14s var(--ease),
              opacity 0.16s var(--ease), transform 0.10s var(--ease);
}
#reelsPrev { inset-inline-start: -10px; }
#reelsNext { inset-inline-end: -10px; }
.reels-btn:hover:not(:disabled) { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.reels-btn:active:not(:disabled) { transform: scale(0.94); }
.reels-btn:disabled { opacity: 0; pointer-events: none; }
.reels-btn svg { width: 18px; height: 18px; }

/* Touch devices scroll the row by swiping, so the overlay arrows are noise. */
@media (max-width: 760px) { .reels-btn { display: none; } }
/* Play affordance, hidden once the clip is running. */
.reel-play {
  position: absolute; inset-inline-start: 50%; inset-block-start: 34%;
  translate: -50% -50%;
  width: 56px; height: 56px; border-radius: var(--r-full);
  background: rgba(251, 247, 240, 0.92); color: var(--ink);
  display: grid; place-items: center; pointer-events: none;
  transition: opacity 0.18s var(--ease);
}
.reel[data-playing="true"] .reel-play { opacity: 0; }
.reel-play svg { width: 20px; height: 20px; translate: 2px 0; }

@media (max-width: 560px) {
  .reels { grid-auto-columns: minmax(196px, 196px); }
}

/* ---------- Sunday timeline ---------- */

.timeline { list-style: none; margin: var(--s-6) 0 0; padding: 0; }
.timeline li {
  display: grid; grid-template-columns: 148px 1fr; gap: var(--s-4);
  padding-block: var(--s-4); border-top: 1px solid var(--hair);
  transition: background-color 0.2s var(--ease);
}
.timeline li:last-child { border-bottom: 1px solid var(--hair); }
.tl-time {
  font-family: var(--font-d); font-weight: 700; font-size: var(--text-lg);
  letter-spacing: -0.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
  display: flex; align-items: baseline; gap: 10px; color: var(--ink);
}
.tl-dot { width: 9px; height: 9px; border-radius: var(--r-full); flex: none; translate: 0 -3px; }
.timeline li:nth-child(1) .tl-dot { background: var(--blk-sprouts); }
.timeline li:nth-child(2) .tl-dot { background: var(--blk-crew); }
.timeline li:nth-child(3) .tl-dot { background: var(--blk-club); }
.timeline li:nth-child(4) .tl-dot { background: var(--blk-roots); }
.timeline li:nth-child(5) .tl-dot { background: var(--accent); }
.tl-body h3 { font-size: var(--text-lg); margin-bottom: 6px; }
.tl-body p { color: var(--ink-2); max-width: 58ch; }
@media (max-width: 660px) {
  .timeline li { grid-template-columns: 1fr; gap: var(--s-1); }
}

/* ---------- Division blocks ---------- */

.division { padding-block: var(--s-10); color: var(--on-blk); }
.division-inner { display: grid; grid-template-columns: 1.08fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.division:nth-of-type(even) .division-media { order: -1; }

.division--sprouts { background: var(--blk-sprouts); }
.division--roots   { background: var(--blk-roots); }
.division--crew    { background: var(--blk-crew); }
.division--club    { background: var(--blk-club); }

/* No opacity on labels over a saturated block: fading white drops small-text
   contrast below AA. Size, weight and tracking do the demoting. */
.d-ages {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: 0.75rem; font-weight: 500; letter-spacing: 0.16em;
  text-transform: uppercase; margin-bottom: var(--s-2);
}
.d-ages::before { content: ""; width: 28px; height: 1px; background: currentColor; flex: none; }

.division h2 { font-size: var(--text-display-sm); margin-bottom: var(--s-3); max-width: 20ch; }
.division p { max-width: 52ch; margin-bottom: var(--s-5); font-size: var(--text-base); }

/* Numbered, hairline-ruled list. Deliberately not a dot or an icon in front of
   each line — a marker glyph per bullet is the single most recognisable
   generated-page tell. A counter reads as editorial index instead. */
.division ol {
  list-style: none; margin: 0 0 var(--s-5); padding: 0;
  counter-reset: dpoint; max-width: 52ch;
}
.division ol li {
  counter-increment: dpoint;
  display: grid; grid-template-columns: 2.5rem 1fr; gap: var(--s-2);
  font-size: var(--text-sm); line-height: 1.5;
  padding-block: 14px;
  border-top: 1px solid rgba(255,255,255,.22);
}
.division ol li:last-child { border-bottom: 1px solid rgba(255,255,255,.22); }
.division ol li::before {
  content: "0" counter(dpoint);
  font-family: var(--font-b); font-weight: 500; font-size: 0.6875rem;
  letter-spacing: 0.1em; opacity: 0.72; translate: 0 3px;
  font-variant-numeric: tabular-nums;
}

/* height:auto is required, not cosmetic: the <img> carries width/height
   attributes for CLS, which make the box height definite and silently cancel
   aspect-ratio. Without this the per-division image shapes do nothing.
   The paper border plus tilt reads as a print pinned to the wall. */
.division-media img {
  width: 100%; height: auto; object-fit: cover;
  border-radius: var(--r-sm);
  border: 8px solid var(--paper);
  transition: rotate 0.3s var(--ease);
}
.division--roots .division-media img { rotate: var(--tilt-a); }
.division--crew  .division-media img { rotate: var(--tilt-b); }
.division--club  .division-media img { rotate: var(--tilt-c); }
.division-media img:hover { rotate: 0deg; }
.division-mark { width: min(100%, 320px); margin-inline: auto; }

/* ---- Per-division layout variants ----
   Four identical two-column blocks is a card grid rotated ninety degrees.
   Each division gets its own proportions, image shape and list rhythm so the
   page has a rhythm rather than a template. */

/* 01 Sprouts — copy-led, generous, tall paper mark alongside */
.division--sprouts .division-inner { grid-template-columns: 1.25fr 0.75fr; }

/* 02 Roots — image-led and wide, copy in a tighter measure */
.division--roots .division-inner { grid-template-columns: 0.9fr 1.1fr; }
.division--roots .division-media img { aspect-ratio: 5 / 4; }
.division--roots ol { grid-template-columns: 1fr 1fr; display: grid; column-gap: var(--s-4); }
.division--roots ol li:nth-child(2) { border-top: 1px solid rgba(255,255,255,.22); }

/* 03 Mitzvah Crew — the widest text column; portrait image offset lower */
.division--crew .division-inner { grid-template-columns: 1.5fr 0.85fr; align-items: end; }
.division--crew .division-media img { aspect-ratio: 3 / 4; }
.division--crew h2 { max-width: 26ch; }

/* 04 Bat Mitzvah Club — image dominant, copy in a narrow editorial column */
.division--club .division-inner { grid-template-columns: 0.8fr 1.2fr; }
.division--club .division-media img { aspect-ratio: 4 / 3; }
.division--club p { max-width: 44ch; }

@media (max-width: 880px) {
  .division-inner,
  .division--sprouts .division-inner,
  .division--roots .division-inner,
  .division--crew .division-inner,
  .division--club .division-inner { grid-template-columns: 1fr; align-items: start; }
  .division:nth-of-type(even) .division-media { order: 0; }
  .division--roots ol { grid-template-columns: 1fr; }
}

/* ---------- Aleph Champ ladder ---------- */

/* The ladder runs RIGHT TO LEFT. It carries the Hebrew alphabet in sequence
   (alef, beis, gimmel...), and running that left-to-right reads as broken to
   anyone who reads Hebrew — which is most of this school's point. Level 01 sits
   on the right and progress moves leftward.
   Each rung is set back to ltr so the English level names and the 01-10 numbers
   inside it are not themselves mirrored. */
.ladder {
  direction: rtl;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 2px; margin-top: var(--s-6);
  border: 1px solid var(--hair);
}
.ladder .rung { direction: ltr; }
.rung {
  padding: var(--s-3) var(--s-2) var(--s-3);
  display: flex; flex-direction: column; gap: 10px;
  transition: transform 0.16s var(--ease);
}
.rung:hover { transform: translateY(-2px); }
.rung-top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-1); }
.rung-he { font-size: 1.5rem; line-height: 1; }
.rung-n {
  font-family: var(--font-b); font-weight: 500; font-size: 0.625rem;
  letter-spacing: 0.1em;
  /* No opacity here. At 0.75 this failed contrast on five of the ten rungs
     (3.14:1 on level 02) - the same trap as .d-ages, which the premium pass
     already caught. The Aleph Champ colours are program data and cannot be
     altered, so the text has to carry the ratio. It is already de-emphasised
     by size against .rung-name; it does not need the alpha too. */
}
.rung-name {
  font-family: var(--font-b); font-weight: 500; font-size: 0.6875rem;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.rung-what { font-size: 0.75rem; line-height: 1.4; }

/* ---------- Month cycle ---------- */

.months { list-style: none; margin: var(--s-6) 0 0; padding: 0; }
.months li {
  display: grid; grid-template-columns: 190px 1fr; gap: var(--s-4);
  align-items: baseline; padding-block: var(--s-3); border-top: 1px solid var(--hair);
}
.months li:last-child { border-bottom: 1px solid var(--hair); }
.m-when { font-family: var(--font-d); font-weight: 700; font-size: var(--text-lg); letter-spacing: -0.02em; }
.m-what { color: var(--ink-2); }
@media (max-width: 620px) { .months li { grid-template-columns: 1fr; gap: 4px; } }

/* ---------- Pull quote ---------- */

.pull {
  font-family: var(--font-d); font-weight: 700;
  font-size: var(--text-xl); line-height: 1.15; letter-spacing: -0.03em;
  max-width: 30ch; margin-block: var(--s-8) 0;
  padding-inline-start: var(--s-4); border-inline-start: 2px solid var(--accent);
}

/* ---------- Two-up editorial ---------- */

.duo { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.duo-pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }
.duo-pair img {
  width: 100%; height: auto; aspect-ratio: 3 / 4; object-fit: cover;
  border-radius: var(--r-sm); border: 8px solid var(--paper);
}
/* Second image drops and counter-rotates, so the pair reads as two prints laid
   down by hand rather than a two-column image grid. */
.duo-pair img:first-child { rotate: var(--tilt-a); }
.duo-pair img:last-child  { rotate: var(--tilt-b); translate: 0 var(--s-6); }
@media (max-width: 880px) {
  .duo-pair img:last-child { translate: none; }
}
@media (max-width: 880px) { .duo { grid-template-columns: 1fr; } }

/* ---------- Divisions index — one compact band, four panels ----------
   Replaces four full-height division sections on the homepage (which were 30%
   of total page height, ~8 screens). Deliberately edge-to-edge panels with no
   gaps or borders so it reads as a single band of color rather than a
   four-card grid, which is the tell this site is trying to avoid. */

.dband { display: grid; grid-template-columns: repeat(3, 1fr); }
.dpanel {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 420px; padding: var(--s-5) var(--s-3) var(--s-4);
  color: var(--on-blk); text-decoration: none;
  transition: flex-grow 0.35s var(--ease);
}
.dpanel--sprouts { background: var(--blk-sprouts); }
.dpanel--roots   { background: var(--blk-roots); }
.dpanel--crew    { background: var(--blk-crew); }

.dpanel-n {
  font-family: var(--font-b); font-weight: 500; font-size: 0.6875rem;
  letter-spacing: 0.14em; margin-bottom: auto; font-variant-numeric: tabular-nums;
}
.dpanel h3 { font-size: var(--text-xl); margin-bottom: 6px; letter-spacing: -0.02em; }
.dpanel .dpanel-ages {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; margin-bottom: var(--s-2);
}
.dpanel p { font-size: var(--text-sm); line-height: 1.45; margin-bottom: var(--s-3); }
.dpanel-go {
  font-family: var(--font-b); font-weight: 500; font-size: var(--text-sm);
  display: inline-flex; align-items: center; gap: 8px;
  border-bottom: 1.5px solid currentColor; padding-bottom: 3px; align-self: flex-start;
  transition: gap 0.2s var(--ease);
}
.dpanel:hover .dpanel-go { gap: 14px; }

@media (max-width: 900px) {
  .dband { grid-template-columns: 1fr; }
  .dpanel { min-height: 320px; }
}
@media (max-width: 560px) {
  .dband { grid-template-columns: 1fr; }
  .dpanel { min-height: 0; padding-block: var(--s-4); }
  .dpanel-n { margin-bottom: var(--s-2); }
}

/* ---------- Division page hero ---------- */

.dhero { color: var(--on-blk); padding-block: var(--s-10) var(--s-8); position: relative; overflow: hidden; }
.dhero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: var(--grain); opacity: 0.05;
}
.dhero > * { position: relative; z-index: 1; }
.dhero--sprouts { background: var(--blk-sprouts); }
.dhero--roots   { background: var(--blk-roots); }
.dhero--crew    { background: var(--blk-crew); }
.dhero--club    { background: var(--blk-club); }
.dhero h1 { font-size: var(--text-display-sm); max-width: 24ch; margin-bottom: var(--s-3); }
.dhero .lede { color: rgba(255,255,255,.88); max-width: 54ch; }
.dhero .eyebrow { color: rgba(255,255,255,.85); }
.dhero-back {
  display: inline-flex; align-items: center; gap: 8px; color: var(--on-blk);
  font-size: var(--text-sm); font-weight: 500; text-decoration: none;
  margin-bottom: var(--s-4); opacity: 0.9;
}
.dhero-back:hover { text-decoration: underline; }

/* Numbered list on a light background, for the division pages. */
.plist { list-style: none; margin: var(--s-5) 0 0; padding: 0; counter-reset: pl; }
.plist li {
  counter-increment: pl;
  display: grid; grid-template-columns: 2.5rem 1fr; gap: var(--s-2);
  padding-block: var(--s-3); border-top: 1px solid var(--hair);
}
.plist li:last-child { border-bottom: 1px solid var(--hair); }
.plist li::before {
  content: "0" counter(pl);
  font-family: var(--font-b); font-weight: 500; font-size: 0.6875rem;
  letter-spacing: 0.1em; color: var(--ink-2); translate: 0 6px;
  font-variant-numeric: tabular-nums;
}
.plist h3 { font-size: var(--text-base); margin-bottom: 4px; }
.plist p { color: var(--ink-2); font-size: var(--text-sm); max-width: 58ch; }

/* ---------- Outcomes — large numerals, two columns, no rules ---------- */

.outcomes {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--s-6) clamp(2rem, 5vw, 4.5rem);
  margin-top: var(--s-8); counter-reset: oc; list-style: none; padding: 0;
}
.outcomes li { counter-increment: oc; }
.outcomes li::before {
  content: "0" counter(oc);
  display: block; font-family: var(--font-d); font-weight: 700;
  font-size: var(--text-lg); color: var(--accent);
  letter-spacing: -0.01em; margin-bottom: var(--s-1);
  font-variant-numeric: tabular-nums;
}
.outcomes h3 { font-size: var(--text-lg); margin-bottom: 6px; }
.outcomes p { color: var(--ink-2); font-size: var(--text-sm); max-width: 44ch; }
@media (max-width: 780px) { .outcomes { grid-template-columns: 1fr; gap: var(--s-5); } }

/* ---------- Tuition — a real table, not three pricing cards ---------- */

.tuition-wrap { margin-top: var(--s-6); overflow-x: auto; }
table.tuition { width: 100%; border-collapse: collapse; text-align: start; }
table.tuition caption { text-align: start; padding-bottom: var(--s-2); color: var(--ink-2); font-size: var(--text-sm); }
table.tuition th, table.tuition td {
  padding: var(--s-3) var(--s-2); border-top: 1px solid var(--hair);
  text-align: start; vertical-align: baseline;
}
table.tuition thead th {
  border-top: 0; border-bottom: 1px solid var(--ink);
  font-family: var(--font-b); font-weight: 500;
  font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2);
}
table.tuition tbody th { font-family: var(--font-d); font-weight: 700; font-size: var(--text-base); }
table.tuition td.amount {
  font-family: var(--font-d); font-weight: 700; font-size: var(--text-lg);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
table.tuition tbody tr:last-child { border-bottom: 1px solid var(--hair); }
.tuition-note { font-size: var(--text-sm); color: var(--ink-2); max-width: 62ch; margin-top: var(--s-4); }

/* ---------- Calendar ---------- */

.cal { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(2rem, 6vw, 5rem); }
.cal-facts { list-style: none; margin: 0; padding: 0; }
.cal-facts li { padding-block: var(--s-2); border-top: 1px solid var(--hair); }
.cal-facts li:last-child { border-bottom: 1px solid var(--hair); }
.cal-facts b { display: block; font-family: var(--font-d); font-weight: 700; font-size: var(--text-base); }
.cal-facts span { font-size: var(--text-sm); color: var(--ink-2); }
.cal-high { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.cal-high li {
  display: grid; grid-template-columns: 1.5rem 1fr; gap: var(--s-2);
  align-items: baseline; padding: var(--s-2) var(--s-2) var(--s-2) 0;
  border-top: 1px solid var(--hair); font-size: var(--text-sm);
}
.cal-high li:last-child { border-bottom: 1px solid var(--hair); }
.cal-high li::before {
  content: ""; width: 7px; height: 7px; border-radius: var(--r-full);
  background: var(--hair); translate: 0 -2px;
}
/* The reserved ceremony color, spent here and on the two teen division marks.
   Nowhere else — not on a button, not on a link. */
.cal-high li.is-ceremony::before { background: var(--ceremony); }
.cal-high li.is-ceremony { font-weight: 500; }
@media (max-width: 820px) { .cal { grid-template-columns: 1fr; } }

/* ---------- FAQ ---------- */

.faq { margin-top: var(--s-6); }
.faq details { border-top: 1px solid var(--hair); }
.faq details:last-of-type { border-bottom: 1px solid var(--hair); }
.faq summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3);
  padding-block: var(--s-3); cursor: pointer; list-style: none;
  font-family: var(--font-d); font-weight: 700; font-size: var(--text-lg);
  letter-spacing: -0.015em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; flex: none; font-family: var(--font-b); font-weight: 500;
  font-size: 1.25rem; color: var(--accent); line-height: 1;
  transition: transform 0.18s var(--ease);
}
.faq details[open] summary::after { content: "\2212"; }
.faq summary:hover { color: var(--accent-ink); }
.faq .faq-a { padding-bottom: var(--s-4); color: var(--ink-2); max-width: 66ch; }

/* ---------- Final CTA ---------- */

.cta-final { position: relative; background: var(--ink); color: var(--paper); padding-block: var(--s-12); overflow: hidden; }
.cta-final::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: var(--grain); opacity: 0.05;
}
.cta-final > * { position: relative; z-index: 1; }
.cta-final-inner { display: grid; grid-template-columns: 1.3fr 0.7fr; gap: clamp(2rem, 6vw, 5rem); align-items: end; }
.cta-final h2 { font-size: var(--text-display-sm); max-width: 24ch; margin-bottom: var(--s-3); }
.cta-final p { color: #C6BCAB; max-width: 52ch; }
.cta-final .eyebrow { color: #A79C8A; }
.cta-final .btn--primary { background: var(--paper); color: var(--ink); }
.cta-final .btn--primary:hover { background: var(--accent); color: #fff; }
.cta-final .btn--ghost { color: var(--paper); border-color: rgba(251,247,240,.5); }
.cta-final .btn--ghost:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.cta-buttons { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.cta-tag {
  font-family: var(--font-d); font-weight: 700; font-size: var(--text-lg);
  letter-spacing: -0.02em; color: var(--paper); margin-top: var(--s-5);
}
@media (max-width: 820px) { .cta-final-inner { grid-template-columns: 1fr; align-items: start; } }

/* ---------- Footer ---------- */

.footer { background: var(--paper-2); border-top: 1px solid var(--hair); padding-block: var(--s-8) var(--s-5); }
.footer-top { display: grid; grid-template-columns: 1.3fr 0.9fr 0.9fr 0.8fr; gap: var(--s-5); }
.footer-brand .wordmark { font-size: var(--text-lg); }
.footer-brand p { color: var(--ink-2); font-size: var(--text-sm); max-width: 42ch; margin-top: var(--s-2); }
.footer h3 {
  font-family: var(--font-b); font-weight: 500; font-size: 0.6875rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2);
  margin-bottom: var(--s-2); letter-spacing: 0.12em;
}
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.footer a { display: inline-flex; align-items: center; min-height: 28px; color: var(--ink); text-decoration: none; font-size: var(--text-sm); }
.footer a:hover { color: var(--accent); text-decoration: underline; }
.footer-bottom {
  margin-top: var(--s-6); padding-top: var(--s-3); border-top: 1px solid var(--hair);
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-3); justify-content: space-between;
  font-size: 0.8125rem; color: var(--ink-2);
}
/* 4 -> 2 -> 1 rather than 4 -> 1: dropping straight to a single column made a
   very tall stack on tablets. */
@media (max-width: 780px) { .footer-top { grid-template-columns: 1fr 1fr; gap: var(--s-5); } }
@media (max-width: 520px) { .footer-top { grid-template-columns: 1fr; } }

/* ---------- Scroll reveal ----------
   Opacity and transform only.

   Note the `.js-reveal` gate: the hiding rule applies ONLY once script has
   confirmed it can un-hide things. Content is therefore visible by default and
   stays visible if JS fails, IntersectionObserver is unavailable, or the
   observer never fires. Never hide content in CSS that only JS can restore. */
@media (prefers-reduced-motion: no-preference) {
  .js-reveal .reveal { opacity: 0; transform: translateY(14px); }
  .js-reveal .reveal.is-in {
    opacity: 1; transform: none;
    transition: opacity 0.5s var(--ease), transform 0.55s var(--ease);
  }

  /* Stagger — children of a .stagger group arrive in sequence rather than as a
     block. Delays are capped at 10 children; anything beyond simply arrives
     with the last one rather than trailing off for several seconds. */
  .js-reveal .stagger > * { opacity: 0; transform: translateY(12px); }
  .js-reveal .stagger.is-in > * {
    opacity: 1; transform: none;
    transition: opacity 0.45s var(--ease), transform 0.5s var(--ease);
  }
  .js-reveal .stagger.is-in > *:nth-child(1) { transition-delay: 0ms; }
  .js-reveal .stagger.is-in > *:nth-child(2) { transition-delay: 60ms; }
  .js-reveal .stagger.is-in > *:nth-child(3) { transition-delay: 120ms; }
  .js-reveal .stagger.is-in > *:nth-child(4) { transition-delay: 180ms; }
  .js-reveal .stagger.is-in > *:nth-child(5) { transition-delay: 240ms; }
  .js-reveal .stagger.is-in > *:nth-child(6) { transition-delay: 300ms; }
  .js-reveal .stagger.is-in > *:nth-child(7) { transition-delay: 360ms; }
  .js-reveal .stagger.is-in > *:nth-child(8) { transition-delay: 420ms; }
  .js-reveal .stagger.is-in > *:nth-child(n+9) { transition-delay: 480ms; }

  /* Cut-paper marks settle into place, as though set down by hand. */
  .js-reveal .reveal .spot,
  .js-reveal .stagger .spot { transform: rotate(-6deg) scale(0.92); transform-origin: 50% 70%; }
  .js-reveal .reveal.is-in .spot,
  .js-reveal .stagger.is-in .spot {
    transform: none;
    transition: transform 0.6s cubic-bezier(0.22, 1.2, 0.36, 1);
  }

  /* Hero entrance on load. No scroll needed — it is already in view. */
  .hero-left > * { animation: rise 0.62s var(--ease) both; }
  .hero-left > *:nth-child(1) { animation-delay: 0.05s; }
  .hero-left > *:nth-child(2) { animation-delay: 0.13s; }
  .hero-left > *:nth-child(3) { animation-delay: 0.21s; }
  .hero-left > *:nth-child(4) { animation-delay: 0.29s; }
  .hero-left > *:nth-child(5) { animation-delay: 0.37s; }
  .hero-action-img { animation: heroImg 0.9s var(--ease) both 0.12s; }
  @keyframes rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
  @keyframes heroImg { from { opacity: 0; transform: scale(1.04); } to { opacity: 1; transform: none; } }

  /* Division panels lift on hover. */
  .dpanel { transition: flex-grow 0.35s var(--ease), transform 0.28s var(--ease); }
  .dpanel:hover { transform: translateY(-4px); }
}
/* Right column bleeds to the viewport edge and is filled entirely, matching
   camp.jewishtroy.com where the hero image covers 104% of its panel. */
.hero { padding-inline: max(1.5rem, calc((100vw - 1280px) / 2)) 0; }
.hero-right {
  position: relative; z-index: 1; align-self: stretch;
  min-height: clamp(360px, 52vh, 620px);
  display: grid; place-items: center; overflow: hidden;
  /* Paper, not the blue tint it used to carry: the image is masked to
     transparent on its left edge, so whatever sits behind it IS the fade.
     A tint here would show as a coloured block bleeding out of the photo. */
  background: var(--paper);
  /* No left radius. A rounded corner made this read as a card pasted beside
     the text; square, full-height and faded, it reads as one surface. */
  border-radius: 0;
  padding: 0;
}

/* The photo dissolves into the paper on its left edge rather than butting
   against the copy with a hard line. This is the "fading into each other"
   the client asked for, and it is why the grid gap could go to zero: the
   fade does the separating, so the headline can sit close without colliding.
   Desktop only - below 940px the panel is a full-width band above the copy,
   where a left-edge fade would make no sense. Both mask properties are
   needed; Safari still wants the prefix. */
@media (min-width: 941px) {
  .hero-action-img {
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 26%);
            mask-image: linear-gradient(to right, transparent 0%, #000 26%);
  }
}
.hero-action-img,
.hero-fallback {
  width: 100%; height: 100%; object-fit: cover; display: block;
  border: 0; border-radius: 0; rotate: none;
  /* aspect-ratio: auto is REQUIRED here, not tidiness. The earlier
     .hero-action-img rule (the framed, tilted treatment) sets aspect-ratio
     4/5, and an aspect-ratio silently beats height: 100% - the image rendered
     438px tall inside a 200px panel and overflowed it. This is the same trap
     the digest records in mirror image: there, width/height attributes
     cancelled an aspect-ratio; here, an aspect-ratio cancels a height. */
  aspect-ratio: auto;
  /* The source is now framed head-to-craft, and the panel still crops ~140px
     of it vertically. Biased low (62%) so that crop comes off the top rather
     than the bottom: losing a little headroom costs nothing, losing the flower
     pot she is holding up costs the whole point of the photograph.
     62% put the craft dead centre but cropped her eyes, which is the worse
     trade for a school hero - a face with no eyes reads as a mistake. 50%
     keeps the eyes and still carries the flowers and most of the pot. */
  object-position: center 50%;
}

/* The panel is display:grid with place-items:center, so its child is never
   stretched and a percentage height does not resolve - the image took its
   intrinsic 250px inside a 200px panel. Pinning to the panel box is
   deterministic and does not care how the panel lays its children out.
   .hero-right is position:relative, so inset:0 is exactly the panel. */
.hero-action-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.hero-fallback { padding: clamp(1rem, 3vw, 2.5rem); }

/* Cards sit over the filled panel — kept fully inside it, since a negative
   inline start pushed this one over the headline column. */
.hero-action-title { inset-inline-start: 18px; inset-block-start: 16px; }
.hero-action-note  { inset-inline-end: 18px; inset-block-end: 16px; }
.hero-action-chip  { inset-inline-end: 18px; inset-block-start: 16px; }

/* ---------- Stat row: one full-width row under the header ---------- */
.stat-row {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--hair); border-block: 1px solid var(--hair);
}
.stat { padding: var(--s-3) clamp(1rem, 2.4vw, 1.75rem); }
.stat.s1 { background: var(--tint-sprouts); }
.stat.s2 { background: var(--tint-roots); }
.stat.s3 { background: var(--tint-club); }
.stat.s4 { background: var(--tint-crew); }
.stat strong {
  display: block; font-family: var(--font-d); font-weight: 700;
  font-size: var(--text-lg); letter-spacing: -0.02em; margin-bottom: 3px;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
}
.stat span {
  /* Was 0.6875rem (11px). These carry the hours, the session count and the
     age range - information, not decoration - and read as fine print. */
  font-size: 0.8125rem; font-weight: 500; letter-spacing: 0.07em;
  text-transform: uppercase; color: var(--ink-2);
}
@media (max-width: 760px) {
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  /* These carry real information on a phone - the hours and the age range -
     not decoration. 11px with 0.1em tracking is a label size, not a reading
     size, so ease both back at the width where the row goes 2-up. */
  .stat span { font-size: 0.75rem; letter-spacing: 0.06em; }
}

@media (max-width: 940px) {
  .hero { padding-inline: clamp(1.25rem, 5vw, 2rem); }
  /* Below 940px .hero-right takes order: -1, so this panel is spent before the
     reader reaches the headline. At 42vh it ran to ~354px on a 390x844 phone
     and pushed Enroll Now past the fold. Fixed heights, not vh: the panel is
     decoration above the copy, so it should cost a predictable amount rather
     than scale with the screen. The real hero photo fills it the same way via
     object-fit: cover. */
  .hero-right {
    border-radius: var(--r-lg);
    /* The base rule sets align-self: stretch. Left alone, the grid row keeps
       its content-derived height and stretches the panel straight back, so the
       height below does nothing. Both declarations are needed. */
    align-self: start;
    min-height: 0;
    height: 260px;
  }
}
@media (max-width: 940px) {
  /* Measured at 390x844: 85px sat between the bottom of the photo and the
     eyebrow, which is what made the two read as separate blocks stacked up
     rather than one hero. */
  .hero-left { padding-block: var(--s-2) var(--s-6); }

  /* The mobile equivalent of the desktop edge fade: the photo dissolves
     downward into the paper instead of ending on a hard line above the copy.
     Same idea, rotated 90 degrees to match the stacked layout. */
  .hero-action-img {
    -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  }
}
@media (max-width: 560px) {
  /* The eyebrow chip cost ~68px (44px tall plus a 24px margin) sitting between
     the photograph and the headline, which is what made the phone hero feel
     loose. Everything it says is already on screen: the wordmark names the
     school in the header, and the stat row directly below carries "Starts
     Oct 11" and "Troy, MI". Hidden on phones only - it still renders on
     tablet and desktop, where there is room for it. */
  .hero-tag { display: none; }

  /* The 68px goes into the photograph. 200px was a thin strip; 300 gives it
     presence and the headline now sits directly under it. */
  .hero-right { height: 300px; }

  /* The headline left 183px of a 350px column unused at 48px. */
  .hero-h1 { font-size: clamp(3.25rem, 16vw, 4.5rem); letter-spacing: -0.04em; }
}
