/* harvardae.org — the design system.
 *
 * The token reference at /styleguide is generated from this file and is the
 * readable version of it: every colour with its measured contrast, every size
 * with what it renders at, and the places this stylesheet contradicts its own
 * rules. Start there.
 *
 * HAE asked for a site that feels bright, dynamic, founder-centered, global,
 * personal, modern and welcoming — and does not feel institutional, corporate,
 * academic, dark or like a generic startup. Four decisions follow from that and
 * they are the ones to know before changing anything here:
 *
 *   - Light only. No dark surface, and no block that switches on an operating
 *     system's dark preference: color-scheme is declared light so the page
 *     cannot be inverted into an appearance HAE asked us to avoid.
 *   - White paper and neutral stone bands, warm ink rather than black. The
 *     surfaces were cream and peach until 2026-09-14, when Regina wrote she was
 *     "not crazy for the creamsicle coloring at the bottom and as color
 *     background on the blocks" (solace/canon/_feedback/2026-09-13-regina-ryan/).
 *     Crimson and gold carry the colour; serif body copy still reads academic.
 *   - Hard offset shadows and 2px borders rather than soft grey elevation.
 *     Soft elevation on rounded cards is the default startup look; this reads
 *     as printed matter, which suits a volunteer-run community of 25 years.
 *   - One system font stack, no webfont. The site renders with no network
 *     request for type — and no typeface has been chosen for HAE, which is an
 *     open question rather than a preference. See /styleguide.
 */

:root {
  color-scheme: light;

  --paper: #FFFFFF;
  --paper-2: #F6F5F3;
  --blush: #F8F0F1;
  /* Demo 2 program surfaces, approved by Regina 2026-10-24; reserved here for token parity. */
  --program-peach: #F7E2D5;
  --program-blue-gray: #E3ECEF;
  --program-lavender: #EDE3F3;
  --ink: #1F1714;
  --ink-2: #4A3B34;
  --ink-3: #7A6659;
  --rule: #E4E0DC;

  --crimson: #A51C30;
  --crimson-deep: #7E1224;
  --gold: #F5B324;
  --gold-deep: #A9740A;
  --sea: #0B6E63;

  --wrap: 1180px;
  --narrow: 760px;

  --step--1: clamp(.82rem, .8rem + .1vw, .9rem);
  --step-0: clamp(1rem, .96rem + .2vw, 1.09rem);
  --step-1: clamp(1.2rem, 1.1rem + .45vw, 1.42rem);
  --step-2: clamp(1.5rem, 1.3rem + .9vw, 2rem);
  --step-3: clamp(2rem, 1.6rem + 1.8vw, 3rem);
  /* The floor is 2.1rem and not 2.6rem because "Entrepreneurship" — the
     longest word any headline writes — needs 400px at 2.6rem and a 390px phone
     gives the headline 352px. The grid track sized itself to that word and
     pushed two pages 29px wider than the screen. Measured on the device, not
     reasoned about. Raising this floor puts it back. */
  --step-4: clamp(2.1rem, 1.4rem + 2.6vw, 3.9rem);

  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;

  /* NO ELEVATION. Both tokens were hard offsets — `6px 6px 0 ink` on eleven
     objects and `4px 4px 0 gold` on the cards. The header comment above
     defended them as "printed matter"; iris ruled against that on 2026-08-12
     and the ruling is recorded in canon 06. Three grounds, short version:
     print has no floating shadows and no 999px pills, and this sheet ran both
     at once; the actual printed-matter idiom was already in the token table as
     `--rule` ("hairlines, card edges") and was passed over; and the shadow
     language appears in zero of the 22,444,668 customer pixels that settled
     the crimson. Hard-offset-plus-thick-ink-border is *neubrutalism*, a named
     template trend of 2021-2024 — which is the brief's "Generic startup
     aesthetics" prohibition, not an escape from it.
     Kept as tokens rather than deleted so the eleven call sites stay readable
     as one decision, and so restoring elevation is one line if that ruling is
     ever overturned. */
  --shadow: none;
  --shadow-soft: none;

  /* ONE corner language. The sheet held seven — 999px, 18, 16, 12, 10, 6, 3, 2
     — which is what made pill buttons and boxy cards read as two designs
     sharing a page. 999px survives only where the shape IS the meaning: a
     chip, a tag, a toggle. */
  /* One size and one tracking for every uppercase kicker. The sheet held
     13 sizes inside a 0.2rem band and four trackings for one job; nobody can
     see .68rem against .70rem, so thirteen near-duplicates are noise, not
     decisions. */
  --micro: .72rem;
  --track-caps: .14em;

  --r-sm: 8px;
  --r-lg: 12px;
  --r-pill: 999px;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 var(--step-0)/1.65 var(--sans);
  letter-spacing: -.005em;
}

/* Optical tracking and leading scale with size. One pair for all three levels
   put 32px card headings on 33.6px leading — 1.6px between two lines. */
h1, h2, h3 { margin: 0; font-weight: 800; }
h1 { line-height: 1.06; letter-spacing: -.03em; }
h2 { line-height: 1.15; letter-spacing: -.022em; }
h3 { line-height: 1.25; letter-spacing: -.012em; }
p { margin: 0 0 1rem; }
ul, ol { margin: 0; padding: 0; }
a { color: var(--crimson); text-underline-offset: .18em; text-decoration-thickness: .09em; }
a:hover { color: var(--crimson-deep); }
img, svg { max-width: 100%; }

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

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

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--crimson); color: #fff; padding: .8rem 1.2rem; font-weight: 700;
}
.skip:focus { left: 0; }

.wrap { width: min(100% - 2.4rem, var(--wrap)); margin-inline: auto; }
.wrap-narrow { width: min(100% - 2.4rem, var(--narrow)); }

/* ---------------------------------------------------------------- masthead */

.masthead {
  position: sticky; top: 0; z-index: 40;
  background: rgba(255, 251, 245, .94);
  backdrop-filter: saturate(1.4) blur(8px);
  border-bottom: 1px solid var(--rule);
}
.masthead-in {
  display: flex; align-items: center; gap: 1.4rem;
  min-height: 68px; padding-block: .5rem;
  /* WRAP, and let both children shrink. Without these three declarations this
     row held a hard 528px floor — `.brand` and `.utility` were both
     `flex: 0 0 auto` inside a nowrap flex container, so the row could not
     shrink and it pushed all twelve pages 138px wider than a 390px phone. The
     h1 clipped mid-word ("Entrepreneurshi") and the header's own "Join HAE"
     ran off-screen. Desktop overflow was exactly 0px, so it was invisible at
     any width anyone had looked at.

     `min-width: 0` is the load-bearing part — flex items default to
     `min-width: auto`, which refuses to shrink below content size. */
  flex-wrap: wrap;
}
.brand {
  display: grid; text-decoration: none; line-height: 1;
  flex: 1 1 auto; min-width: 0;
}
.brand-mark {
  font-size: 1.45rem; font-weight: 800; letter-spacing: -.05em; color: var(--crimson);
}
.brand-sub {
  font-size: .66rem; font-weight: 700; letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--ink-3); margin-top: .18rem;
  /* The widest fixed thing in the masthead: uppercase at .16em tracking.
     Allowed to break rather than to set the row's floor. */
  overflow-wrap: anywhere;
}

/* Regina's horizontal logo (sonnet-hae-logo-20260912). The shipped PNG is
   3704x2084 with the crest-and-wordmark band sitting in the middle of large
   white margins — mostly vertical, some horizontal. The frame is a fixed,
   phone-safe box with `overflow: hidden`; the image inside is stretched to
   fill it with `object-fit: cover`, which — because the frame is far wider
   relative to its height than the source photo is — scales the PNG to the
   frame's WIDTH and lets the excess height (the white margin above and below
   the wordmark) run off the top and bottom edges, `object-position: center`
   keeping the crop vertically centered on the band. No pixel of the PNG is
   ever touched; this crops the presentation only.
   No `mix-blend-mode`: blending would touch every pixel of the PNG to hide
   one edge, and no pixel of it is touched here. The masthead and footer
   grounds are both near-white (`.masthead`'s `rgba(255,251,245,.94)`, the
   footer's `--paper-2`) but neither is identical to the logo's own white
   background, so its white rectangle can remain visible against either
   ground rather than disappearing into it. */
.brand-logo-frame {
  display: block; overflow: hidden;
  width: 148px; height: 28px;
}
.brand-logo {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
@media (min-width: 640px) {
  .brand-logo-frame { width: 210px; height: 40px; }
}

.primary { flex: 1 1 auto; }
.primary ul { display: flex; flex-wrap: wrap; gap: .1rem; list-style: none; justify-content: center; }
.primary a {
  display: block; padding: .45rem .55rem; border-radius: 999px;
  font-size: .88rem; font-weight: 600; color: var(--ink-2); text-decoration: none;
}
.primary a:hover { background: var(--blush); color: var(--crimson); }
.primary a[aria-current="page"] {
  background: var(--ink); color: var(--paper);
}

/* The wrap is STRUCTURAL: content needs 1543px against a 1180px wrap, so the
   second row happens at every desktop width. Left-dangling under the brand it
   read as a bug; pushed right it reads as a designed two-tier masthead. */
.utility { display: flex; align-items: center; gap: .45rem; flex: 0 1 auto; min-width: 0; margin-left: auto; }
.util {
  font-size: .82rem; font-weight: 600; text-decoration: none; color: var(--ink-2);
  padding: .4rem .6rem; border-radius: 999px;
}
.util:hover { background: var(--blush); }
.util-join {
  background: var(--crimson); color: #fff; border: 1px solid transparent;
  padding: .45rem .95rem;
}
.util-join:hover { background: var(--crimson-deep); color: #fff; }

.cite-toggle, .menu-toggle {
  font: 600 .78rem var(--sans); cursor: pointer;
  background: transparent; color: var(--ink-2);
  border: 2px solid var(--rule); border-radius: 999px; padding: .35rem .7rem;
}
.cite-toggle[aria-pressed="true"] { background: var(--gold); border-color: var(--ink); color: var(--ink); }
.menu-toggle { display: none; }

.mobile-nav { border-top: 1px solid var(--rule); background: var(--paper-2); }
.mobile-nav ul { list-style: none; display: grid; }
.mobile-nav a {
  display: block; padding: .85rem 1.2rem; font-weight: 700; text-decoration: none;
  color: var(--ink); border-bottom: 1px solid var(--rule);
}

@media (max-width: 1080px) {
  .primary { display: none; }
  .menu-toggle { display: inline-block; }
  .util:not(.util-join) { display: none; }
}

/* -------------------------------------------------------------------- hero */

.hero { padding: clamp(2.4rem, 5vw, 4.4rem) 0 0; background:
  radial-gradient(120% 90% at 12% 0%, var(--blush) 0%, transparent 58%),
  radial-gradient(90% 70% at 96% 8%, var(--paper-2) 0%, transparent 55%);
}
.hero-in { display: grid; grid-template-columns: 3fr 2fr; gap: clamp(1.6rem, 4vw, 3.4rem); align-items: start; }
.hero-aside:empty { display: none; }
.hero-in:has(.hero-aside:empty) { grid-template-columns: 1fr; }

.eyebrow-row { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; margin-bottom: 1.1rem; }
.eyebrow {
  display: inline-block; margin: 0;
  /* Was a gold pill with a 2px ink border, 454px wide, directly above the h1
     on all 12 pages — the least important line carrying the highest visual
     mass. Now the site's own quiet-kicker pattern. crimson on blush is
     6.37:1, on paper 7.25:1 — AA small text either way. */
  background: transparent; border: 0; border-radius: 0; padding: 0;
  font-size: var(--micro); font-weight: 800; color: var(--crimson);
  letter-spacing: var(--track-caps); text-transform: uppercase;
}
/* Program-page identity must read before a generic display headline. Regina's
   2026-09-13 review named the Accelerator as the concrete miss: its exact name
   was present here at 11.52px, but her eye did not see it. Keep the quiet
   kicker language and add hierarchy rather than restoring the old heavy pill. */
.program-identity {
  font-size: var(--step-0); line-height: 1.3;
  border-inline-start: .28rem solid var(--gold);
  padding-inline-start: .75rem;
}
/* 2026-09-14: 17px was still read as a caption above a 60px headline. On a
   single program's page the program's name is a title line of its own and the
   rest of her eyebrow ("· Powered by …") drops under it at body size. */
.program-name { display: block; font-size: var(--step-2); line-height: 1.15; }
.program-by { display: block; margin-top: .35rem; color: var(--ink-2); }
.program-sep { display: none; }
.flag {
  margin: 0; font-size: .8rem; font-weight: 700; color: var(--ink-2);
  display: inline-flex; align-items: center; gap: .45rem;
}
.flag::before {
  content: ""; width: .55rem; height: .55rem; border-radius: 50%;
  background: var(--sea); box-shadow: 0 0 0 4px rgba(11, 110, 99, .18);
}

/* `overflow-wrap: anywhere` is the fail-safe, not the fix: it also lowers the
   element's min-content, so a longer word than we have today wraps instead of
   widening the track. The type floor above is what keeps today's words whole. */
.hero-h { font-size: var(--step-4); max-width: 18ch; overflow-wrap: anywhere; }

/* The accent was ONE element doing two jobs: `display: block` broke the line
   before it AND made the painted gold the width of the container. A highlight
   whose width is the container's is not a highlight, it is a rule that happens
   to start where the words do. Measured in Chromium on 2026-08-12, at 1440:
   448px of gold past "this site." on `search`, 434px past the last line on
   `operators` and `events`, 397px on `about`. At 390 the one that settles it:
   `give-back` painted 352px behind the 40px word "it." — 8.8x the text.
   canon 06 recorded 23-53px for this on the phone and called it "the one
   genuine defect here"; at 1440 nobody had looked.

   The two jobs are now two elements. `.hero-accent-line` keeps the break, so
   the headline composes exactly as before; `.hero-accent` is inline, so the
   paint is the text. `box-decoration-break: clone` is the load-bearing half —
   the accent wraps to two or three lines on seven of the twelve pages at 1440
   and eight at 390 (counted, after the fix, in the same browser), and
   without it the fragments share one box and the band paints across the gap
   between lines instead of under each of them. `background-size: 100% 100%`
   is gone: on an inline box it re-introduces exactly the sizing being fixed.

   NO TRAILING PADDING. This rule carried `padding-inline-end: .1em`, added to
   give the gold band a little air past the final glyph. Two things then
   happened to it. First, the band was retired further down this sheet — the
   later `background: none` on this class means the padding paints nothing at
   all, on any page, at any width. Second, it is inline-end padding on an inline
   box, so it is width the line box does not get to break: `overflow-wrap:
   anywhere` on `.hero-h` guarantees no WORD can be wider than the box, which
   leaves this padding as the only thing in the headline's subtree that can push
   its scrollWidth past its clientWidth. At the phone's 33.6px `--step-4` floor
   it is 3.36px — and h018 measured `programs-podcast` needing 355px in a 352px
   box and `programs-startup-world-cup` 354 in 352, on headlines whose last line
   packs to the full measure. Removing it removes the overflow without touching
   Regina's copy, the accent, the type scale or the desktop composition, because
   the declaration was already painting nothing. */
.hero-accent-line { display: block; }
.hero-accent {
  display: inline; color: var(--crimson);
  background: linear-gradient(transparent 80%, var(--gold) 80%, var(--gold) 96%, transparent 96%);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.hero-lede { font-size: var(--step-1); line-height: 1.45; color: var(--ink-2); max-width: 46ch; margin-top: 1.2rem; }

.cta-row { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.6rem; }

/* THREE BUTTONS, ONE FAMILY, DESCENDING WEIGHT. Previously all three carried a
   6px offset shadow and slid 3px on hover — the sticker-peel interaction that
   is neubrutalism's signature gesture, on every call to action on the site.
   The hierarchy now comes from fill: solid crimson, then crimson outline, then
   quiet text. Which is how a reader tells a primary action from a secondary
   one anyway; the shadow was never carrying that information. */
.btn {
  display: inline-block; text-decoration: none; font-weight: 700;
  padding: .8rem 1.4rem; border-radius: var(--r-pill); border: 1px solid transparent;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}
.btn:active { transform: translateY(1px); }
.btn-sm { padding: .55rem 1rem; font-size: .85rem; }
.btn-primary { background: var(--crimson); color: #fff; }
.btn-primary:hover { background: var(--crimson-deep); color: #fff; }
.btn-secondary { background: transparent; color: var(--crimson); border-color: var(--crimson); }
.btn-secondary:hover { background: var(--blush); color: var(--crimson-deep); border-color: var(--crimson-deep); }
/* `ink-2` on paper is 10.36:1; the underline is what marks it as an action. */
.btn-tertiary { background: transparent; color: var(--ink-2); text-decoration: underline; }
.btn-tertiary:hover { color: var(--crimson); }

/* ------------------------------------------------------------------- stats */

.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0; border: 2px solid var(--ink); border-radius: var(--r-lg); overflow: hidden;
  background: var(--paper);
}
.stats-hero { margin: clamp(2rem, 4vw, 3.2rem) 0 0; transform: translateY(28px); }
.hero:has(.stats-hero) { padding-bottom: 28px; }
.stat { padding: 1.2rem 1.3rem; border-right: 2px solid var(--ink); }
.stat:last-child { border-right: 0; }
.stat-fig { font-size: var(--step-3); font-weight: 800; letter-spacing: -.02em; margin: 0; line-height: 1; }
/* Was gold-deep: "20K+" and "5th" changed colour mid-figure, so the eye
   parsed "5" and "th" as two data points. */
.stat-suffix { color: inherit; }
.stat-label { margin: .45rem 0 0; font-size: .82rem; color: var(--ink-3); line-height: 1.35; }
@media (max-width: 720px) {
  .stat { border-right: 0; border-bottom: 2px solid var(--ink); }
  .stat:last-child { border-bottom: 0; }
}

/* ------------------------------------------------------------------- bands */

.band { padding: clamp(2.6rem, 6vw, 4.6rem) 0; }
.band-h {
  font-size: var(--step-2); max-width: 24ch; margin-bottom: .9rem;
  position: relative; padding-bottom: .5rem;
}
.band-h::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 3.2rem; height: .32rem; background: var(--crimson); border-radius: 999px;
}
.band-lede { font-size: var(--step-1); line-height: 1.45; color: var(--ink-2); max-width: 52ch; }
.prose p { max-width: 62ch; color: var(--ink-2); }
.prose p:first-child { color: var(--ink); font-size: var(--step-1); line-height: 1.45; }

.band-audiences { background: var(--paper-2); border-block: 1px solid var(--rule); }
/* 230px fitted four of Regina's FIVE doors per row at 1180 and orphaned
   the fifth on a line of its own. 5x200 + 4x16 gap = 1064, inside the
   1180 wrap, so all five compose as one row and the set reads as a
   choice rather than a list with a straggler. */
.aud-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1.6rem; }
/* The card WAS one `<a>`. It could not be: `.aud-b` carries a citation chip,
   which is itself an `<a>`, and an anchor inside an anchor is invalid — the
   parser runs the adoption agency and closes the outer one. Measured in the
   DOM on 2026-08-12, not read off the source: on `index` every `.aud-go` and
   every `.cite` came out as a direct child of `.aud-grid`, so the grid held
   eight items instead of four and laid them out 2x4. "See the pathway ->"
   painted in the empty column beside its own card, four times, and was not
   part of the link it advertised.
   So the card is a `<div>` and the anchor is the title, stretched over the
   card by `.aud-link::after`. Click target and hover are unchanged; the focus
   ring moves back onto the card with `:has()`, which this sheet already uses. */
.aud {
  display: grid; gap: .35rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: 1.3rem; transition: border-color .12s ease, background-color .12s ease;
  position: relative;
}
.aud:hover { border-color: var(--crimson); background: var(--paper-2); color: var(--ink); }
.aud-link { color: inherit; text-decoration: none; }
.aud-link::after { content: ""; position: absolute; inset: 0; border-radius: var(--r-lg); }
.aud-link:focus-visible { outline: none; }
.aud:has(.aud-link:focus-visible) { outline: 3px solid var(--sea); outline-offset: 3px; border-radius: var(--r-lg); }
/* The chip sits under that stretched overlay, so cite mode would be
   unclickable without lifting it back out. */
.aud .cite { position: relative; z-index: 1; }
.aud-i { font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-3); }
.aud-n { font-size: var(--step-2); font-weight: 800; letter-spacing: -.04em; color: var(--crimson); line-height: 1; }
.aud-b { font-size: .9rem; color: var(--ink-2); }
.aud-go { font-size: .82rem; font-weight: 700; color: var(--crimson); margin-top: .5rem; }

.card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.1rem; margin-top: 1.8rem; }
.card {
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: 1.4rem;
}
/* `ink-2`, not `gold-deep`. gold-deep is 3.93:1 on paper — canon 06 marks it
   "large text only (>=24px)" and this eyebrow sets it at 10.88px, seven times
   across the site. ink-2 on paper is 10.36:1, which clears AA small text
   (4.5:1) with room. Measured, not assumed; the /styleguide violation table is
   generated from this file, so it stops listing this rule by itself. */
.card-eyebrow {
  font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--ink-2); margin-bottom: .5rem;
}
.card-h { font-size: var(--step-1); margin-bottom: .6rem; }
.card-b { color: var(--ink-2); font-size: .95rem; }
.card-go { font-weight: 700; font-size: .88rem; text-decoration: none; }
.card-go:hover { text-decoration: underline; }

.band-stats { background: var(--blush); border-block: 2px solid var(--ink); }

.band-quote .pull, .closer-q {
  font-size: var(--step-2); font-weight: 700; letter-spacing: -.03em;
  border-left: .4rem solid var(--gold); margin: 0 0 1.6rem; padding: .3rem 0 .3rem 1.3rem;
}
.band-closer {
  background: var(--crimson); color: var(--paper); text-align: center;
  border-block: 1px solid var(--rule);
}
.band-closer .closer-q { border-left: 0; padding: 0; font-size: var(--step-3); max-width: 20ch; margin-inline: auto; }
.band-closer .closer-sub { color: #FFE3C9; font-size: var(--step-1); font-weight: 600; }
.band-closer .cta-row { justify-content: center; }
.band-closer .btn-primary { background: var(--paper); color: var(--crimson); }
/* THE INVERSE WAS WRITTEN FOR PRIMARY AND NOT FOR SECONDARY, AND THE BUTTON
   VANISHED. `.btn-secondary` is transparent with crimson text and a crimson
   border; `.band-closer` is the first — and only — crimson ground on the site
   to carry one. Rendered, "Explore Programs" was crimson on crimson: contrast
   1.00:1, a 220px anchor still in the tab order, invisible to everyone and
   detectable without measuring colour only because it shoved the visible
   button 115.7px off the band's centre.
   Measured by iris 2026-08-13. Held by test_site.py — every .btn variant must
   clear 4.5:1 against the ground it is actually painted on, not against paper. */
.band-closer .btn-secondary { color: var(--paper); border-color: var(--paper); }
.band-closer .btn-secondary:hover { background: var(--paper); color: var(--crimson); border-color: var(--paper); }
.band-closer .cite { background: #fff; color: var(--crimson); }

/* --------------------------------------------------------------- pathways */

.path-grid, .track-grid, .region-grid, .who-grid, .tier-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.1rem; margin-top: 1.6rem;
}
.path { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-lg); padding: 1.2rem; }
.path-h { font-size: var(--step-1); color: var(--crimson); margin-bottom: .8rem; }
.path-steps { list-style: none; display: grid; gap: .5rem; }
.path-steps li { display: flex; gap: .6rem; align-items: baseline; font-size: .9rem; color: var(--ink-2); }
.step-n {
  flex: 0 0 auto; width: 1.5rem; height: 1.5rem; border-radius: 50%;
  background: var(--blush); border: 1px solid var(--rule);
  font-size: .72rem; font-weight: 800; display: grid; place-items: center; color: var(--crimson);
}
.steps { list-style: none; display: grid; gap: .9rem; margin-top: 1.4rem; }
.step { display: flex; gap: .9rem; align-items: flex-start; }
.step-h { font-weight: 800; margin: 0; }
.step-b { margin: 0; color: var(--ink-2); font-size: .92rem; }

.feature-in { display: grid; grid-template-columns: 3fr 2fr; gap: clamp(1.4rem, 4vw, 3rem); align-items: center; }
.band-feature { background: var(--paper-2); border-block: 1px solid var(--rule); }
/* The day a dated feature happens. It sits inside .feature-copy, which is the
   first grid child and the one the 720px rule below stacks on top, so the date
   is above the fold of the band on a 390px phone as well as on the desktop.
   No colour: Regina's events deck slide 2 says "Not red and green)", and a
   date painted a status colour is the same mistake one band further down. */
.feature-date { margin: .55rem 0 0; font-size: var(--step-1); font-weight: 800; }

.acc-grid { display: grid; gap: 1rem; margin-top: 1.6rem; }
.acc {
  display: grid; grid-template-columns: 1fr 1fr 2fr; gap: 1rem; align-items: baseline;
  border: 1px solid var(--rule); border-radius: var(--r-lg); padding: 1.1rem 1.2rem; background: var(--paper);
}
.acc-what { font-weight: 800; margin: 0; font-size: var(--step-1); }
.acc-rule { margin: 0; font-weight: 700; font-size: .85rem; }
/* NO STATUS COLOUR ON AN ACCESS RULE. Regina, events deck slide 2, beside a
   photograph of this table: "Not red and green)".
   These four rules were:
       .acc-open   { border-left:.6rem solid var(--sea) }
       .acc-open   .acc-rule { color: var(--sea) }
       .acc-closed { border-left:.6rem solid var(--crimson) }
       .acc-closed .acc-rule { color: var(--crimson) }
   — a green rail for a row whose text contained "Open" and a crimson one for
   every other row. Crimson is this site's disclaimer colour, so "Run by 22
   chapters" was painted the same red as "Not affiliated with or funded by
   Harvard University". The rail is now one neutral hairline weight on every
   row and the access line inherits the body colour; the distinction lives in
   `.acc-label`, which is a word. `render.sec_access_table` no longer computes
   the state at all, so the classes are gone rather than merely uncoloured. */
.acc { border-left: .6rem solid var(--rule); }
.acc-label { display: block; font-size: var(--micro); font-weight: 700;
             letter-spacing: var(--track-caps); text-transform: uppercase;
             color: var(--ink-3); margin-bottom: .3rem; }
.acc-detail { margin: 0; color: var(--ink-2); font-size: .92rem; }
@media (max-width: 760px) { .acc { grid-template-columns: 1fr; gap: .4rem; } }

.track, .region, .who {
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: 1.3rem;
}
.track-h, .region-h, .who-h { font-size: var(--step-1); color: var(--crimson); margin-bottom: .5rem; }
.track-b, .region-b, .who-b { margin: 0; color: var(--ink-2); font-size: .93rem; }
.band-tracks { background: var(--paper-2); border-block: 1px solid var(--rule); }

/* Her slide-6 composition, kept as a composition (h025 T3, 2026-09-07).
   HAE x A Foundery, IS THIS FOR YOU?: four fit blocks 2x2 on the LEFT, and on
   the RIGHT her statement, its sentence, and the progression under them. The
   split is a grid rather than floats so the source order — cards, then the
   aside — is also the reading order when the columns stack.
   No new size, weight or tracking: `--step--1`, `--micro` and `--track-caps`
   are the ramp canon 06 already records, and a new component is exactly where
   a fifty-first off-scale literal gets in. */
.tracks-split {
  display: grid; grid-template-columns: 3fr 2fr;
  gap: clamp(1.4rem, 4vw, 3rem); align-items: start;
}
.tracks-split .track-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tracks-aside { display: grid; align-content: start; gap: .7rem; margin-top: 1.6rem; min-width: 0; }
.aside-eyebrow {
  font-size: var(--micro); font-weight: 700; letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--crimson); margin: 0;
}
.aside-h { font-size: var(--step-1); margin: 0; }
.progression { margin: .3rem 0 0; min-width: 0; }
/* `flex-wrap` and `overflow-wrap` are the phone's whole defence here: four
   uppercase words on one line is 300-odd pixels of unbreakable text, which is
   the 138px-overflow defect of 2026-08-10 in a new band. Wrapped, the steps
   read top-to-bottom in her order. */
.progression-steps {
  list-style: none; display: flex; flex-wrap: wrap; align-items: baseline;
  gap: .3rem .55rem; margin: 0; padding: 0;
}
.progression-step {
  display: flex; align-items: baseline; gap: .55rem; min-width: 0;
  font-size: var(--step--1); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--crimson); overflow-wrap: anywhere;
}
.progression-arrow { color: var(--ink-3); font-weight: 700; }

@media (max-width: 900px) {
  .tracks-split { grid-template-columns: 1fr; }
  .tracks-split .track-grid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
}

.tier { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-lg); padding: 1.3rem; }
.tier-h { font-size: var(--step-1); margin-bottom: .4rem; }
.tier-price { font-size: var(--step-3); font-weight: 800; letter-spacing: -.05em; margin: 0 0 .5rem; line-height: 1; }
.tier-per { font-size: 1rem; font-weight: 700; color: var(--ink-3); letter-spacing: 0; }
.tier-ask { font-size: var(--step-1); color: var(--ink-3); }
.tier-b { color: var(--ink-2); font-size: .92rem; }

.gap-rail { display: grid; gap: 1.2rem; margin-top: 1.6rem; }
.gap-floor { border: 1px solid var(--rule); border-radius: var(--r-lg); padding: 1.2rem; background: var(--paper-2); }
.gap-label { font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase; margin: 0 0 .3rem; }
.gap-price { font-size: var(--step-2); font-weight: 800; margin: 0; }
.gap-hole {
  border: 3px dashed var(--crimson); border-radius: var(--r-lg); padding: 1.4rem;
  background: repeating-linear-gradient(135deg, var(--blush) 0 12px, var(--paper) 12px 24px);
}
.gap-hole-h { font-weight: 800; color: var(--crimson); margin-bottom: .4rem; }
.gap-hole-b { margin: 0; color: var(--ink-2); font-size: .93rem; }

.undescribed { list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: .5rem; margin-top: 1.2rem; }
.undescribed li {
  border: 2px dashed var(--rule); border-radius: var(--r-lg); padding: .7rem .9rem;
  font-weight: 600; color: var(--ink-2); font-size: .9rem; background: var(--paper);
}

.navcmp { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; margin: 1.6rem 0; }
.navcol { border: 2px solid var(--rule); border-radius: var(--r-lg); padding: 1.2rem; background: var(--paper); }
.navcol-built { border-color: var(--crimson); }
.navcol-h { font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-3); margin-bottom: .7rem; }
.navcol-built .navcol-h { color: var(--crimson); }
.navcol ol { padding-left: 1.2rem; }
.navcol li { font-weight: 600; padding: .12rem 0; }
@media (max-width: 720px) { .navcmp, .feature-in, .hero-in { grid-template-columns: 1fr; } }

.contact-mail { font-size: var(--step-2); font-weight: 800; }

/* ------------------------------------------------------------------ photos */

.photo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.2rem; margin-top: 1.6rem; }
.photo { margin: 0; }
/* A band that is in her order and whose content nobody has supplied yet —
   slide 6 of the chapters deck, HUMAN PROOF, whose quote exists in no document
   this project holds. Muted and italic: the register `.dir-unknown` and
   `.faq-outstanding` already use on this same page for the field that is not
   filled, so the line is visible, quiet, and never mistakable for a member's
   words. */
.photo-outstanding { margin-top: 1.1rem; max-width: 44rem; color: var(--ink-3); font-style: italic; }
/* ABSENCE IS NOT AN ALARM. This frame was `3px dashed var(--crimson)` on a
   two-stop gradient, and it is the most-repeated large object on the site —
   four on `index` alone, more on six other pages.
   Dashed crimson is this stylesheet's OWN vocabulary for missing-or-closed:
   `.gap-hole` is the "named in no source document" panel and `.acc-closed` is
   the shut door. So the band titled "The people, not the programs" — the
   section carrying the brief's People Before Programs principle — rendered as
   three error states in a row, and at 390 the first scroll after the CTAs was
   ~450px of empty gradient inside a red dashed box.
   The photography gap is real and stays visible. What changes is that a slot
   waiting for a commissioned photograph now reads as a quiet reserved space
   rather than as something that has gone wrong. Bright · Personal · Welcoming
   are three of the seven words the brief asks for; an alarm is none of them. */
.photo-frame {
  aspect-ratio: 4 / 3; border-radius: var(--r-lg); border: 1px solid var(--rule);
  background: var(--paper-2);
  display: grid; place-items: center; padding: 1rem;
}
.photo-hero .photo-frame { aspect-ratio: 4 / 5; }
/* The filled slot. Same geometry as the reserved frame above so a page does
   not reflow between "asset pending" and "asset landed"; cover-fit so any
   generated aspect fills it edge to edge. */
.photo-img {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--r-lg); border: 1px solid var(--rule);
}
.photo-hero .photo-img { aspect-ratio: 4 / 5; }
.photo-tag {
  font-size: var(--micro); font-weight: 700; letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--ink-3); background: transparent; border: 1px solid var(--rule);
  border-radius: 999px; padding: .4rem .9rem; text-align: center;
}
.photo figcaption { padding-top: .8rem; }
.photo-subject { font-size: .9rem; font-weight: 600; color: var(--ink); margin-bottom: .5rem; }
.photo-avoid { display: none; background: var(--paper-2); border-left: .3rem solid var(--gold); padding: .6rem .8rem; border-radius: 0 var(--r-sm) var(--r-sm) 0; }
/* Same rule, the other violator: 11.2px of gold-deep on `paper-2`, thirteen
   times. It reads "The brief prohibits, by name:", and crimson is already this
   stylesheet's colour for a prohibition (`.gap-hole-h`, `.acc-closed
   .acc-rule`, `.disclaimer`), so the fix moves it onto a token that is both
   legal and already carrying that meaning. crimson on paper-2 is 6.89:1. */
.photo-avoid-h { font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--crimson); margin: 0 0 .3rem; }
.photo-avoid ul { padding-left: 1.1rem; }
.photo-avoid li { font-size: .82rem; color: var(--ink-2); }
/* D5. The last working note still printing to visitors: "Subject rules from
   the creative brief §8. HAE has no cleared photography of people yet…" —
   under all four frames on `index`, three side by side in one viewport. Same
   defect class this sheet already fixed for `.photo-avoid` and `.src-path`,
   one selector short of done. `.photo-subject` stays: a written brief for a
   photograph is honest content. */
.photo-cite { display: none; font-size: .76rem; color: var(--ink-3); margin: .6rem 0 0; }
body.cites .photo-cite { display: block; }

/* ---------------------------------------------------------------- sources */

.cite {
  display: none; margin-left: .4rem; vertical-align: .35em;
  font-size: .6rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  background: var(--sea); color: #fff; border-radius: 999px; padding: .12rem .5rem;
  text-decoration: none; white-space: nowrap;
}
body.cites .cite { display: inline-block; }
body.cites .claim { background: rgba(11, 110, 99, .07); box-shadow: 0 0 0 .18rem rgba(11, 110, 99, .07); border-radius: 3px; }

/* The reviewer's layer renders in the reviewer's state — nothing is removed.
 *
 * `body.cites` already means "show me the layer a reviewer reads": the `.cite`
 * chips above are hidden by default and appear when the header's Sources button
 * is pressed. Two things carrying exactly that material sat OUTSIDE the switch
 * and printed to every visitor:
 *
 *   1. `.src-path` — a wall of `solace/_origin/extracted/...` monospace repo
 *      paths, as the last content in `main`, shown to a cold founder. An
 *      internal filesystem location is not a document name.
 *   2. `.photo-avoid` — the customer's INTERNAL photography prohibition list
 *      ("The brief prohibits, by name: staged stock photography"), 13 panels on
 *      7 pages, two of them above the fold at 1440. This is the same defect
 *      `render.note_card` already fixed for notes: working notes, printed to
 *      the visitor. `content.photo()` sources them to "Darwin's constraint 4",
 *      not to anything the customer asked for.
 *
 * THE AUDIENCE LINE MOVED TWICE AND BOTH CORRECTIONS ARE RECORDED HERE,
 * because each one was a smaller version of the same mistake.
 *
 * First cut hid the whole `.sources` section. Wrong: `.sources-lede` is the
 * page's trust signal — *"Each statement of fact above is quoted from one of
 * these customer documents… Nothing on this page asserts anything about HAE
 * that is not in this list."* — and the only visible thing telling a reader an
 * evidence layer exists. Hiding it left `$99/yr` and `$0 equity taken — ever`
 * asserting themselves with no visible pointer to provenance.
 *
 * Second cut kept the lede and hid `.src-list`. Also wrong, and worse in one
 * specific way: *"one of these"* and *"not in this list"* then referred to
 * nothing. A wall of repo paths is ugly; a sentence pointing at an invisible
 * list is incoherent. Measured on the rendered page, not reasoned about.
 *
 * So the line is drawn INSIDE the row. `render.sources_block` builds each
 * `<li>` as a plain-English document name — "Creative brief", "HAE prototype
 * homepage", "Brief §11 homepage comp" — plus a `<code class="src-path">`
 * holding the repo path. The names are founder material and resolve the
 * lede's referent; the path is an internal filesystem location and is the part
 * that was genuinely wrong to show a visitor.
 *
 *   default    heading · lede · list · document names   VISIBLE
 *              `.src-path`, `.photo-avoid`              hidden
 *   body.cites everything, byte-identical to pre-T-1
 *
 * The hide is scoped `.src-list .src-path` rather than `.src-path`, and that
 * is not tidiness: `styleguide.html` reuses `.src-path` for 75 token names
 * (`crimson`, `paper`, `#F5B324`). A bare `.src-path { display: none }` would
 * blank the token reference and survive only because that page happens to
 * author `<body class="cites">` — a page rendering correctly by coincidence.
 *
 * `display: none`, not deletion. `site/tests/test_site.py` requires the
 * `.sources` block in the markup of every page, `site/assets/site.js` reads
 * `.src-list li` to label search results, and `querySelectorAll` sees a hidden
 * element — all three keep working. The one `#sources` referrer on the site is
 * the `.cite` chip; the section it points at is now always on screen, so that
 * anchor resolves in both states rather than only in one.
 *
 * What does NOT move: `.photo-frame`, `.photo-tag` and `.photo-subject` — the
 * dashed PHOTOGRAPH TO BE COMMISSIONED reservation and its subject brief are
 * the page's own content and stay visible in both states.
 */
body.cites .photo-avoid { display: block; }
.src-list .src-path { display: none; }
body.cites .src-list .src-path { display: inline; }

.sources { background: var(--paper-2); border-top: 1px solid var(--rule); padding: clamp(2rem, 4vw, 3rem) 0; }
.sources h2 { font-size: var(--step-1); margin-bottom: .7rem; }
.sources-lede { max-width: 68ch; color: var(--ink-2); font-size: .95rem; }
.src-list { list-style: none; display: grid; gap: .4rem; margin-top: 1rem; }
.src-list li { display: flex; flex-wrap: wrap; gap: .6rem; align-items: baseline; }
.src-label { font-weight: 800; font-size: .88rem; min-width: 15rem; }
.src-path { font-size: .78rem; color: var(--ink-3); background: var(--paper); border: 1px solid var(--rule); border-radius: 6px; padding: .1rem .4rem; }

/* ----------------------------------------------------------------- search */

.search-label { display: block; font-weight: 800; margin-bottom: .5rem; }
.search-input {
  width: 100%; font: 600 var(--step-1) var(--sans); padding: .9rem 1.1rem;
  border: 1px solid var(--rule); border-radius: 999px; background: var(--paper); color: var(--ink);
}
.search-count { margin-top: .8rem; font-size: .85rem; color: var(--ink-3); font-weight: 700; }
.search-results { display: grid; gap: .8rem; margin-top: .6rem; }
.result { border: 1px solid var(--rule); border-radius: var(--r-lg); padding: 1rem 1.2rem; background: var(--paper); }
.result-kicker { font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--crimson); margin: 0 0 .3rem; }
.result-text { margin: 0 0 .5rem; color: var(--ink-2); }
.result mark { background: var(--blush); color: var(--ink); border-radius: 3px; padding: 0 .15em; }
.result-src { font-size: .76rem; color: var(--ink-3); margin: 0; }

/* ------------------------------------------------- the Academy library stages
 *
 * Added 2026-09-07 (h024). These four words were `.eyebrow` paragraphs until
 * the courses gained the stage membership her 2026 Courses template supplies;
 * they are controls now, so they look like controls. Three things are load
 * bearing rather than decorative:
 *
 *   - the size is `--step--1`, not `--micro`. `--micro` is a caption token and
 *     paints at 11.5px, which `test_qa_sweep.py` already documents as the size
 *     that reads as 13 in review. A control a reader has to hit is not a
 *     caption. (That check reads `.btn` and `.card-go` and would not have
 *     caught this one, which is exactly why the size is chosen here and not
 *     left to it.)
 *   - `:focus-visible` is a visible ring. The whole keyboard claim in the run's
 *     gates rests on a reader being able to see which chip they are on.
 *   - `aria-pressed="true"` is what paints the selection, so the state a
 *     screen reader announces and the state an eye sees are the same attribute
 *     and cannot drift apart.
 */

.stage-row { margin-bottom: .9rem; }
.stage-chip {
  font: 800 var(--step--1) var(--sans);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--crimson); background: var(--paper);
  border: 1px solid var(--rule); border-radius: var(--r-pill);
  padding: .45rem 1rem; cursor: pointer;
}
.stage-chip:hover { border-color: var(--crimson); }
.stage-chip:focus-visible { outline: 3px solid var(--gold-deep); outline-offset: 2px; }
.stage-chip[aria-pressed="true"] {
  background: var(--crimson); border-color: var(--crimson); color: var(--paper);
}
/* Ours, not hers, and it reads as the way out rather than as a fifth stage. */
.stage-chip-all { color: var(--ink-2); text-transform: none; letter-spacing: 0; }
.stage-chip-all[aria-pressed="true"] {
  background: var(--paper-2); border-color: var(--ink-2); color: var(--ink);
}
/* Built by `site.js`, never shipped in the markup: with scripting off no card
   is ever hidden, so a count on disk would be a sentence that can only lie. */
.library-status { margin: 0 0 1.1rem; font-weight: 700; color: var(--ink-2); }

/* ----------------------------------------------------------- three questions */

/* The three-question band is the brief's acceptance test, printed on every page.
 * It has to stand apart from the page it judges without going dark — the brief
 * prohibits dark by name — so it separates itself with a stone band, rules and
 * gold labels instead of an inverted surface. It was a peach-over-cream
 * gradient until 2026-09-14: the "creamsicle coloring at the bottom" Regina
 * named. */
.three-q {
  background: var(--paper-2);
  border-block: 1px solid var(--rule);
  padding: clamp(2.4rem, 5vw, 3.6rem) 0;
}
/* The band's heading is `.sr-only`, so it sets no font-size of its own and
   inherited the UA's `h2 { font-size: 1.5em }` — 26.16px at 1440, which is on
   no step of the ramp (14.24 / 17.44 / 22.72 / 32 / 48 / 68.64). It paints
   nothing: measured at 1x1 and clipped on all twelve pages, so this is not a
   visible defect and is not being reported as one. It is put on `--step-1`
   anyway because "every h2 on this site is on the ramp" is a sentence worth
   being able to say, and the alternative is one h2 that only a reader using
   a screen-reader's heading list ever meets, at a size nobody chose. */
.three-q h2 { font-size: var(--step-1); }
.q-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.6rem; }
.q { border-top: 2px solid var(--crimson); padding-top: 1rem; }
.q-label {
  font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--crimson); margin-bottom: .6rem;
}
.q-body, .q-list li { color: var(--ink-2); font-size: .96rem; }
.q-list { list-style: none; display: grid; gap: .5rem; }
.q-list li { padding-left: 1.2rem; position: relative; }
.q-list li::before { content: "→"; position: absolute; left: 0; color: var(--gold-deep); font-weight: 800; }
.q-why { margin-top: .8rem; font-size: .88rem; color: var(--ink-3); }

/* ----------------------------------------------------------------- footer */

.site-footer { background: var(--paper-2); border-top: 1px solid var(--rule); padding: clamp(2.4rem, 5vw, 3.6rem) 0 1.6rem; }
/* 2026-09-14: once the three-question band became flat stone it was the same
   colour as the footer under it, two bands reading as one. The footer goes
   white so the band keeps standing apart, as its own rule above says it must. */
.site-footer { background: var(--paper); }
/* FIVE CHILDREN, FOUR TRACKS. `.fgrid` holds `.fbrand` plus one `.fcol` per
   entry in `content.FOOTER_COLUMNS`, and that list became HER FOUR columns
   (canon 12) while this rule still declared the three the old footer had. Grid
   does not shrink to fit: the fifth child took an implicit second row, so STAY
   IN THE LOOP — the newsletter capture — rendered underneath the wordmark
   instead of beside ABOUT. Her render has the brand and four columns on one
   line. `test_footer.py` now derives the track count from `FOOTER_COLUMNS`, so
   a fifth column added to the data goes red here rather than silently
   wrapping. */
.fgrid { display: grid; grid-template-columns: 1.4fr repeat(4, 1fr); gap: 1.8rem; }
.fbrand .brand-mark { font-size: 1.6rem; }
.fbrand .brand-logo-frame { width: 210px; height: 40px; }
.fnote { display: block; font-size: .86rem; color: var(--ink-2); margin: .8rem 0 1rem; max-width: 34ch; }
.fcol h3 { font-size: var(--micro); font-weight: 800; letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-3); margin-bottom: .7rem; }
.fcol ul { list-style: none; display: grid; gap: .35rem; }
.fcol a { font-size: .9rem; color: var(--ink-2); text-decoration: none; font-weight: 600; }
.fcol a:hover { color: var(--crimson); text-decoration: underline; }
.legal { border-top: 2px solid var(--rule); margin-top: 2rem; padding-top: 1.2rem; }
.legal p { margin: 0; font-size: .84rem; color: var(--ink-3); }
.disclaimer { color: var(--crimson); font-weight: 800; }
@media (max-width: 860px) { .fgrid { grid-template-columns: 1fr 1fr; } }

/* The uppercase kicker band — `--micro` + `--track-caps`, set on each rule
   above rather than overridden from here. Before this there were 13 sizes
   inside a 0.2rem band and four trackings doing one job: a difference nobody
   can see, multiplied across nine selectors. Overriding them from a later
   block would have left every dead literal in the file, and the drift test
   counts what is in the file. It was right to fail. */

/* 8 · one rule weight at every seam. Two bordered bands adjoining painted a
   4px rule where every other rule on the site is 1px — which reads as a
   rendering error rather than a heavier division. */
.band-closer + .three-q,
.three-q + .sources { border-top: 0; }

/* ── The navigation Regina specified — canon 06 "The navigation system" ─────
   Every value here is in that canon section, measured off regina-spec-1.png.
   If this block and that table disagree, the canon is right. */

.masthead-in{min-height:98px}
.brand-sub{line-height:1.15;font-weight:700}

.primary>ul{display:flex;gap:34px;align-items:center;margin:0;padding:0;list-style:none}
.primary li{position:relative}

.navtop{font:700 var(--step-0)/1.2 var(--sans);color:var(--ink);background:none;border:0;
        padding:0;cursor:pointer;display:inline-flex;
        align-items:center;gap:7px;text-decoration:none}
.navtop:hover,.navtop[aria-expanded="true"],.navtop[aria-current="page"]{color:var(--crimson)}

.caret{width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;
       border-top:5px solid currentColor;display:inline-block}

/* The panel floats on a 1px rule and NO shadow. P5 (not generic startup)
   forbids the elevation, and the border is the separation cue that replaces
   it — canon 06's elevation ruling, carried forward deliberately over
   fidelity to her screenshot, which appears to carry a faint one. */
.navpanel{position:absolute;top:calc(100% + 14px);left:-30px;z-index:60;
          display:none;gap:90px;background:var(--paper);
          border:1px solid var(--rule);box-shadow:none;padding:26px 30px}
.has-panel:hover .navpanel,
.has-panel:focus-within .navpanel{display:flex}
/* Every panel after the first opens from its item's right edge, so an open
   panel stays on a 1085px screen: in the build container's fonts "Get
   Involved" ran 45px past it (Cloud Build 8ecbcde6, 2026-09-14). */
.has-panel:not(:first-child) .navpanel{left:auto;right:-30px}
/* Menu intent (site.js §5): a panel the pointer just left stays open for a
   moment, and while it does, a neighbour's hover does not open another over
   it. Keyboard focus is never suppressed. */
.has-panel.is-held .navpanel{display:flex}
.primary.holding .has-panel:not(.is-held):not(:focus-within) .navpanel{display:none}

/* THE 14px THE POINTER HAD TO CROSS AND COULD NOT. The panel opens at
   `top: calc(100% + 14px)`, so between the bottom of the menu item and the
   top of the panel there is a 14px band belonging to NEITHER. Moving the
   cursor from the button down toward the panel left `.has-panel:hover`,
   the panel returned to `display:none`, and the links to the individual
   pages could not be reached at all. Reported from outside 2026-09-10:
   "Not able to view the individual pages as the menus disappears".
   This bridges the band with a transparent extension of the item's own
   hover area. It changes no pixel: the panel still floats 14px clear on
   its 1px rule with no shadow, which is canon 06's elevation ruling. */
.has-panel::after{content:"";position:absolute;left:0;right:0;top:100%;
                  height:14px}
/* The item's bridge above is only as wide as its button; this band gives the
   open panel its full width over the 14px gap. A pointer leaving diagonally
   through the gap BESIDE the button is handled by site.js §5 (menu intent),
   which holds the panel for a moment. */
.navpanel::before{content:"";position:absolute;left:-1px;right:-1px;bottom:100%;
                  height:16px}

/* 210px: 'Strategic Advisory Network' and 'Startup World Cup' both wrapped
   at 170 and her render has neither on two lines. */
.megacol{min-width:210px}
.megacol-h{font-size:var(--micro);font-weight:700;letter-spacing:var(--track-caps);text-transform:uppercase;
          color:var(--ink-40,#8a8a8a);margin:0 0 16px}
.megacol ul{list-style:none;margin:0;padding:0}
/* Her rows sit close. 22px was the measured gap BETWEEN BASELINES in a
   1365-wide print; adding it as a margin on top of the theme's inherited
   li padding doubled it. This is the gap, not the gap plus the padding. */
.megacol li{padding:0}
.megacol li+li{margin-top:11px}
.megacol a{font-size:var(--step-0);font-weight:400;line-height:1.35;color:var(--ink);text-decoration:none}
.megacol a:hover{color:var(--crimson);text-decoration:underline}
/* "The Academy course should be a subnav to Academy page" (Regina, 11 Sep).
   The child list rendered at the same size and edge as its parent, so it
   read as a sibling. Indented on a hairline, one step smaller. */
.megacol ul ul{margin:9px 0 0 9px;padding-left:12px;border-left:2px solid var(--rule)}
.megacol ul ul a{font-size:var(--step--1);color:var(--ink-2)}

/* She named it; nobody has written it. Visible, muted, not a link, and it
   says so on hover — canon 11's open question rendered rather than hidden. */
.navlink-unwritten{font-size:var(--step-0);line-height:1.35;color:var(--ink-40,#8a8a8a);
                   cursor:not-allowed;border-bottom:1px dotted var(--ink-40,#8a8a8a)}

.btn-outline,.btn-filled{font-size:var(--step--1);font-weight:700;text-transform:uppercase;
                         padding:14px 26px;border-radius:3px;text-decoration:none;
                         display:inline-block;letter-spacing:var(--track-caps)}
.btn-outline{border:1px solid var(--ink);color:var(--ink);background:none}
.btn-outline:hover{background:var(--ink);color:var(--paper)}
.btn-filled{border:1px solid var(--crimson);background:var(--crimson);color:var(--paper)}
.btn-filled:hover{background:#8c1727;border-color:#8c1727}

/* No narrow screen was sent (canon 06, docked). A two-column mega panel has
   to become something under ~900px, so it becomes the honest thing: the panel
   stops floating and the columns stack in the mobile drawer. */
@media (max-width:900px){
  .primary{display:none}
  .has-panel::after{content:none}
  .navpanel::before{content:none}
  .navpanel{position:static;display:flex;flex-direction:column;gap:22px;
            border:0;padding:14px 0 0}
  .mobile-nav .primary{display:block}
}

/* ── Join page components — canon 06 "The Join page components" ───────────── */

.tier-flag{font-size:var(--micro);font-weight:700;letter-spacing:var(--track-caps);
           text-transform:uppercase;color:var(--crimson);margin:0 0 .6rem}
.tier-featured{border-color:var(--crimson)}

/* P6: a price and its period are never the same size. The period is small and
   muted so the number reads at a glance instead of being parsed. */
.tier-per{font-size:var(--step--1);font-weight:400;color:var(--ink-40,#8a8a8a);
          letter-spacing:0;margin-left:.25rem}

.tier-list{list-style:none;margin:1rem 0 1.4rem;padding:0}
.tier-list li{position:relative;padding-left:1.5rem;line-height:1.35;margin-top:.7rem}
.tier-list li::before{content:"\2713";position:absolute;left:0;color:var(--crimson);font-weight:700}

.faq-list{border-top:1px solid var(--rule);max-width:52rem}
.faq-item{border-bottom:1px solid var(--rule)}
.faq-q{font-weight:700;padding:1.15rem 2rem 1.15rem 0;cursor:pointer;list-style:none;position:relative}
.faq-q::-webkit-details-marker{display:none}
.faq-q::after{content:"+";position:absolute;right:0;color:var(--ink-40,#8a8a8a);font-weight:400}
.faq-item[open] .faq-q::after{content:"\2212"}
.faq-a{padding:0 0 1.3rem;max-width:44rem}
.faq-outstanding{color:var(--ink-40,#8a8a8a);font-style:italic}

/* The chapter directory — slide 3 and slide 4 of her chapters deck, which are
   one object on a page: twenty-two names that open in place, and no individual
   chapter pages ("No separate chapter pages", her words, twice).

   COLUMNS AND NOT A GRID. Her slide sets the names in three columns read down
   rather than across, and CSS multicolumn is the only layout that gives that
   back without reordering the DOM: a three-track grid would put Africa, Denver
   and Oceania on one row and hand a keyboard the same order. `break-inside`
   keeps an open chapter whole rather than splitting its leadership across a
   column edge. The phone gets one column, so the reading order is hers there
   too.

   The `+` is drawn here rather than written into the markup, exactly as
   `.faq-q::after` draws the FAQ's, so the affordance she marks beside every
   name is visible to a reader and is not part of the cited text a checker
   reads back against her file. `<details>` brings its own keyboard behaviour
   and the sheet's global `:focus-visible` ring; nothing here needs script. */
.dir-list{margin-top:1.6rem;border-top:1px solid var(--rule)}
.dir-item{break-inside:avoid;border-bottom:1px solid var(--rule);background:#FFFFFF}
.dir-q{font-weight:700;padding:.85rem 2rem .85rem 0;cursor:pointer;list-style:none;position:relative}
.dir-q::-webkit-details-marker{display:none}
.dir-q::after{content:"+";position:absolute;right:0;color:var(--ink-3);font-weight:400}
.dir-item[open] .dir-q::after{content:"\2212"}
.dir-a{padding:0 0 1.1rem}
.dir-field{margin-top:.75rem}
.dir-field-h{font-size:var(--micro);font-weight:700;letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--ink-3)}
.dir-b{margin-top:.2rem}
.dir-people li{margin-top:.4rem}
.dir-person{display:block;font-weight:700}
.dir-role{display:block;color:var(--ink-3)}
.dir-act{margin-top:.3rem}
/* A field nobody has supplied. Muted and italic, the register
   `.faq-outstanding` already uses for the answer that is not written yet —
   visible, quiet, and never mistakable for content. */
.dir-unknown{margin-top:.2rem;color:var(--ink-3);font-style:italic}
@media (min-width: 900px){
  .dir-list{column-count:3;column-gap:2.4rem}
}

/* Her bulleted lists inside a prose band — WHAT HAPPENS LOCALLY (slide 2) and
   the four formation steps (slide 7). A square marker, not a disc: this sheet
   spends its round shapes on nothing. */
.prose-list{margin-top:1.1rem;max-width:44rem}
.prose-list li{position:relative;padding-left:1.2rem;margin-top:.55rem}
.prose-list li::before{content:"";position:absolute;left:0;top:.6em;width:.4rem;height:.4rem;background:var(--crimson)}
.prose-foot{margin-top:1.2rem}

/* The utility bar — canon 06 "The Join page components". Tokens only. */
.utilbar{border-bottom:1px solid var(--rule);background:var(--paper)}
.utilbar-in{display:flex;justify-content:flex-end;gap:1.6rem;padding:.5rem 0}
.utilbar a{font-size:var(--micro);color:var(--ink-3);text-decoration:none}
.utilbar a:hover{color:var(--crimson);text-decoration:underline}

/* Her render has the logo, the five nav items and the two buttons on ONE row.
   `.masthead-in` wraps on purpose — without it the row held a 528px floor and
   pushed every page 138px wider than a 390px phone — so the wrap stays for
   narrow screens and is switched off only where there is room for it.
   Caught by a 1440 screenshot, not by a test: the buttons had dropped to a
   second row and every assertion still passed. */
@media (min-width:1100px){
  .masthead-in{flex-wrap:nowrap}
  .primary{flex:0 1 auto;min-width:0}
  .primary>ul{gap:clamp(18px,2.2vw,34px);flex-wrap:nowrap}
  .utility{flex:0 0 auto}
}

/* Her footer's social row — three text marks, not icon files. She shows
   "in · X · IG" and a wordmark needs no asset, no licence and no alt text. */
.fsocial{display:flex;gap:1rem;margin:.9rem 0 1.1rem}
.fsocial a{font-size:var(--micro);font-weight:700;letter-spacing:var(--track-caps);
           color:var(--ink-3);text-decoration:none;text-transform:uppercase}
.fsocial a:hover{color:var(--crimson)}

/* Nothing in the masthead may break mid-word. The 1100px nowrap rule above
   removed the row wrap and pushed the squeeze into the words themselves —
   the wordmark rendered "ENTREPRENEUR / S" and three nav items sat on two
   lines each. Her render has every one of them on a single line.
   The brand gets its natural width; the nav items refuse to break; the gap
   is what gives when the row is tight. */
@media (min-width:1100px){
  .brand{flex:0 0 auto}
  .brand-sub{white-space:nowrap}
  .navtop{white-space:nowrap}
  .primary>ul{gap:clamp(14px,1.8vw,34px)}
}

/* The row is over-full at 1440 and nowrap turned wrapping into COLLISION —
   the nav ran under the wordmark and under LOG IN. Her render fits because
   it carries no Sources button; ours does, and that is a reviewer affordance
   we keep. So the nav takes the smaller step here and the gaps tighten.
   Verified by screenshot, not by querying the DOM: three checks of this
   masthead have now passed while the rendered page was wrong. */
@media (min-width:1100px){
  .navtop{font-size:var(--step--1)}
  .primary{margin-inline:auto}
  .primary>ul{gap:clamp(12px,1.4vw,22px)}
  .utility{gap:.4rem}
  .cite-toggle{font-size:var(--micro)}
}

/* Her programme-card meta line — "10 weeks · Equity-free · Open globally". */
.card-meta{font-size:var(--micro);color:var(--ink-3);margin:.6rem 0 .9rem}

/* h032, 2026-09-09 — the session date on an Academy short-course card.
   Pages 2-3 of HAE Academy Courses _ Harvard Alumni Entrepreneurs.pdf put it top-RIGHT, level with the
   stage badge, so the eyebrow becomes a row and the date is its second child.
   Deliberately NOT .card-meta: that one sits under the body and carries the
   flagship availability line ("Starts October 14"), and a bare date there
   would read as availability. The type is --micro on --ink-3, the pair
   .card-meta already ships, so canon 06's frozen ramp gains no literal and no
   eleventh tracking value. The row only exists on cards that pass a `date`;
   every other card emits the bare <p class="card-eyebrow"> it always did. */
/* `wrap`, for the reason .progression-steps wraps: two uppercase runs on one
   unbreakable line inside a 260px card is the 138px phone overflow of
   2026-08-10 in a new component. */
.card-eyebrow-row{display:flex;flex-wrap:wrap;align-items:baseline;
                  justify-content:space-between;gap:.75rem;margin-bottom:.5rem}
.card-eyebrow-row .card-eyebrow{margin-bottom:0}
.card-date{font-size:var(--micro);color:var(--ink-3);white-space:nowrap;flex:0 0 auto}

/* Her events index — a date block left, the event right. The date is a block
   because a reader scans dates first and titles second. From regina-events. */
.evt-list{display:flex;flex-direction:column;gap:0}
.evt{display:flex;gap:1.8rem;padding:1.6rem 0;border-bottom:1px solid var(--rule)}
.evt-date{flex:0 0 5.5rem;text-align:center;border:1px solid var(--rule);
          padding:.7rem .4rem;align-self:flex-start}
.evt-mon{display:block;font-size:var(--micro);font-weight:700;
         letter-spacing:var(--track-caps);text-transform:uppercase;color:var(--crimson)}
.evt-day{display:block;font-size:var(--step-2);font-weight:700;line-height:1.1}
.evt-yr{display:block;font-size:var(--micro);color:var(--ink-3)}
.evt-tags{display:flex;gap:.9rem;margin:0 0 .4rem;font-size:var(--micro);
          letter-spacing:var(--track-caps);text-transform:uppercase}
.evt-kind{font-weight:700;color:var(--crimson)}
.evt-where{color:var(--ink-3)}
.evt-h{margin:0 0 .35rem}
.evt-b{margin:0 0 .4rem;max-width:52ch}
.evt-time{font-size:var(--micro);color:var(--ink-3);margin:0}
@media (max-width:640px){ .evt{flex-direction:column;gap:.8rem} }

/* ═══ HER VISUAL SYSTEM — canon 06 "Her visual system", 2026-08-18 ═══
   The site had her information architecture and her content sitting on OUR
   visual system. Everything below moves the last of it. Each rule cites the
   canon line it implements; if they disagree, the canon is right. */

/* The ground is white. Not --paper, not --paper-2. */
body, .band, .band-cards, .band-stats, .band-events, .band-faq,
.band-tiers, .masthead { background: #FFFFFF; }

/* The utility bar is INVERTED and carries the tagline. */
.utilbar { background: var(--ink); border-bottom: 0; }
.utilbar-in { justify-content: space-between; padding: .55rem 0; }
.utilbar a { color: #FFFFFF; opacity: .82; }
.utilbar a:hover { color: #FFFFFF; opacity: 1; }
.utilbar-tag { font-size: var(--micro); font-weight: 700;
               letter-spacing: var(--track-caps); text-transform: uppercase;
               color: #FFFFFF; }
.utilbar-links { display: flex; gap: 1.6rem; }

/* P7 — the headline is ONE colour. Crimson marks the word HAE, nothing else. */
.hero-h, .hero-h * { color: var(--ink); }
.hero-h .accent { color: var(--ink); }
.hero-h::after, .hero-h .rule, .hero-accent-rule { display: none !important; }
.band-h .hae-mark { color: var(--crimson); }

/* Buttons are rectangles, uppercase, tight. */
.btn, .btn-primary, .btn-secondary, .btn-sm, .btn-outline, .btn-filled {
  border-radius: 2px;
  text-transform: uppercase;
  font-size: var(--micro);
  letter-spacing: var(--track-caps);
  padding: 12px 22px;
}
.btn-primary { background: var(--crimson); color: #FFFFFF; border: 1px solid var(--crimson); }
.btn-secondary { background: #FFFFFF; color: var(--ink); border: 1px solid var(--ink); }

/* The logo has a mark. */
.brand { display: flex; align-items: center; gap: .8rem; }
.brand-mark { display: inline-flex; align-items: center; justify-content: center;
              width: 44px; height: 44px; border-radius: 50%;
              background: var(--crimson); color: #FFFFFF;
              font-weight: 700; font-size: .82rem;
              flex: 0 0 44px; }
.brand-sub { font-size: .92rem; font-weight: 700; line-height: 1.15;
             letter-spacing: 0; text-transform: none; color: var(--ink);
             max-width: 8.5rem; }

/* The stat band is dividers, not a box. */
.stats, .band-stats .stats {
  border: 0; border-radius: 0; background: #FFFFFF;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.stats .stat { border: 0; border-left: 1px solid var(--rule);
               padding: 2rem 1.4rem; background: transparent; }
.stats .stat:first-child { border-left: 0; }
.stat-fig { font-size: var(--step-3); font-weight: 700; color: var(--ink); }
.stat-label { font-size: var(--micro); color: var(--ink-3); }

/* The Sources control stays — it is how a reviewer sees provenance — but it is
   not part of her design and stops competing with JOIN HAE. */
.cite-toggle { border-radius: 2px; font-size: var(--micro); opacity: .55;
               border: 1px solid var(--rule); background: transparent; }
.cite-toggle:hover { opacity: 1; }

/* Three left, all measured against her page-1 render. */

/* 1 · The hero ground is WHITE. Her page has no tint anywhere; the warmth
      comes from photography and the one dark bar. */
.hero { background: #FFFFFF; }

/* 2 · The gold accent underline is retired with the split headline. It left
      an orphan swatch behind when the accent string went empty — an empty
      element still painting its own decoration. */
.hero-accent, .hero-accent-line { background: none; display: inline; }
.hero-accent:empty, .hero-accent-line:empty { display: none; }

/* 3 · Crimson marks the word HAE, not a rule under a heading. Hers writes
      "Neither does HAE." with HAE in crimson and no underline anywhere. */
.band-h::after, .band-h .rule { display: none; }
.band-h { border-bottom: 0; }

/* Her full-bleed photo strip — three landscapes edge to edge between the hero
   and the stat band (HOMEPAGE-v2 page 2). No wrap, no caption, no radius.
   This is where her design puts photography: AFTER the text lands, which is
   why her hero is empty and why ours should not have had a picture in it. */
.band-strip { display: grid; grid-template-columns: repeat(3, 1fr);
              gap: 2px; width: 100%; }
.strip-img { width: 100%; height: clamp(140px, 15vw, 210px);
             object-fit: cover; display: block; }
@media (max-width: 640px){ .band-strip { grid-template-columns: 1fr 1fr; }
                           .band-strip img:nth-child(3){ display: none } }

/* A <button> does not inherit the page font — the newsletter Subscribe control
   was painting in Arial while every other button used the site stack. Caught
   by a computed-style sweep, invisible in review because Arial and the stack
   are both sans. */
button, input, select, textarea { font: inherit; }

/* Her membership band is LEFT-aligned two-column text on white (HOMEPAGE-v2
   page 6). Ours was a centred, full-crimson band — a second left edge at
   340px against the site's 130px, and the only place crimson floods a whole
   section. Both are ours, neither is hers. */
.band-closer { background: #FFFFFF; color: var(--ink); text-align: left;
               border-block: 1px solid var(--rule); }
.band-closer .closer-q { max-width: 22ch; margin-inline: 0;
                         font-size: var(--step-3); color: var(--ink); }
.band-closer .closer-sub { color: var(--ink-2); }
.band-closer .cta-row { justify-content: flex-start; }
.band-closer .btn-primary { background: var(--crimson); color: #FFFFFF; }
/* The band turned white above and its secondary button kept the paper-on-
   crimson inverse from the old crimson band: paper text on a white ground,
   1.03:1, twelve buttons on nine pages. Found 2026-09-14 by reading every
   button's colour against the ground it is painted on. Held by
   tests/test_button_ground_contrast.py. */
.band-closer .btn-secondary { color: var(--crimson); border-color: var(--crimson); }
.band-closer .btn-secondary:hover { background: var(--blush); color: var(--crimson-deep); border-color: var(--crimson-deep); }
.band-newsletter, .band-newsletter .wrap { text-align: left; }

/* `.wrap-narrow` was 760px inheriting `margin-inline: auto` from `.wrap`, so
   it centred and produced a SECOND LEFT EDGE at 340px against the grid's 130.
   Her page keeps every band on one left edge — what narrows is the MEASURE,
   not the container. So the wrap keeps the grid and the text gets the limit.
   Caught by measuring left edges across five pages, not by looking. */
.wrap-narrow { width: min(100% - 2.4rem, var(--wrap)); }
.wrap-narrow > * { max-width: var(--narrow); }

/* 11.5px was below the readable floor for CONTROLS. --micro is right for a
   caption and wrong for a primary call to action: "APPLY TO THE ACCELERATOR"
   was rendering at 11.5px uppercase. Labels keep --micro; anything a person
   clicks moves up one step. Found by sweeping computed font sizes, not by
   looking — 11.5 and 13 are indistinguishable in review. */
.btn, .btn-primary, .btn-secondary, .btn-sm, .btn-outline, .btn-filled,
.card-go, .cite-toggle { font-size: var(--step--1); }

/* The citation marker rendered at 9.6px — the smallest text on the site, and
   it is a LINK. It only appears with Sources on, but a reviewer squinting at
   provenance is exactly who should not have to. Lifted to the caption size. */
.cite { font-size: var(--micro); }

/* THE DROPDOWN WAS CENTRE-ALIGNED AND RAGGED.
   `.megacol ul` computed to `display:flex; flex-direction:row;
   justify-content:center` — inherited from a global list rule that my
   `list-style/margin/padding` override never touched. The items laid out in a
   centred ROW and wrapped, so every link sat on a different left edge:
   Volunteer at 579, Become a Mentor at 544, Join the Investor Network at 524.
   Her panel is a plain vertical list on one left edge.

   Reported by the owner from a screenshot. Three computed-style probes were
   needed to find it because `text-align` was `start` everywhere — the TEXT
   was never centred, the LIST ITEMS were. */
.megacol ul { display: block; }
.megacol li { display: list-item; text-align: left; }
.megacol a  { display: inline-block; }

/* The panel ground follows the page. With the site on white, --paper reads as
   a tint against it; her panel is white with a hairline. */
.navpanel { background: #FFFFFF; }

/* HER EVENT DESCRIPTION PAGE — h010 T3, 2026-09-07.
   Details and speaker on the left, a bounded TICKETS panel on the right, as her
   one-slide mockup sets them. Two rules do the whole layout:

     * the DOM order is details → speaker → tickets, which is the reading order
       on a phone and the tab order everywhere. The single column is the
       default, so the narrow case needs no query and cannot be forgotten.
     * the second column arrives at 900px, the same breakpoint the chapter
       directory takes its three columns at, so the two bands change shape
       together rather than at two widths nobody chose.

   `minmax(0, …)` on both tracks because a long unbroken quotation — her
   `[Street Address · City, State ZIP]` on the sibling page — otherwise sets the
   track's minimum to its own width and pushes the panel off the grid.

   No new token, no new size, no new tracking value: every colour here is
   `--rule`/`--ink-2`/`--ink-3`, every label is `--micro` at `--track-caps`, and
   the unresolved line is the muted italic `.dir-unknown` already uses for a
   field nobody has supplied. */
.event-in{display:grid;grid-template-columns:1fr;gap:2rem;margin-top:1.4rem;align-items:start}
.event-main>*+*{margin-top:1.2rem}
.ev-meta{font-weight:700}
.ev-acts{display:flex;flex-wrap:wrap;gap:1.6rem}
.ev-act{margin:0;max-width:24rem}
.ev-act-why{display:block;color:var(--ink-3);font-style:italic}
.ev-h{font-size:var(--micro);font-weight:700;letter-spacing:var(--track-caps);
      text-transform:uppercase;color:var(--ink-3)}
.ev-speaker{border-top:1px solid var(--rule);padding-top:1.1rem}
/* h010 T4: the in-person variant's venue group — her `[Venue Name] · [Street
   Address · City, State ZIP] · View Map` line, drawn as two unfilled fields and
   one control with no destination. Same rule as `.ev-speaker` because it is the
   same object: a labelled group of holes inside the left column. No new token,
   no new size. */
.ev-venue{border-top:1px solid var(--rule);padding-top:1.1rem}
.ev-field{margin-top:.8rem}
.ev-field-h{font-size:var(--micro);font-weight:700;letter-spacing:var(--track-caps);
            text-transform:uppercase;color:var(--ink-3)}
.ev-field-b{margin-top:.2rem}
.ev-unresolved{margin-top:.2rem;color:var(--ink-3);font-style:italic}
.ev-blank{margin-top:.2rem;color:var(--ink-2)}
.event-tickets{border:1px solid var(--rule);padding:1.3rem}
.tk-rows{margin-top:.2rem}
.tk-note{margin-top:1.2rem;font-size:var(--micro);color:var(--ink-3)}
@media (min-width:900px){
  .event-in{grid-template-columns:minmax(0,1.7fr) minmax(0,1fr)}
}

/* ── @iris, h005 T3: two survivor differences from her page 3 ─────────────
   Found by an agent reading the built page against HAE _ Homepage v2.pdf. */

/* T3 finding 2 · WHY HAE. Her 01-04 are BORDERLESS columns under one
   horizontal rule, numerals in crimson. Ours boxed each as a bordered .card,
   which turns a single idea in four parts into four separate objects. */
#why-hae .card-grid { border-top: 1px solid var(--rule); padding-top: 2.2rem; }
#why-hae .card { border: 0; border-radius: 0; padding: 0; background: none; }
#why-hae .card-eyebrow { color: var(--crimson); font-weight: 700; }
#why-hae .card-go { display: none; }   /* her columns carry no per-item link */

/* T3 finding 1 · WHAT'S HAPPENING. Hers is ONE announcement card — photo
   left, eyebrow + headline + body + link right — inside a single border.
   Ours is a three-card text grid, which reads as three items of equal weight
   where she has one piece of news. Narrowed to one card until she sends more
   than one announcement. */
#happening .card-grid { grid-template-columns: 1fr; max-width: 62rem; }
#happening .card { border: 1px solid var(--rule); padding: 1.8rem 2rem; }
#happening .card + .card { display: none; }

/* Cards were still --paper while the page went white — a cream box on a white
   ground reads as a tint nobody chose. Her cards are white with a hairline. */
.card, .tier, .acc, .navpanel, .faq-item { background: #FFFFFF; }

/* Her section eyebrow — the small uppercase label above every band heading.
   Set in the data since the bands were built and rendered nowhere until
   2026-08-19; eight of the homepage's thirteen "missing" labels were this one
   omission. */
.band-eyebrow{font-size:var(--micro);font-weight:700;letter-spacing:var(--track-caps);
              text-transform:uppercase;color:var(--crimson);margin:0 0 .7rem}

/* 2026-09-14 — the masthead on a 390px phone. The utility bar squeezed its
   tagline to three lines beside the links, and LOG IN / JOIN HAE each broke
   onto two lines. Tagline and links now take a line each, and from 380px up
   the two header buttons keep their words on one line. Below 380px the row
   has no room for that and they wrap as before — nowrap there pushed the
   page 11px wider than a 360px screen. No overflow at 360/375/390/430;
   320 overflows as it already did (the footer columns). */
@media (min-width: 380px){ .btn-outline, .btn-filled { white-space: nowrap; } }
@media (max-width: 640px){
  .utilbar-in { flex-wrap: wrap; row-gap: .35rem; }
  .utilbar-tag, .utilbar-links a { white-space: nowrap; }
  .btn-outline, .btn-filled { padding: 10px 10px; }
  .utility { gap: .35rem; }
}

/* Program-surface swatches in the generated styleguide. */
.program-surface-peach { background: var(--program-peach); }
.program-surface-blue-gray { background: var(--program-blue-gray); }
.program-surface-lavender { background: var(--program-lavender); }

/* Homepage palette preview, 2026-10-27: Regina requested #333333 primary type;
   supporting neutrals implement the approved white/crimson/cool-gray direction. */
:root {
  --ink-neutral: #333333;
  --text-soft: #6B6B6B;
  --surface-cool: #F5F6F7;
  --rule-neutral: #E0E3E7;
}
/* Scoped aliases shared with the static homepage preview. */
body:has(#main[data-page=home]) {
  --ink: var(--ink-neutral);
  --ink-2: var(--text-soft);
  --paper-2: var(--surface-cool);
  --rule: var(--rule-neutral);
}

/* Pale sky testimonial surface requested for the Accelerator application page. */
:root { --surface-sky: #F2F7FA; }
.application-testimonials { background: var(--surface-sky); }
