@import url("tokens.css");

/* =============================================================================
   Rock'Em Robotics Booster Club — site.css
   Hand-written. No build step, no framework.

   HOW TO EDIT THIS FILE
   - Every colour, size, space, radius, shadow and duration comes from
     assets/css/tokens.css. Never write a raw hex value here (the one exception
     the design system itself makes is #fff, used where the club mark needs an
     opaque white tile). If a value you want does not exist as a token, pick the
     nearest token rather than inventing a number.
   - Breakpoints, in order of appearance at the bottom of each section:
       860px — the nav collapses to a toggle panel; two-column splits stack
       720px — section padding shrinks, grids stack
       560px — tightest phone layout
     Add rules to those three blocks. Do not introduce a fourth breakpoint.

   CONTENTS
     1.  Skip link and shared helpers
     2.  Layout: .shell, .band, grids, prose
     3.  Type helpers: .eyebrow, .lede, hero
     4.  Buttons: .btn and variants
     5.  Cards
     6.  Stats, callouts, chips
     7.  Schedule table and roster
     8.  Site header and navigation
     9.  Site footer
     10. States and motion (incl. prefers-reduced-motion)
     11. Responsive: 860px / 720px / 560px
     12. Board page (board.html)
     13. Meetings page (meetings.html)
     14. Home page (index.html)
   ============================================================================ */


/* =============================================================================
   1. SKIP LINK AND SHARED HELPERS
   ========================================================================== */

/* First focusable element on every page. Off-screen until it is focused. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: var(--space-4);
  z-index: var(--z-toast);
  transform: translateY(-200%);
  padding: var(--space-3) var(--space-5);
  background: var(--lake-red);
  color: var(--text-on-red);
  font: var(--type-label);
  font-size: var(--size-caption);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  text-decoration: none;
  border-radius: var(--radius-md);
  transition: transform var(--duration-fast) var(--ease-standard);
}

.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  color: var(--text-on-red);
}

/* Screen-reader-only text (button labels, table captions). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The sticky header would otherwise cover an anchor target. */
#main {
  scroll-margin-top: calc(78px + var(--space-4));
}

/* Lists that are structure, not bullets. */
.list-plain {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* A mono metadata line. Use · as the only separator. */
.meta {
  font: var(--type-mono);
  color: var(--text-muted);
}

/* A row of buttons. Wraps on narrow screens instead of overflowing. */
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
}


/* =============================================================================
   2. LAYOUT
   ========================================================================== */

/* The one horizontal container. Everything on the page sits in a .shell. */
.shell {
  width: 100%;
  max-width: var(--layout-max);
  margin-inline: auto;
  padding-inline: var(--layout-gutter);
}

/* A full-width horizontal section. Put a .shell directly inside it. */
/* Bands carry their own background, so adjacent ones cannot collapse their
   padding — two neighbours put 2x this value between their content. At the
   token's 80px that came to 160px, which read as too airy for pages this short,
   so the band rhythm is one step down at 64px (128px between sections). */
.band {
  padding-block: var(--space-16);
  background: var(--surface-page);
}

/* Tone modifiers. Alternate these down a long page; never repeat a tone
   back-to-back, and keep at most two tones plus white in play per page. */
.band--alt   { background: var(--surface-page-alt); }
.band--tint  { background: var(--surface-brand-tint); }
.band--brand {
  background: var(--surface-brand);
  color: var(--text-on-blue);
}

/* Text inside a blue band is pure white at full opacity — never alpha-muted. */
.band--brand h1,
.band--brand h2,
.band--brand h3,
.band--brand h4,
.band--brand p,
.band--brand li,
.band--brand dd,
.band--brand dt {
  color: var(--text-on-blue);
}

.band--brand .lake-sub {
  color: var(--blue-200);
}

.band--brand a:not(.btn) {
  color: var(--lake-white);
  text-decoration: underline;
}

.band--brand a:not(.btn):hover {
  color: var(--blue-200);
}

/* A hairline between two bands of the same family, when one is needed. */
.band--ruled {
  border-top: var(--border-hairline) solid var(--border-default);
}

/* Reading measure. Wrap any run of body copy longer than a couple of lines. */
.prose {
  max-width: var(--layout-max-prose);
}

.prose > :last-child {
  margin-bottom: 0;
}

/* A heading sitting directly on body copy needs the breathing room .section-head
   gives its children. .stack manages its own gaps, so leave those alone. */
.prose:not(.stack) > h2,
.prose:not(.stack) > h3,
.prose:not(.stack) > h4 {
  margin-bottom: var(--space-4);
}

/* Vertical rhythm for a stack of blocks. */
.stack     { display: flex; flex-direction: column; gap: var(--space-6); }
.stack--sm { gap: var(--space-3); }
.stack--lg { gap: var(--space-10); }

/* The gap owns spacing inside a stack. Zero the children's own bottom margin so
   the two do not compound — a <p> kept its 16px margin on top of the 24px gap,
   which put 40px between paragraphs but only 24px before a <div>, so the same
   stack spaced unevenly depending on what each child happened to be. Paragraphs
   nested deeper (inside a .prose child) keep their normal rhythm. */
.stack > * {
  margin-bottom: 0;
}

/* Section heading group: .eyebrow + h2 + optional .lake-sub. */
.section-head {
  max-width: var(--layout-max-prose);
  margin-bottom: var(--space-8);
}

.section-head > * + * {
  margin-top: var(--space-3);
}

/* Equal-width grids. All of them collapse to one column at 720px. */
.grid {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}

.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Content plus a narrower aside. Stacks at 860px. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--space-12);
  align-items: start;
}


/* =============================================================================
   3. TYPE HELPERS
   Three treatments only: .lake-shout (heavy italic caps), .lake-sub (light
   italic sentence case) and regular upright body. Both .lake-* classes are
   defined in tokens/base.css — consume them, do not redefine them.
   ========================================================================== */

/* Small red all-caps label that sits above a heading. */
.eyebrow {
  display: block;
  font: var(--type-label);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  color: var(--red-600);
  margin: 0 0 var(--space-3);
}

.band--brand .eyebrow {
  color: var(--red-300);
}

/* Sub-headline sizing. Pair with .lake-sub for the italic light treatment. */
.lede {
  font-size: var(--size-body-lg);
  line-height: var(--leading-relaxed);
  max-width: var(--layout-max-prose);
}

/* Big number or short shout inside a band. */
.display {
  font-family: var(--font-display);
  font-weight: var(--weight-black);
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-tight);
  font-size: clamp(38px, 6.5vw, var(--size-display-2));
  margin: 0;
}

/* The home-page hero. .hero--center is the ONE place centred text is allowed. */
.hero {
  padding-block: calc(var(--space-16) + var(--space-4)) var(--space-16);
}

.hero__title {
  font-size: clamp(var(--size-h1), 8vw, var(--size-display-1));
  margin: 0 0 var(--space-5);
}

.hero--center {
  text-align: center;
}

.hero--center .hero__title,
.hero--center .lede,
.hero--center .prose {
  margin-inline: auto;
}

.hero--center .actions {
  justify-content: center;
}

/* Mono runs: team number, dates, dollar amounts. */
.mono {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
}

/* A short slanted rule under a lockup. .lake-rule comes from base.css;
   this only gives it a sensible width and spacing. */
.rule-short {
  width: var(--space-16);
  margin: var(--space-5) 0;
}

.hero--center .rule-short {
  margin-inline: auto;
}


/* =============================================================================
   4. BUTTONS
   ALL CAPS, bold, verb-first, 1–3 words. Corners stay sharp: --radius-md.
   Never --radius-pill on a button.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--control-h-md);
  padding: 0 var(--pad-control-x);
  border: var(--border-thick) solid transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  font-size: var(--size-body-sm);
  line-height: 1;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
  background: transparent;
  transition: var(--transition-control);
}

.btn--lg {
  min-height: var(--control-h-lg);
  padding: 0 var(--space-8);
  font-size: var(--size-body);
}

.btn--sm {
  min-height: var(--control-h-sm);
  padding: 0 var(--space-4);
  font-size: var(--size-caption);
}

/* Fills the width of its container — useful inside a card or on a phone. */
.btn--block {
  display: flex;
  width: 100%;
}

/* Red fill. The membership CTA. */
.btn--accent {
  background: var(--action-accent);
  border-color: var(--action-accent);
  color: var(--text-on-red);
}

/* Blue fill. */
.btn--primary {
  background: var(--action-primary);
  border-color: var(--action-primary);
  color: var(--text-on-blue);
}

/* Blue keyline on a light surface. */
.btn--outline {
  background: transparent;
  border-color: var(--action-primary);
  color: var(--action-primary);
}

/* White on a blue band. */
.btn--inverse {
  background: var(--lake-white);
  border-color: var(--lake-white);
  color: var(--lake-blue);
}

/* The brand's hard offset block. ONE feature element per view — using it twice
   on a page kills it. */
.btn--feature {
  box-shadow: var(--shadow-hard-red);
}


/* =============================================================================
   5. CARDS
   ========================================================================== */

.card {
  background: var(--surface-card);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  padding: var(--pad-card);
  transition: var(--transition-control);
}

.card > :last-child {
  margin-bottom: 0;
}

/* A card whose whole surface is a link. */
a.card,
.card--interactive {
  display: block;
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  color: var(--text-body);
}

/* Left red keyline — for the one card in a group that needs emphasis. The left
   corners square off so the keyline reads as a straight line, not a bowed edge;
   .callout does the same. Every red keyline in this brand is dead straight. */
.card--accent {
  border-left: var(--border-logo) solid var(--lake-red);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}

/* A card sitting on a blue band. */
.band--brand .card {
  border-color: var(--blue-700);
}

.card__title {
  margin: 0 0 var(--space-2);
}

.card__meta {
  font: var(--type-mono);
  color: var(--text-muted);
  margin: 0 0 var(--space-3);
}


/* =============================================================================
   6. STATS, CALLOUTS, CHIPS
   ========================================================================== */

/* A number and its label. Numbers and dollar amounts are mono. */
.stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.stat__value {
  font-family: var(--font-mono);
  font-weight: var(--weight-bold);
  font-size: var(--size-display-2);
  line-height: 1;
  letter-spacing: var(--tracking-display);
  color: var(--lake-blue);
}

.stat__label {
  font: var(--type-label);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.band--brand .stat__value { color: var(--lake-white); }
.band--brand .stat__label { color: var(--blue-200); }

/* A pulled-out sentence: red keyline on the left, tinted field. */
.callout {
  border-left: var(--border-logo) solid var(--lake-red);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--surface-brand-tint);
  padding: var(--space-5) var(--space-6);
}

.callout > :last-child {
  margin-bottom: 0;
}

/* On a white or alt band where the tint would disappear. */
.callout--plain {
  background: var(--surface-card);
  border-top: var(--border-hairline) solid var(--border-default);
  border-right: var(--border-hairline) solid var(--border-default);
  border-bottom: var(--border-hairline) solid var(--border-default);
}

.band--brand .callout {
  background: var(--blue-700);
}

/* Small metadata pill. The only place --radius-pill is allowed. */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 3px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  font-size: var(--size-caption);
  line-height: 1.3;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  white-space: nowrap;
}

/* A meeting that has already happened. */
.chip--past {
  background: var(--gray-100);
  color: var(--text-muted);
}

/* The next meeting up. Red as a small tinted chip, not a field. */
.chip--next {
  background: var(--surface-accent-tint);
  color: var(--red-700);
}

/* On a blue band. */
.chip--inverse {
  background: var(--blue-700);
  color: var(--lake-white);
}


/* =============================================================================
   7. SCHEDULE TABLE AND ROSTER
   ========================================================================== */

/* Wrap any table in <div class="table-wrap"> so a phone scrolls the table,
   not the page. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.schedule {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}

.schedule th {
  font: var(--type-label);
  font-size: var(--size-caption);
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0 var(--space-5) var(--space-3) var(--space-4);
  border-bottom: var(--border-thick) solid var(--border-strong);
  white-space: nowrap;
}

.schedule td {
  padding: var(--space-4) var(--space-5) var(--space-4) var(--space-4);
  border-bottom: var(--border-hairline) solid var(--border-default);
  vertical-align: middle;
}

.schedule th:last-child,
.schedule td:last-child {
  padding-right: var(--space-4);
}

/* The date column is mono. */
.schedule .schedule__date {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

/* Hard-coded state — this is a static site, nothing recomputes at runtime. */
.schedule tr.is-past td {
  color: var(--text-muted);
}

.schedule tr.is-next td {
  background: var(--surface-brand-tint);
  color: var(--text-body);
  font-weight: var(--weight-medium);
}

.schedule tr.is-next td:first-child {
  box-shadow: inset var(--border-logo) 0 0 0 var(--lake-red);
}

/* Board members: name plus role, nothing else. No avatar slot. */
.roster {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

/* Left red keyline, square on the keyline side — identical to .callout and
   .card--accent. Keep it on the LEFT, not the top: a horizontal 3px border lands
   on a fractional y and antialiases at both ends, so only one of its three rows
   is full-strength red and the bar reads visibly lighter than a vertical one.
   Every red keyline on this site is vertical for that reason. */
.person {
  background: var(--surface-card);
  border: var(--border-hairline) solid var(--border-default);
  border-left: var(--border-logo) solid var(--lake-red);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  box-shadow: var(--shadow-xs);
  padding: var(--pad-card);
}

.person__name {
  font-family: var(--font-display);
  font-weight: var(--weight-black);
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-tight);
  font-size: var(--size-h3);
  color: var(--text-heading);
  margin: 0 0 var(--space-2);
}

.person__role {
  font: var(--type-label);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  color: var(--red-600);
  margin: 0;
}


/* =============================================================================
   8. SITE HEADER AND NAVIGATION
   The nav is always in the DOM. Under 860px it only collapses once JS has added
   .has-js to <html>, so the site is fully navigable with JS switched off.
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--surface-brand);
  border-bottom: var(--border-logo) solid var(--lake-red);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: 78px;
}

/* ---- Brand lockup: the booster club gear mark plus the club name ---- */

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  flex-shrink: 1;
  min-width: 0;
}

/* The gear mark's ring type ("LAKE ROBOTICS BOOSTER CLUB") stops being legible
   below roughly 90px, so at header size the mark works as a recognition cue and
   the club name is set as live text beside it. The artwork's white background
   has been flood-filled to transparency, so it needs no white tile on blue. */
.brand__mark {
  display: block;
  height: 52px;
  width: auto;
  flex-shrink: 0;
}

.brand__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.brand__name {
  font-family: var(--font-display);
  font-weight: var(--weight-black);
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-tight);
  font-size: var(--size-h4);
  color: var(--lake-white);
}

.brand__meta {
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  font-size: var(--size-label);
  line-height: 1.2;
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  color: var(--blue-200);
}

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

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: var(--control-h-md);
  padding: 0 0 var(--space-1);
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  font-size: var(--size-body-sm);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--lake-white);
  border-bottom: var(--border-logo) solid transparent;
  transition: var(--transition-control);
}

.nav__link:hover {
  color: var(--lake-white);
  border-bottom-color: var(--action-accent-hover);
}

/* Current page: solid 3px red underline flush to the bottom of the item.
   Markup carries BOTH class="is-current" and aria-current="page". */
.nav__link.is-current,
.nav__link[aria-current="page"] {
  border-bottom-color: var(--lake-red);
}

/* The Join item in the header is a red button, not a plain link. */
.nav__join {
  flex-shrink: 0;
}

/* On join.html the button itself is the current page. It is already red, so
   the marker is a white keyline in the same 3px weight. */
.nav__join .btn.is-current,
.nav__join .btn[aria-current="page"] {
  box-shadow: inset 0 calc(-1 * var(--border-logo)) 0 0 var(--lake-white);
}

/* ---- Mobile toggle ---- */

/* Hidden by default. Revealed by the 860px block, and only when .has-js is set
   — with JS off there is nothing to toggle and the nav stays visible. */
.nav-toggle {
  display: none;
  align-items: center;
  min-height: var(--control-h-md);
  padding: 0 var(--space-4);
  background: transparent;
  border: var(--border-thick) solid var(--lake-white);
  border-radius: var(--radius-md);
  color: var(--lake-white);
  font-family: var(--font-sans);
  font-weight: var(--weight-bold);
  font-size: var(--size-body-sm);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  cursor: pointer;
  transition: var(--transition-control);
}

.nav-toggle:hover {
  background: var(--blue-700);
}


/* =============================================================================
   9. SITE FOOTER
   ========================================================================== */

.site-footer {
  background: var(--surface-brand-deep);
  color: var(--lake-white);
  padding-block: var(--section-pad-y-sm);
  border-top: var(--border-logo) solid var(--lake-red);
}

.footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr);
  gap: var(--space-10);
}

.footer__col > :last-child {
  margin-bottom: 0;
}

.footer__title {
  font: var(--type-label);
  font-size: var(--size-label);
  letter-spacing: var(--tracking-caps-wide);
  text-transform: uppercase;
  color: var(--blue-200);
  margin: 0 0 var(--space-4);
}

.footer__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.footer__text {
  color: var(--lake-white);
  max-width: 42ch;
  margin: 0 0 var(--space-3);
}

.footer__note {
  font-family: var(--font-mono);
  font-weight: var(--weight-medium);
  font-size: var(--size-body-sm);
  letter-spacing: var(--tracking-caps);
  color: var(--blue-200);
}

.footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* The contact/social list in column 1 follows the 501(c)(3) line rather than a
   .footer__title, so it needs the space that title would have supplied. */
.footer__legal + .footer__list {
  margin-top: var(--space-4);
}

.site-footer a {
  color: var(--lake-white);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

.site-footer a:hover {
  color: var(--red-300);
}

.footer__address {
  font-style: normal;
  line-height: var(--leading-body);
  color: var(--lake-white);
}

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-3) var(--space-6);
  margin-top: var(--space-10);
  padding-top: var(--space-5);
  border-top: var(--border-hairline) solid var(--blue-700);
}

.footer__legal {
  font-size: var(--size-caption);
  color: var(--blue-200);
  margin: 0;
}


/* =============================================================================
   10. STATES AND MOTION
   Hover on a filled button DARKENS one ramp step — never lightens, never
   changes opacity. Press moves down 1px, no scale. Focus is a 2px red ring.
   ========================================================================== */

/* ---- Hover: filled buttons darken one step ---- */
.btn--accent:hover  { background: var(--action-accent-hover);  border-color: var(--action-accent-hover);  color: var(--text-on-red); }
.btn--primary:hover { background: var(--action-primary-hover); border-color: var(--action-primary-hover); color: var(--text-on-blue); }
.btn--outline:hover { background: var(--surface-brand-tint);   border-color: var(--action-primary-hover); color: var(--action-primary-hover); }
.btn--inverse:hover { background: var(--blue-100);             border-color: var(--blue-100);             color: var(--blue-700); }

/* ---- Press: down by --press-translate, plus the -active ramp step ---- */
.btn:active {
  transform: translateY(var(--press-translate));
}

.btn--accent:active  { background: var(--action-accent-active);  border-color: var(--action-accent-active); }
.btn--primary:active { background: var(--action-primary-active); border-color: var(--action-primary-active); }
.btn--outline:active { background: var(--blue-100);              border-color: var(--action-primary-active); color: var(--action-primary-active); }
.btn--inverse:active { background: var(--blue-200);              border-color: var(--blue-200);              color: var(--blue-800); }

/* The hard offset block tucks in on press so the button looks pushed. */
.btn--feature:active {
  box-shadow: var(--shadow-hard-red-sm);
}

/* ---- Hover on a card: --shadow-sm to --shadow-md plus a 2px rise ---- */
.card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

/* Opt out for a card that is purely a container. */
.card--static:hover {
  box-shadow: var(--shadow-xs);
  transform: none;
}

a.card:active,
.card--interactive:active {
  transform: translateY(var(--press-translate));
  box-shadow: var(--shadow-sm);
}

/* ---- Hover on a link: blue to red, underline stays ---- */
/* base.css already does a:hover { color: var(--text-link-hover) }. This keeps
   the underline from disappearing on links inside prose. */
.prose a:hover,
.callout a:hover,
.card a:hover {
  color: var(--text-link-hover);
  text-decoration: underline;
}

/* ---- Focus: 2px solid red at 2px offset, on everything focusable ---- */
.btn:focus-visible,
.nav__link:focus-visible,
.nav-toggle:focus-visible,
.card:focus-visible,
.brand:focus-visible {
  outline: var(--border-thick) solid var(--focus-ring);
  outline-offset: 2px;
}

/* ---- Entrances: a fade plus a 6px rise. Nothing else, nowhere else. ---- */
.enter {
  animation: enter var(--duration-base) var(--ease-standard) both;
}

@keyframes enter {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ---- Reduced motion: drop every transform, keep opacity ---- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* The skip link is deliberately NOT in this list: translateY(-200%) is the
     only thing keeping it off-screen when it is not focused. Its transition is
     already neutralised by the duration override above, so the reveal is
     instant without the transform being cancelled. */
  .btn:active,
  .card:hover,
  a.card:active,
  .card--interactive:active {
    transform: none;
  }

  .enter {
    animation: enter-fade var(--duration-fast) linear both;
  }

  @keyframes enter-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* The mobile panel still fades; it just does not slide. */
  .has-js .site-nav {
    transform: none;
  }
}


/* =============================================================================
   11. RESPONSIVE
   Three breakpoints. Put new rules in the matching block.
   ========================================================================== */

/* ---- 860px: the nav collapses, two-column splits stack ------------------- */
@media (max-width: 860px) {

  .site-header__inner {
    min-height: 66px;
    gap: var(--space-4);
  }

  #main {
    scroll-margin-top: calc(66px + var(--space-4));
  }

  /* With JS off, .has-js is never set: the nav simply stacks under the lockup
     and every page stays reachable. */
  .site-header__inner {
    flex-wrap: wrap;
    padding-block: var(--space-3);
  }

  .site-nav {
    width: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
  }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .nav__link {
    min-height: var(--control-h-md);
    padding: var(--space-2) 0;
    border-bottom: var(--border-hairline) solid var(--blue-500);
  }

  /* The current-page marker stays a solid 3px red underline. */
  .nav__link.is-current,
  .nav__link[aria-current="page"] {
    border-bottom: var(--border-logo) solid var(--lake-red);
  }

  .nav__join {
    margin-top: var(--space-3);
  }

  .nav__join .btn {
    width: 100%;
  }

  /* With JS on, that stacked list becomes a toggled panel. */
  .has-js .nav-toggle {
    display: inline-flex;
  }

  .has-js .site-header__inner {
    flex-wrap: nowrap;
    padding-block: 0;
  }

  .has-js .site-nav {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    width: auto;
    z-index: var(--z-dropdown);
    padding: var(--space-5) var(--layout-gutter) var(--space-6);
    background: var(--surface-brand);
    border-bottom: var(--border-logo) solid var(--lake-red);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition:
      opacity var(--duration-base) var(--ease-standard),
      transform var(--duration-base) var(--ease-standard),
      visibility var(--duration-base) var(--ease-standard);
  }

  .has-js .site-nav.is-open {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  /* Layout */
  .split {
    grid-template-columns: 1fr;
    gap: var(--space-10);
  }

  .grid--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .footer__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-8);
  }
}

/* ---- 720px: tighter sections, grids stack -------------------------------- */
@media (max-width: 720px) {

  .band {
    padding-block: var(--space-10);
  }

  .hero {
    padding-block: calc(var(--space-10) + var(--space-3)) var(--space-10);
  }

  .grid--2,
  .grid--3,
  .grid--4 {
    grid-template-columns: 1fr;
  }

  .section-head {
    margin-bottom: var(--space-8);
  }

  .footer__grid {
    grid-template-columns: 1fr;
    gap: var(--space-8);
  }

  .roster {
    grid-template-columns: 1fr;
  }

  .stat__value {
    font-size: var(--size-h1);
  }
}

/* ---- 560px: tightest phone layout (tested down to 320px) ----------------- */
@media (max-width: 560px) {

  .shell {
    padding-inline: var(--space-4);
  }

  .has-js .site-nav {
    padding-inline: var(--space-4);
  }

  /* At 320px the lockup plus the toggle is wider than the viewport unless the
     lockup is allowed to give. The tile keeps its size; only the wordmark wraps. */
  .brand {
    flex-shrink: 1;
    min-width: 0;
  }

  .nav-toggle {
    padding: 0 var(--space-3);
  }

  .brand__mark {
    height: 38px;
  }

  .brand__name {
    font-size: var(--size-body);
  }

  .brand__meta {
    font-size: var(--size-caption);
    letter-spacing: var(--tracking-caps);
  }

  .card,
  .person {
    padding: var(--space-5);
  }

  .callout {
    padding: var(--space-4) var(--space-5);
  }

  /* Buttons go full width so nothing gets clipped at 320px. */
  .actions .btn {
    width: 100%;
  }

  .btn--lg {
    padding-inline: var(--space-5);
  }

  .schedule th,
  .schedule td {
    padding-inline: var(--space-3) var(--space-3);
  }

  .footer__bottom {
    margin-top: var(--space-8);
  }
}

/* =============================================================================
   12. BOARD PAGE (board.html)
   The roster cards lead with the role as the red eyebrow label and put the
   name underneath as the heading, which is the reverse of the source order the
   base .person rules assume. These two lines only move the spacing to match;
   no new class names, and nothing shared is restyled.
   ========================================================================== */

.person .person__role { margin-bottom: var(--space-2); }
.person > :last-child { margin-bottom: 0; }


/* =============================================================================
   13. MEETINGS PAGE (meetings.html)
   Three additions, all used only by meetings.html. Nothing here restyles a
   shared component — .schedule, .card, .chip and the band tones are consumed
   exactly as they ship above.
   ========================================================================== */

/* The address inside the "Where we meet" card. <address> defaults to italic,
   and italic is reserved for .lake-shout / .lake-sub, so reset it. */
.meetings-address {
  font-style: normal;
  line-height: var(--leading-body);
  margin: 0 0 var(--space-3);
}

/* Holds "Aug 31, 2026" together on one line once the 560px block below lets
   the rest of the date cell wrap. */
.meetings-date__text {
  white-space: nowrap;
}

@media (max-width: 560px) {

  /* At phone width the Day and Place columns come out. Every meeting is a
     Monday at the Lake Elementary Library, and both facts are stated above the
     table, so date and time are what is left — and they fit at 320px. The
     columns are dropped rather than left to scroll sideways. */
  .meetings-schedule th:nth-child(2),
  .meetings-schedule td:nth-child(2),
  .meetings-schedule th:nth-child(4),
  .meetings-schedule td:nth-child(4) {
    display: none;
  }

  /* Let the Past / Next chip drop below the date instead of widening the cell. */
  .meetings-schedule .schedule__date {
    white-space: normal;
  }
}

/* =============================================================================
   14. HOME PAGE (index.html) - page-specific, nothing else uses this.
   The hero shows the gear mark large enough that its ring type reads, which the
   52px header version cannot do. Transparent artwork, so no white tile.
   Everything else on the home page is built from the shared classes above.
   ========================================================================== */

.home-hero-mark {
  display: block;
  margin-bottom: var(--space-8);
  height: 150px;
  width: auto;
  max-width: 100%;
}

@media (max-width: 860px) {
  .home-hero-mark {
    height: 104px;
  }
}

@media (max-width: 560px) {
  .home-hero-mark {
    height: 72px;
  }
}
