/* Body / typography baseline */
html, body {
  margin: 0;
  padding: 0;
  background: var(--color-pure-white);
  color: var(--color-near-black-ink);
  font-family: var(--font-text);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.47;
  letter-spacing: -0.374px;
}

a {
  color: var(--color-action-blue);
  text-decoration: none;
}
a:hover { text-decoration: underline; }

/* Headlines — Vercel-tightened scale. Display fonts stay SF Pro Display;
   sizes scale down from Apple's marketing rhythm (88/56/40/28) toward a
   tool-app rhythm (48/32/22/16) so the layout reads as a dashboard
   rather than a launch page. */
.headline-display {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.5px;
  line-height: 1.15;
  margin: 0;
}
.headline-hero {
  font-family: var(--font-display);
  font-size: 48px;
  font-weight: 600;
  letter-spacing: -0.8px;
  line-height: 1.08;
  margin: 0;
}
.lead {
  font-family: var(--font-text);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: -0.1px;
  color: var(--color-muted-ink-80);
}
@media (max-width: 833px) {
  .headline-hero { font-size: 36px; letter-spacing: -0.5px; }
  .headline-display { font-size: 26px; }
}

/* Pill CTAs — Vercel-tightened: smaller padding/font, smoother hover
   transitions, subtle elevation on hover, retained scale-on-press
   micro-interaction. */
.btn-pill-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--color-action-blue);
  color: var(--color-paper-white);
  font-family: var(--font-text);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.1px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  padding: 9px 18px;
  cursor: pointer;
  text-decoration: none;
  transition:
    background 0.16s ease,
    transform 0.1s ease,
    box-shadow 0.16s ease;
}
.btn-pill-primary:hover {
  background: #0058b0;       /* Action Blue, ~10% darker */
  text-decoration: none;
}
.btn-pill-primary:active { transform: scale(0.96); }
.btn-pill-primary:focus-visible {
  outline: 2px solid var(--color-focus-blue);
  outline-offset: 2px;
}

.btn-pill-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--color-pure-white);
  color: var(--color-near-black-ink);
  border: 1px solid var(--color-neutral-200);
  border-radius: var(--radius-pill);
  padding: 9px 18px;
  font-family: var(--font-text);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.1px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.1s ease;
}
.btn-pill-ghost:hover {
  background: var(--color-neutral-50);
  border-color: var(--color-neutral-300);
  text-decoration: none;
}
.btn-pill-ghost:active { transform: scale(0.96); }

.btn-pill-pearl {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--color-pearl-button);
  color: var(--color-near-black-ink);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-pill);
  padding: 9px 18px;
  font-family: var(--font-text);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.1px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.16s ease, border-color 0.16s ease, transform 0.1s ease;
}
.btn-pill-pearl:hover {
  background: var(--color-neutral-100);
  border-color: var(--color-neutral-300);
  text-decoration: none;
}
.btn-pill-pearl:active { transform: scale(0.96); }

/* Vercel-style high-contrast CTA — black bg, white text. Use sparingly
   (one per page max) for the most important "Apply" / "Save" action. */
.btn-pill-dark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--color-neutral-900);
  color: var(--color-paper-white);
  border: 1px solid var(--color-neutral-900);
  border-radius: var(--radius-pill);
  padding: 9px 18px;
  font-family: var(--font-text);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.1px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.16s ease, transform 0.1s ease;
}
.btn-pill-dark:hover {
  background: #2a2a2e;
  text-decoration: none;
}
.btn-pill-dark:active { transform: scale(0.96); }

/* Tiles — Vercel-style: 12px corners, hairline border, subtle hover lift
   when tile is interactive (.dashboard-link applies the lift). */
.tile-card {
  background: var(--color-pure-white);
  border-radius: var(--radius-card);
  border: 1px solid var(--color-neutral-200);
  padding: 24px;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.tile-card-soft {  /* opt-in for marketing-style 18px hero panels */
  border-radius: var(--radius-card-soft);
}
.tile-parchment {
  background: var(--color-parchment);
  padding: 64px 0;
}
.tile-dark {
  background: var(--color-tile-1);
  color: var(--color-paper-white);
  padding: 64px 0;
}

/* Centered narrow page wrapper — used for login / signup / pending */
.auth-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--color-parchment);
  padding: var(--space-48) var(--space-24);
}
.auth-card {
  background: var(--color-pure-white);
  border-radius: var(--radius-card);
  border: 1px solid var(--color-hairline);
  padding: 48px;
  width: 100%;
  max-width: 440px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
}
.auth-card .brand {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.28px;
  margin-bottom: var(--space-8);
}
.auth-card .lead-small {
  font-family: var(--font-display);
  font-size: 17px;
  color: var(--color-muted-ink-80);
  margin-bottom: var(--space-24);
}

.auth-card form input[type="text"],
.auth-card form input[type="email"],
.auth-card form input[type="password"] {
  width: 100%;
  box-sizing: border-box;
  padding: 12px 14px;
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-utility);
  font-family: var(--font-text);
  font-size: 17px;
  color: var(--color-near-black-ink);
  background: var(--color-pure-white);
  margin-bottom: var(--space-12);
}
.auth-card form label {
  display: block;
  font-size: 13px;
  color: var(--color-muted-ink-80);
  margin-bottom: var(--space-4);
}
.auth-card .form-row {
  display: flex;
  gap: var(--space-12);
  align-items: center;
  margin-top: var(--space-16);
}
.auth-card .footer-row {
  margin-top: var(--space-24);
  font-size: 14px;
  color: var(--color-muted-ink-80);
}

/* Confidence + season + discipline badges */
.badge {
  display: inline-block;
  border-radius: var(--radius-pill);
  font-size: 12px;
  padding: 4px 10px;
}
.badge-confirmed {
  background: var(--color-action-blue);
  color: var(--color-paper-white);
}
.badge-auto {
  background: var(--color-soft-chip-gray);
  color: var(--color-near-black-ink);
}

/* Errorlist (used by Django forms in templates) */
.errorlist {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-12);
  color: var(--color-destructive);
  font-size: 14px;
}

/* ----- Global nav: floating-island (Raycast-style) -----
   Deviates from the strict Apple §4 edge-to-edge global-nav pattern; see
   DESIGN-apple.md §4 ("Navigation") for the override note. The single
   drop-shadow on this container is an accepted deviation from the
   §6 "no shadows on UI elements" rule.

   The bar sits sticky at top: 16px with horizontal insets, scrolls
   along with the page until it docks at the top, and rests above
   content via z-index + a faint shadow. */
.global-nav {
  position: sticky;
  top: 16px;
  z-index: 100;

  /* Inset margins are intentionally tight so the bar is generously wide
     and gives nav contents room to breathe inside its rounded ends. On
     wider viewports the absolute inset goes up modestly, but the bar
     never collapses to a thin pill. */
  margin: 16px 12px;

  height: 56px;
  border-radius: 28px; /* half the height — fully rounded ends */

  /* Solid Action Blue — the brand accent reads as authoritative when
     fully opaque rather than washed-out behind backdrop-filter. */
  background: var(--color-action-blue);
  color: rgba(255, 255, 255, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);

  display: flex;
  align-items: stretch;
}
.global-nav-inner {
  width: 100%;
  padding: 0 32px;
  display: flex;
  align-items: stretch;
  gap: var(--space-24);
  font-size: 14px;
}
@media (min-width: 640px)  { .global-nav { margin: 16px 24px; } .global-nav-inner { padding: 0 40px; } }
@media (min-width: 1068px) { .global-nav { margin: 16px 32px; } .global-nav-inner { padding: 0 48px; } }
@media (max-width: 419px)  { .global-nav { margin: 12px; }     .global-nav-inner { padding: 0 20px; gap: var(--space-12); } }

.global-nav-brand {
  display: flex;
  align-items: center;
  color: var(--color-paper-white);
  text-decoration: none;
  font-weight: 600;
  letter-spacing: -0.2px;
  font-size: 14px;
  white-space: nowrap;
}
.global-nav-brand:hover { text-decoration: none; opacity: 0.9; }
.global-nav-primary {
  display: flex;
  align-items: stretch;
  gap: var(--space-20);
  /* Center-bias the primary nav links between brand and right cluster.
     The two flexible spacers (set on .global-nav-inner via margin-left
     auto on .global-nav-primary's inner items) achieve a soft center.
     For now we let the gap distribute naturally — the visual center
     happens via flex of the primary group within available space. */
}
.global-nav-spacer { flex: 1; }
.global-nav-right {
  display: flex;
  align-items: center;
  gap: var(--space-12);
}
.global-nav-user {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.92);
  font-size: 13px;
  white-space: nowrap;
}
.global-nav-link {
  display: inline-flex;
  align-items: center;
  color: rgba(255, 255, 255, 0.78);
  text-decoration: none;
  position: relative;
  padding: 0;
  font-weight: 500;
  transition: color 0.15s ease;
  white-space: nowrap;
}
.global-nav-link:hover {
  color: var(--color-paper-white);
  text-decoration: none;
}
.global-nav-link.is-active {
  color: var(--color-paper-white);
  font-weight: 600;
}
/* Right-cluster links get a soft hover pill so they read as actions
   distinct from the primary in-line nav items. */
.global-nav-right .global-nav-link {
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  transition: background 0.15s ease, color 0.15s ease;
}
.global-nav-right .global-nav-link:hover {
  background: rgba(255, 255, 255, 0.16);
  color: var(--color-paper-white);
}

/* Hamburger-only at narrow widths. The <details> element is hidden by
   default and shown via the breakpoint below. Clicking it sets the
   [open] attribute, which is the trigger for revealing the primary
   nav as an absolute-positioned dropdown anchored to the floating bar. */
.global-nav-mobile { display: none; }

/* Responsive nudges for the inner layout. The bar itself never goes
   edge-to-edge; the inset margin always applies. */
@media (max-width: 1067px) {
  .global-nav-primary { gap: var(--space-12); }
  .global-nav-link { font-size: 13px; }
}
@media (max-width: 833px) {
  .global-nav-mobile {
    display: flex;
    align-items: center;
  }
  .global-nav-mobile-toggle {
    cursor: pointer;
    color: rgba(255, 255, 255, 0.85);
    font-size: 20px;
    line-height: 1;
    list-style: none; /* hide the default ▶ disclosure triangle */
    padding: 4px 10px;
    border-radius: var(--radius-pill);
  }
  .global-nav-mobile-toggle::-webkit-details-marker { display: none; }
  .global-nav-mobile-toggle:hover { background: rgba(255, 255, 255, 0.08); }

  /* Hide the primary nav row by default at this breakpoint; the toggle
     reveals it as a dropdown beneath the bar. */
  .global-nav-primary {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    left: 16px;
    right: 16px;
    flex-direction: column;
    gap: 4px;
    background: #1a1a1a;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 18px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
    padding: 12px;
    z-index: 105;
  }
  .global-nav-mobile[open] ~ .global-nav-primary {
    display: flex;
  }
  .global-nav-primary .global-nav-link {
    padding: 10px 12px;
    border-radius: var(--radius-utility);
  }
  .global-nav-primary .global-nav-link:hover {
    background: rgba(255, 255, 255, 0.08);
  }
  .global-nav-primary .global-nav-dropdown { width: 100%; }
  .global-nav-primary .global-nav-dropdown-toggle {
    width: 100%;
    text-align: left;
    padding: 10px 12px;
    border-radius: var(--radius-utility);
  }
  .global-nav-primary .global-nav-menu {
    /* In the mobile dropdown, the inner sub-menu sits inline rather
       than as a floating absolute panel. */
    position: static;
    display: block;
    box-shadow: none;
    border: none;
    background: rgba(255, 255, 255, 0.04);
    margin-top: 4px;
    padding: 4px 0;
    color: rgba(255, 255, 255, 0.85);
  }
  .global-nav-primary .global-nav-menu-item {
    color: rgba(255, 255, 255, 0.78);
    padding-left: 28px;
  }
  .global-nav-primary .global-nav-menu-item:hover {
    background: rgba(255, 255, 255, 0.08);
  }
  .global-nav-primary .global-nav-menu-item.is-active {
    color: var(--color-action-blue);
  }

  /* At ≤833px the username pill costs more horizontal space than it's
     worth — Sign out alone is sufficient to convey "logged in". */
  .global-nav-user { display: none; }
}

@media (max-width: 500px) {
  /* On true phone widths the brand wordmark eats the bar; toggle alone
     identifies the surface. */
  .global-nav-brand { display: none; }
}

/* Dropdowns in the global nav (Apple-styled, CSS-only — hover/focus). */
.global-nav-dropdown {
  position: relative;
  display: inline-flex;
  align-items: stretch;
}
.global-nav-dropdown-toggle {
  background: transparent;
  border: none;
  cursor: pointer;
  font: inherit;
}
.global-nav-caret {
  font-size: 10px;
  margin-left: 4px;
  opacity: 0.6;
}
.global-nav-menu {
  position: absolute;
  top: 100%;
  left: -12px;
  min-width: 240px;
  background: var(--color-pure-white);
  color: var(--color-near-black-ink);
  border-radius: var(--radius-card);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.06);
  border: 1px solid var(--color-hairline);
  padding: 6px 0;
  display: none;
  z-index: 110;
  margin-top: 4px;
}
/* Invisible bridge that extends the hover area through the gap between
   the button and the menu so :hover doesn't flip off mid-air. */
.global-nav-menu::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -8px;
  height: 8px;
  background: transparent;
}
.global-nav-dropdown:hover .global-nav-menu,
.global-nav-dropdown:focus-within .global-nav-menu {
  display: block;
}
.global-nav-menu-item {
  display: block;
  padding: 8px 16px;
  font-size: 14px;
  color: var(--color-near-black-ink);
  text-decoration: none;
  white-space: nowrap;
}
.global-nav-menu-item:hover {
  background: var(--color-parchment);
  text-decoration: none;
}
.global-nav-menu-item.is-active {
  color: var(--color-action-blue);
  font-weight: 600;
}

/* ----- Section sub-nav (frosted band, Apple §4) -----
   Sticky top is anchored to dock just below the floating global nav
   (16px top offset + 56px bar height + 16px breathing room = 88px). */
.sub-nav {
  background: rgba(245, 245, 247, 0.85);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--color-hairline);
  position: sticky;
  top: 88px;
  z-index: 90;
}
.sub-nav-inner {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--space-24);
  display: flex;
  align-items: center;
  gap: var(--space-16);
  font-size: 14px;
  min-height: 48px;
}
.sub-nav-left { font-weight: 600; }
.sub-nav-right { margin-left: auto; display: flex; align-items: center; gap: var(--space-12); }
.sub-nav-tabs {
  display: flex;
  align-items: center;
  gap: var(--space-24);
  flex-wrap: wrap;
}
.sub-nav-tab {
  color: var(--color-muted-ink-80);
  text-decoration: none;
  padding: 14px 0;
  position: relative;
  font-weight: 400;
  transition: color 0.15s ease;
}
.sub-nav-tab:hover { color: var(--color-near-black-ink); text-decoration: none; }
.sub-nav-tab.is-active {
  color: var(--color-near-black-ink);
  font-weight: 600;
}
.sub-nav-tab.is-active::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--color-action-blue);
}

/* ----- Module sub-nav (second strip under section sub-nav) -----
   Renders as a small floating pill below the global-nav pill: the
   outer container is transparent (so the page content shows through
   the empty side margins), only the inner row carries a frosted pill
   background. Sticky so the tabs stay docked at top: 88px while
   scrolling — matches the .sub-nav docking position (16px margin +
   56px global pill height + 16px breathing = 88px). pointer-events
   are turned off on the empty outer area so clicks pass through to
   content below. */
.module-sub-nav {
  position: sticky;
  top: 88px;
  z-index: 90;
  padding: 0 var(--space-24);
  display: flex;
  justify-content: center;
  background: transparent;
  pointer-events: none;
}
.module-sub-nav-inner {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--space-20);
  font-size: 13px;
  min-height: 40px;
  flex-wrap: wrap;

  /* Floating pill — smaller-scale echo of the global-nav pill above. */
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 20px;
  padding: 0 var(--space-20);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}
.module-sub-nav-tab {
  color: var(--color-muted-ink-80);
  text-decoration: none;
  padding: 10px 0;
  position: relative;
}
.module-sub-nav-tab:hover { color: var(--color-near-black-ink); text-decoration: none; }
.module-sub-nav-tab.is-active {
  color: var(--color-action-blue);
  font-weight: 600;
}

/* ----- Footer ----- */
.site-footer {
  background: var(--color-parchment);
  border-top: 1px solid var(--color-hairline);
  margin-top: var(--space-80);
  padding: var(--space-24) 0;
}
.site-footer-inner {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--space-24);
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: var(--color-muted-ink-80);
}
.site-footer-meta { color: var(--color-muted-ink-48); }

@media (max-width: 833px) {
  .site-footer-inner { flex-direction: column; gap: var(--space-8); }
}

/* ----- Analytics page skeleton (consumed by every plan-05 view) ----- */
.analytics-shell {
  max-width: 1440px;
  margin: 0 auto;
}
.analytics-tile {
  padding: var(--space-64) var(--space-24);
}
.analytics-tile.parchment { background: var(--color-parchment); }
.analytics-tile.white     { background: var(--color-pure-white); }
.analytics-tile-inner {
  max-width: 1280px;
  margin: 0 auto;
}
.analytics-headline-num {
  font-family: var(--font-display);
  font-size: 56px;
  font-weight: 600;
  letter-spacing: -1.2px;
  line-height: 1.05;
  color: var(--color-near-black-ink);
  font-variant-numeric: tabular-nums;
}
/* Inline pairing of a hero stat with its short caption — used in
   analytics page banners where the big number and the one-line
   description sit side-by-side instead of stacking, to keep the tile's
   vertical footprint compact. */
.analytics-stat-inline {
  display: flex;
  align-items: baseline;
  gap: var(--space-20);
  flex-wrap: wrap;
}
.analytics-stat-inline .analytics-headline-delta {
  margin-top: 0;
  max-width: 540px;
}
@media (max-width: 639px) {
  .analytics-stat-inline { gap: var(--space-12); }
}
.analytics-headline-delta {
  font-family: var(--font-text);
  font-size: 14px;
  margin-top: 6px;
  color: var(--color-neutral-500);
}
.analytics-method-note {
  font-size: 13px;
  color: var(--color-muted-ink-80);
  max-width: 720px;
  line-height: 1.55;
}

/* Chart tile — softer card with crisp 12px corner. */
.analytics-chart-tile {
  width: 100%;
  background: var(--color-pure-white);
  border-radius: var(--radius-card);
  border: 1px solid var(--color-neutral-200);
  padding: var(--space-24);
  margin: 0 auto;
  max-width: 1280px;
  position: relative;
}
.analytics-chart-svg-host {
  width: 100%;
  min-height: 320px;
}

/* Chart legend */
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  font-size: 13px;
  margin-bottom: var(--space-16);
}
.chart-legend-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-soft-chip-gray);
  cursor: pointer;
  user-select: none;
}
.chart-legend-chip[aria-pressed="true"] {
  background: var(--color-action-blue);
  color: var(--color-paper-white);
}
.chart-legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
}

/* Chart-tile header row — title on the left, controls (e.g., the
   stacked/total segmented control for the grade chart) on the right. */
.chart-tile-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-16);
  margin-bottom: var(--space-12);
}
.chart-tile-toggle-slot {
  flex: 0 0 auto;
}
@media (max-width: 639px) {
  .chart-tile-header { flex-direction: column; }
}

/* Segmented control — Vercel-style pill with two segments. The active
   segment gets a white card surface + subtle 1px shadow; the inactive
   segment is transparent on the parchment-tinted track. */
.chart-toggle {
  display: inline-flex;
  background: var(--color-neutral-100);
  border: 1px solid var(--color-neutral-200);
  border-radius: var(--radius-pill);
  padding: 3px;
  gap: 0;
}
.chart-toggle-btn {
  display: inline-flex;
  align-items: center;
  padding: 5px 14px;
  border: none;
  background: transparent;
  font-family: var(--font-text);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.1px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  color: var(--color-muted-ink-80);
  transition: background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
  white-space: nowrap;
}
.chart-toggle-btn:hover { color: var(--color-near-black-ink); }
.chart-toggle-btn.is-active {
  background: var(--color-pure-white);
  color: var(--color-near-black-ink);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08),
              0 1px 1px rgba(0, 0, 0, 0.04);
}
.chart-toggle-btn:focus-visible {
  outline: 2px solid var(--color-action-blue);
  outline-offset: 2px;
}

/* Programs-overview list — discipline / season tallies on the
   summary_programs page. Each row uses [data-discipline=…] to pick up
   the discipline tint via the existing [data-discipline] CSS rules
   (which set `color`); the swatch chip uses currentColor so it lights
   up in the discipline's tint, and the name text inherits ink color. */
.programs-overview-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
.programs-overview-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.programs-overview-list-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: currentColor;
  flex: 0 0 10px;
}
.programs-overview-list-name {
  color: var(--color-near-black-ink);
  flex: 1 1 auto;
  min-width: 0;
}
.programs-overview-list-count {
  font-weight: 600;
  color: var(--color-muted-ink-80);
}

/* Project-overview "What this surface answers" list on the home page. */
.project-objectives {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-12);
}
.project-objectives li {
  font-size: 15px;
  line-height: 1.55;
  color: var(--color-near-black-ink);
  padding-left: 16px;
  position: relative;
}
.project-objectives li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 10px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-action-blue);
}
.project-objectives strong {
  font-weight: 600;
  color: var(--color-near-black-ink);
}

/* Dual-thumb range slider — used on the discipline-transitions page
   to bracket the grade range fed into the analysis. Two overlaid
   <input type="range"> elements share a background track; a colored
   fill div tracks the active range. JS clamps min ≤ max and updates
   the live label as the user drags. */
.grade-range-slider {
  display: inline-flex;
  flex-direction: column;
  gap: 6px;
  min-width: 260px;
}
.grade-range-slider-label {
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-neutral-500);
}
.grade-range-slider-label .grade-range-current {
  color: var(--color-near-black-ink);
  text-transform: none;
  letter-spacing: -0.1px;
  font-weight: 600;
  margin-left: 6px;
  font-variant-numeric: tabular-nums;
}
.grade-range-track-wrap {
  position: relative;
  height: 28px;
  display: flex;
  align-items: center;
  width: 240px;
}
.grade-range-track,
.grade-range-fill {
  position: absolute;
  height: 4px;
  /* The 28px wrapper has the input thumbs vertically centered; place
     the track + fill at the same y so the dots ride on the line. */
  top: calc(50% - 2px);
  border-radius: 2px;
  pointer-events: none;
}
.grade-range-track {
  left: 0; right: 0;
  background: var(--color-neutral-200);
}
.grade-range-fill {
  background: var(--color-action-blue);
  /* JS sets `left` and `right` as % values to bracket the active range. */
}
.grade-range-input {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  left: 0; right: 0;
  width: 100%;
  background: transparent;
  pointer-events: none; /* track itself swallows nothing; only thumbs grab */
  margin: 0;
  height: 28px;
}
/* Native thumbs become invisible drag targets. Their geometric edges
   anchor at the input's bounds at min/max, which would visually shift
   the dot inward — we don't render those at all. The visible
   .grade-range-thumb DIVs below replace them, positioned by JS using
   left: X%; transform: translate(-50%, -50%) so the center always
   sits on the value point regardless of slider extreme. */
.grade-range-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  background: transparent;
  border: none;
  box-shadow: none;
  cursor: pointer;
  pointer-events: auto;
}
.grade-range-input::-moz-range-thumb {
  width: 18px;
  height: 18px;
  background: transparent;
  border: none;
  box-shadow: none;
  cursor: pointer;
  pointer-events: auto;
}
.grade-range-input::-webkit-slider-runnable-track {
  height: 28px;
  background: transparent;
  border: none;
}
.grade-range-input::-moz-range-track {
  height: 28px;
  background: transparent;
  border: none;
}

/* Visible thumb DIVs — geometric center sits at left: X%; top: 50%
   via the translate. Pointer-events:none so drag passes through to
   the native input underneath (which is the actual hit target). */
.grade-range-thumb {
  position: absolute;
  top: 50%;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-pure-white);
  border: 2px solid var(--color-action-blue);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
  transform: translate(-50%, -50%);
  pointer-events: none;
  /* JS sets `left: X%` based on (value / max) * 100. */
}

/* Year-highlight chip strip on the grade-distribution page. Each chip
   toggles whether that year's line is colored prominently across every
   small-multiple panel. Multiple chips may be active; each gets a
   distinct color from a 4-stop palette set inline by the JS so the
   chip color matches the line color. */
.grade-year-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-bottom: var(--space-16);
  padding: 12px 14px;
  background: var(--color-neutral-50);
  border: 1px solid var(--color-neutral-200);
  border-radius: var(--radius-utility);
}
.grade-year-picker-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-neutral-500);
  margin-right: 8px;
}
.grade-year-chip {
  font-family: var(--font-text);
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-neutral-200);
  background: var(--color-pure-white);
  color: var(--color-neutral-700);
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}
.grade-year-chip:hover {
  border-color: var(--color-neutral-300);
  background: var(--color-pure-white);
  color: var(--color-near-black-ink);
}
.grade-year-chip.is-active {
  /* Active chips get their stroke color injected as inline styles
     by the JS so they visually match the line color in the chart. */
  color: var(--color-paper-white);
  font-weight: 600;
}
.grade-year-chip:focus-visible {
  outline: 2px solid var(--color-action-blue);
  outline-offset: 2px;
}
.grade-year-clear {
  font-family: var(--font-text);
  font-size: 12px;
  font-weight: 500;
  color: var(--color-muted-ink-48);
  background: transparent;
  border: none;
  cursor: pointer;
  margin-left: auto;
  padding: 4px 10px;
  border-radius: var(--radius-utility);
  transition: background 0.12s ease, color 0.12s ease;
}
.grade-year-clear:hover {
  background: var(--color-neutral-100);
  color: var(--color-near-black-ink);
}

/* Legend chips for stacked bar charts. Used by the cohort histogram
   when bins carry per-segment counts (e.g. grade × school stack). */
.cohort-histogram-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--color-divider-4);
  font-size: 12px;
  color: var(--color-near-black-ink);
}
.cohort-histogram-legend-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 4px;
  white-space: nowrap;
}
.cohort-histogram-legend-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex: 0 0 10px;
}

/* Tables — Vercel: small uppercase tracked-caps header on neutral-50,
   subtle row dividers, tabular-nums on numeric columns (apply via the
   .num utility), soft hover. */
.analytics-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  background: var(--color-pure-white);
}
.analytics-table thead th {
  text-align: left;
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-neutral-500);
  background: var(--color-neutral-50);
  padding: 10px 14px;
  border-bottom: 1px solid var(--color-neutral-200);
}
.analytics-table thead th:first-child { border-top-left-radius: 8px; }
.analytics-table thead th:last-child  { border-top-right-radius: 8px; }
.analytics-table tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--color-divider-4);
  color: var(--color-near-black-ink);
}
.analytics-table tbody tr {
  transition: background 0.12s ease;
}
.analytics-table tbody tr:hover td {
  background: var(--color-neutral-50);
}
.analytics-table tbody tr:last-child td { border-bottom: none; }
.analytics-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Filter bar — Vercel: inline label-input pairs, smaller controls, a
   visible-on-focus accent ring driven by Action Blue. */
.analytics-filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-12);
  align-items: end;
  margin-top: var(--space-16);
}
/* Only labels wrapping a select / text-input get the stacked
   tracked-caps treatment. Labels wrapping a checkbox or radio (e.g.
   season filters) keep the default inline flow so the box and its
   text sit side-by-side. */
.analytics-filter-bar label:has(select),
.analytics-filter-bar label:has(input[type="text"]),
.analytics-filter-bar label:has(input[type="number"]),
.analytics-filter-bar label:has(input[type="search"]) {
  display: inline-flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-neutral-500);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.analytics-filter-bar select,
.analytics-filter-bar input[type="text"],
.analytics-filter-bar input[type="number"],
.analytics-filter-bar input[type="search"] {
  padding: 8px 12px;
  border: 1px solid var(--color-neutral-200);
  border-radius: var(--radius-utility);
  font-family: var(--font-text);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: -0.1px;
  color: var(--color-near-black-ink);
  background: var(--color-pure-white);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
  text-transform: none;
}
.analytics-filter-bar select:hover,
.analytics-filter-bar input:hover {
  border-color: var(--color-neutral-300);
}
.analytics-filter-bar select:focus,
.analytics-filter-bar input:focus {
  outline: none;
  border-color: var(--color-action-blue);
  box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.16);
}

/* Responsive — Apple §8 */
@media (max-width: 1067px) {
  .analytics-tile { padding: var(--space-48) var(--space-16); }
  .analytics-headline-num { font-size: 44px; }
}
@media (max-width: 639px) {
  .analytics-tile { padding: var(--space-24) var(--space-16); }
  .analytics-headline-num { font-size: 36px; }
}

/* Tooltip (positioned via JS in chart_utils.js) */
.chart-tooltip {
  position: fixed;
  pointer-events: none;
  background: var(--color-pure-white);
  border: 1px solid var(--color-hairline);
  border-radius: var(--radius-utility);
  padding: 8px 12px;
  font-size: 14px;
  color: var(--color-near-black-ink);
  z-index: 1000;
  box-shadow: var(--shadow-product);
  opacity: 0;
  transition: opacity 0.1s ease;
}
.chart-tooltip.visible { opacity: 1; }

/* Cohort drill-in modal — opens when a histogram bar is clicked.
   Uses the native HTML <dialog> element with showModal() so ESC and
   focus-trap come for free; the ::backdrop pseudo handles the scrim.
   Visually borrowed from Vercel's command-modal language: tall
   max-height, generous padding, sharp typography hierarchy, an inline
   horizontal bar in each row to give the count a glanceable shape.

   Entry animation: slide down from above + fade in via @starting-style.
   Browsers without @starting-style support (older Safari/FF) fall back
   to instant open — no breakage. */
.cohort-modal {
  border: none;
  border-radius: 14px;
  padding: 0;
  background: var(--color-pure-white);
  color: var(--color-near-black-ink);
  width: min(720px, calc(100vw - 32px));
  max-height: 85vh;
  margin-top: 6vh;            /* anchor to upper portion of viewport */
  margin-bottom: auto;
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.04),
    0 24px 64px rgba(0, 0, 0, 0.18),
    0 8px 24px rgba(0, 0, 0, 0.10);
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity 0.22s ease,
    transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1),
    overlay 0.22s ease allow-discrete,
    display 0.22s ease allow-discrete;
}
.cohort-modal:not([open]) {
  opacity: 0;
  transform: translateY(-32px);
}
@starting-style {
  .cohort-modal[open] {
    opacity: 0;
    transform: translateY(-32px);
  }
}
.cohort-modal::backdrop {
  background: rgba(15, 15, 17, 0.48);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 1;
  transition:
    opacity 0.22s ease,
    overlay 0.22s ease allow-discrete,
    display 0.22s ease allow-discrete;
}
.cohort-modal:not([open])::backdrop { opacity: 0; }
@starting-style {
  .cohort-modal[open]::backdrop { opacity: 0; }
}

.cohort-modal-form {
  display: flex;
  flex-direction: column;
  max-height: 85vh;
  margin: 0;
}
.cohort-modal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-24);
  padding: 28px 32px 20px;
  border-bottom: 1px solid var(--color-hairline);
}
.cohort-modal-title {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.4px;
  line-height: 1.18;
  margin: 0 0 6px;
  color: var(--color-near-black-ink);
  /* Long school names break gracefully instead of overflowing. */
  word-break: break-word;
}
.cohort-modal-subtitle {
  margin: 0;
  font-size: 14px;
  color: var(--color-muted-ink-48);
  letter-spacing: -0.1px;
}
.cohort-modal-close {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-pearl-button);
  border: 1px solid var(--color-hairline);
  border-radius: 50%;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  color: var(--color-muted-ink-80);
  transition:
    background 0.12s ease,
    border-color 0.12s ease,
    transform 0.12s ease;
}
.cohort-modal-close:hover {
  background: var(--color-parchment);
  border-color: rgba(0, 0, 0, 0.18);
}
.cohort-modal-close:active { transform: scale(0.95); }
.cohort-modal-close:focus-visible {
  outline: 2px solid var(--color-action-blue);
  outline-offset: 2px;
}

.cohort-modal-body {
  padding: 8px 32px 28px;
  overflow-y: auto;
  /* Smooth scrolling + thin scrollbar feel, Vercel-ish. */
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
}
.cohort-modal-body::-webkit-scrollbar { width: 8px; }
.cohort-modal-body::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.18);
  border-radius: 8px;
}

.cohort-modal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  margin-top: 8px;
}
.cohort-modal-table thead th {
  text-align: left;
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-muted-ink-48);
  padding: 12px 10px;
  background: var(--color-parchment);
  border-bottom: 1px solid var(--color-hairline);
  position: sticky;
  top: 0;
  z-index: 1;
}
.cohort-modal-table thead th:first-child { border-top-left-radius: 8px; }
.cohort-modal-table thead th:last-child  { border-top-right-radius: 8px; }
.cohort-modal-table tbody td {
  padding: 12px 10px;
  border-bottom: 1px solid var(--color-divider-4);
  vertical-align: middle;
}
.cohort-modal-table tbody tr {
  transition: background 0.12s ease;
}
.cohort-modal-table tbody tr:hover td {
  background: var(--color-parchment);
}
.cohort-modal-table .cohort-modal-name {
  font-weight: 500;
  color: var(--color-near-black-ink);
}
.cohort-modal-table .cohort-modal-count {
  width: 1%;
  white-space: nowrap;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--color-near-black-ink);
}
/* Inline mini-bar visualizing the row's share of the bin total — gives
   the table a glanceable shape without leaving the modal. Width is set
   inline by the JS based on `count / max`. */
.cohort-modal-bar {
  width: 120px;
  position: relative;
}
.cohort-modal-bar-track {
  height: 6px;
  background: rgba(0, 102, 204, 0.10);
  border-radius: 3px;
  overflow: hidden;
}
.cohort-modal-bar-fill {
  height: 100%;
  background: var(--color-action-blue);
  border-radius: 3px;
  transition: width 0.4s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.cohort-modal-table tfoot td {
  padding: 14px 10px 4px;
  font-weight: 600;
  font-size: 13px;
  color: var(--color-muted-ink-80);
  border-top: 1px solid var(--color-hairline);
  border-bottom: none;
}

@media (max-width: 640px) {
  .cohort-modal { width: calc(100vw - 16px); margin-top: 4vh; }
  .cohort-modal-header { padding: 20px 20px 14px; }
  .cohort-modal-body { padding: 8px 20px 20px; }
  .cohort-modal-bar { display: none; }
}

/* Dashboard summary tiles — Vercel-style compact cards. The big stat
   number drops from 56px to 32px so the tile reads as "metric +
   description" rather than "marketing hero". */
.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-16);
}
.dashboard-link {
  display: block;
  text-decoration: none;
  color: var(--color-near-black-ink);
  transition: transform 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease;
}
.dashboard-link:hover {
  text-decoration: none;
  transform: translateY(-1px);
  border-color: var(--color-neutral-300);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 4px 12px rgba(0, 0, 0, 0.04);
}
.dashboard-grid h3,
.dashboard-link h2 {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--color-neutral-500);
  margin: 0 0 var(--space-8);
}
.dashboard-grid p,
.dashboard-link p {
  font-size: 13px;
  line-height: 1.45;
  color: var(--color-muted-ink-80);
  margin: 0;
}
.dashboard-stat {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.5px;
  line-height: 1.1;
  color: var(--color-near-black-ink);
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--space-8);
}

/* Discipline tints — used by both mapping and analytics */
[data-discipline="alpine"] { color: var(--color-disc-alpine); }
[data-discipline="moguls"] { color: var(--color-disc-moguls); }
[data-discipline="freeskiing"] { color: var(--color-disc-freeskiing); }
[data-discipline="snowboard"] { color: var(--color-disc-snowboard); }
[data-discipline="cross_country"] { color: var(--color-disc-cross-country); }
[data-discipline="jump_nordic_combined"] { color: var(--color-disc-jump-nordic); }
[data-discipline="cycling"] { color: var(--color-disc-cycling); }
[data-discipline="youth_development"] { color: var(--color-disc-youth-development); }
[data-discipline="other"] { color: var(--color-disc-other); }
