@charset "UTF-8";
/* ==========================================================================
   UPSAC 2026 — University of Portsmouth Sub Aqua Club
   Mobile-first stylesheet. No frameworks, no jQuery, no Bootstrap.

   Structure of this file:
     1.  Design tokens
     2.  Reset & base elements
     3.  Layout primitives (.wrap, .band, .section)
     4.  Type helpers (eyebrow, section head)
     5.  Buttons & links
     6.  Site header / navigation
     7.  Hero
     8.  Notice strip
     9.  About
     10. Season timeline  <- signature element
     11. Qualified band
     12. Contact tiles
     13. Gallery + lightbox
     14. Documents
     15. Footer
     16. Sub-page (interior) styles
     17. Motion & reveal
     18. Print
   ========================================================================== */


/* ==========================================================================
   1. DESIGN TOKENS
   Palette is a depth gradient: surface light -> Solent green -> abyssal navy,
   with a high-visibility marker-buoy orange as the only warm accent.
   ========================================================================== */

:root {
  color-scheme: light;

  /* --- depth palette --- */
  --abyss:      #08192B;   /* deepest navy: hero veil, footer */
  --deep:       #0E2740;   /* dark bands */
  --deep-soft:  #17395B;   /* dark band gradient partner */
  --navy:       #273C75;   /* the club's existing brand navy: headings */
  --kelp:       #127C6B;   /* cold Solent green-teal: rules, dots, labels */
  --kelp-ink:   #0E6154;   /* AA-safe teal for body-size link text */
  --buoy:       #FF6B1A;   /* delayed surface marker buoy: CTAs, next-up */
  --buoy-ink:   #B84400;   /* AA-safe orange for body-size text on light */

  /* --- surfaces & ink --- */
  --surface:    #F5F8FA;   /* page background */
  --card:       #FFFFFF;
  --ink:        #0F2338;   /* body copy */
  --mist:       #55697E;   /* secondary copy, captions */
  --line:       #D9E3EB;   /* hairlines on light */
  --line-dark:  rgb(255 255 255 / 0.16);  /* hairlines on dark */

  /* --- typography ---
     Archivo (wide) for display, Public Sans for reading AND for every small
     uppercase label, IBM Plex Mono for dates and data only. Loaded from Google
     Fonts in the <head>; each falls back to a well-matched system stack.

     The mono rule is the one to hold the line on. It was written as "dates and
     data" from the start, but mono had drifted onto 23 selectors — it had become
     the universal small-label face, which is most of why the type system felt
     busy. It is now down to eight, and every one is a date, a number, a code or
     a username: .ev-when, .money, .detail, .total .label, .steps > li::before,
     .lb-count, .doc .kind and .tile .handle. Monospace on this site therefore
     *means* something. Before reaching for --font-mono on a
     new component, check the content is genuinely data; if it is a label, it
     wants --font-body at --fw-label with --track-caps. */
  --font-display: "Archivo", "Archivo Black", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body:    "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* fluid type scale — all clamp()ed so nothing needs a media query */
  --fs-hero:   clamp(2.5rem, 11vw, 6.75rem);
  --fs-h2:     clamp(1.75rem, 5.2vw, 3rem);
  --fs-h3:     clamp(1.2rem, 3.4vw, 1.6rem);
  --fs-lead:   clamp(1.05rem, 2.6vw, 1.3rem);
  --fs-body:   clamp(1rem, 0.96rem + 0.22vw, 1.125rem);
  --fs-small:  0.875rem;
  --fs-micro:  0.75rem;
  --fs-figure: clamp(1.35rem, 4.5vw, 1.75rem);  /* .total .amount, .options .fee */

  /* weight — four steps and no more: 400 reads, 600 labels, 800 heads, 900 is
     the hero and the two big money figures. */
  --fw-body:  400;
  --fw-label: 600;
  --fw-head:  800;
  --fw-hero:  900;

  /* tracking — capitals need letter-spacing, lower-case does not, and large
     capitals need it negative. The amount has to fall as the size rises:
     0.12em is right on a 12px badge and looks broken on a 19px heading, which
     is why there are two caps values rather than one. Lower-case text carries
     no letter-spacing declaration at all. */
  --track-display: -0.02em;  /* h1-h4, .hero-title */
  --track-caps:     0.12em;  /* uppercase at --fs-micro */
  --track-caps-lg:  0.04em;  /* uppercase at --fs-small and above */
  --track-hero:     0.3em;   /* .hero-eyebrow and .hero-scroll only */

  /* --- space, radius, shadow, motion --- */
  --gap:        clamp(1rem, 3vw, 1.75rem);
  --pad-section: clamp(3.25rem, 8vw, 6.5rem);
  --wrap:       min(100% - 2rem, 1200px);
  --wrap-text:  min(100% - 2rem, 70ch);

  --r-sm: 6px;
  --r:    12px;
  --r-lg: 20px;
  --r-pill: 999px;

  --shadow-1: 0 1px 2px rgb(8 25 43 / 0.06), 0 2px 8px rgb(8 25 43 / 0.05);
  --shadow-2: 0 2px 6px rgb(8 25 43 / 0.07), 0 12px 32px rgb(8 25 43 / 0.09);
  --shadow-3: 0 24px 60px rgb(8 25 43 / 0.28);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 260ms;

  --nav-h: 60px;
}

@media (min-width: 1000px) {
  :root { --nav-h: 72px; }
}


/* ==========================================================================
   2. RESET & BASE
   ========================================================================== */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* offset in-page anchors so the sticky header never covers a heading */
  scroll-padding-top: calc(var(--nav-h) + 12px);
}

body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--ink);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  /* Insurance for narrow phones: a long unbroken string (an email address, a
     pasted URL, a word nobody thought about) breaks rather than pushing the
     page sideways. break-word rather than anywhere, so normal prose still
     wraps at spaces first. */
  overflow-wrap: break-word;
}

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

button, input, select, textarea { font: inherit; color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--fw-head);
  line-height: 1.08;
  letter-spacing: var(--track-display);
  text-wrap: balance;
  color: var(--navy);
}

/* Archivo carries a width axis; widen the display face so the caps read like
   hull lettering rather than a default grotesque. Ignored on the fallback. */
@supports (font-variation-settings: "wdth" 115) {
  h1, h2, h3, .btn, .nav-link, .hero-title { font-variation-settings: "wdth" 112; }
}

p { text-wrap: pretty; }

/* The UA default for <b>/<strong> is 700, which would be a fifth weight the
   type system never chose — and would force the font request to carry a weight
   nothing declares. Pull inline bold to the label step so the four --fw-*
   values are the whole set. .notice b and .offer b set their own and win on
   specificity. */
b, strong { font-weight: var(--fw-label); }

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

ul, ol { padding-left: 1.25em; }
li + li { margin-top: 0.4em; }

hr { border: 0; border-top: 1px solid var(--line); margin-block: 2rem; }

/* Visible keyboard focus everywhere — never remove without replacing. */
:focus-visible {
  outline: 3px solid var(--buoy);
  outline-offset: 3px;
  border-radius: 2px;
}

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

/* Skip link */
.skip {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -120%);
  z-index: 200;
  padding: 0.7rem 1.2rem;
  background: var(--buoy);
  color: var(--abyss);
  font-weight: var(--fw-label);
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  transition: transform var(--dur) var(--ease);
}
.skip:focus { transform: translate(-50%, 0); }


/* ==========================================================================
   3. LAYOUT PRIMITIVES
   One padding rule for every section, so nothing fights over margins.
   ========================================================================== */

.wrap      { width: var(--wrap); margin-inline: auto; }
.wrap-text { width: var(--wrap-text); margin-inline: auto; }

.section { padding-block: var(--pad-section); }

/* Dark bands: a descent from mid navy to abyss as you go down the page. */
.band-dark {
  background: linear-gradient(165deg, var(--deep-soft) 0%, var(--deep) 45%, var(--abyss) 100%);
  color: #E8F0F7;
}
.band-dark h2, .band-dark h3, .band-dark h4 { color: #FFFFFF; }
.band-dark a { color: #FFC9A3; }
.band-dark a:hover { color: #FFFFFF; }
.band-dark .lead, .band-dark p { color: #CBDAE8; }

.band-deep { background: var(--abyss); color: #E8F0F7; }


/* ==========================================================================
   4. TYPE HELPERS
   ========================================================================== */

/* Small mono label above a heading. Used to name the section, never decorative. */
.eyebrow {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--kelp);
  margin-bottom: 0.6rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: var(--buoy);
  flex: none;
}
.band-dark .eyebrow { color: #7FD8C6; }

.section-head { margin-bottom: clamp(1.75rem, 5vw, 3rem); }
.section-head h2 { font-size: var(--fs-h2); text-transform: uppercase; }
.section-head .lead { margin-top: 0.85rem; font-size: var(--fs-lead); color: var(--mist); max-width: 62ch; }

.center { text-align: center; }
.center .eyebrow { justify-content: center; }
.center .lead { margin-inline: auto; }


/* ==========================================================================
   5. BUTTONS
   Orange fill with near-black ink — far higher contrast than white on orange.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 48px;                 /* comfortable thumb target */
  padding: 0.75rem 1.5rem;
  font-family: var(--font-display);
  font-weight: var(--fw-head);
  font-size: var(--fs-small);
  letter-spacing: var(--track-caps-lg);
  text-transform: uppercase;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: transform var(--dur) var(--ease), background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn-primary { background: var(--buoy); color: var(--abyss); }
.btn-primary:hover { background: #FF8340; color: var(--abyss); }

.btn-ghost { background: transparent; color: #FFFFFF; border-color: rgb(255 255 255 / 0.55); }
.btn-ghost:hover { background: rgb(255 255 255 / 0.12); border-color: #FFFFFF; color: #FFFFFF; }

.btn-line { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn-line:hover { background: var(--navy); color: #FFFFFF; }

.btn svg { width: 1.1em; height: 1.1em; flex: none; }


/* ==========================================================================
   6. SITE HEADER / NAVIGATION
   Transparent over the hero, solid once you scroll past it.
   ========================================================================== */

.site-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  padding-inline: max(1rem, env(safe-area-inset-left)) max(1rem, env(safe-area-inset-right));
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease);
}

/* The bar's background and frosted blur live on a pseudo-element, NOT on
   .site-head itself. This is load-bearing, not tidiness: per the Filter
   Effects spec, a backdrop-filter (or filter) other than none makes an element
   the containing block for its position: fixed descendants. .nav-panel is a
   fixed child of .site-head, so putting the blur on the header collapsed the
   open mobile menu to the 60px height of the bar the instant .is-stuck was
   applied on scroll — you could see the first item and nothing else. A
   ::before is a child, not an ancestor, so the panel keeps resolving its
   insets against the viewport and stays full-screen. Same look, no trap.
   Negative z-index paints it above the header's own background but beneath
   the brand and the burger (CSS 2.1 Appendix E, steps 1-2 vs 5-6). */
.site-head::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: transparent;
  transition: background-color var(--dur) var(--ease),
              -webkit-backdrop-filter var(--dur) var(--ease),
              backdrop-filter var(--dur) var(--ease);
}
.site-head.is-stuck::before {
  background: rgb(8 25 43 / 0.92);
  -webkit-backdrop-filter: saturate(150%) blur(12px);
  backdrop-filter: saturate(150%) blur(12px);
}
.site-head.is-stuck { border-bottom-color: var(--line-dark); }

/* Interior pages have no hero, so the bar is solid from the start. */
.site-head.is-solid::before { background: var(--abyss); }
.site-head.is-solid { border-bottom-color: var(--line-dark); }

/* While the menu is open the bar must be opaque, or the top 60px shows hero
   photo through it while the panel below it is solid navy. */
.site-head.is-menu-open::before {
  background: var(--abyss);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.site-head.is-menu-open { border-bottom-color: var(--line-dark); }

.site-head .brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-right: auto;
  text-decoration: none;
  color: #FFFFFF;
}
.brand img { height: 30px; width: auto; }
.brand-text {
  font-family: var(--font-display);
  font-weight: var(--fw-head);
  font-size: var(--fs-body);
  line-height: 1;
}
.brand-text small {
  display: block;
  font-family: var(--font-body);
  font-weight: var(--fw-label);
  font-size: 0.625rem;
  /* The full club name is 38 characters against 19 for the old "Portsmouth Sub
     Aqua". This was 8px, because in mono 38 characters ran 219px against roughly
     179px of room beside the burger on a 320px phone. Public Sans fixed that
     without a size change: mono bills a flat 0.6em for every glyph including
     "i" and "l", whereas this string averages 0.477em proportionally, so it is
     17% narrower for free. That paid for 10px, which is above the point where
     the name stops being readable at arm's length. At 320px it still wraps, and
     it should: line-height 1.35 stops two lines touching (it was inheriting
     line-height: 1 from .brand-text, fine while it was always one line) and
     text-wrap: balance splits it evenly rather than stranding "Aqua Club". Two
     10px lines stack to ~27px, so the block is ~48px inside the 60px bar. By
     360px the 227px string fits one line unaided. */
  letter-spacing: var(--track-caps);
  line-height: 1.35;
  text-wrap: balance;
  opacity: 0.75;
  margin-top: 3px;
}

/* B3: 10px is the phone value, and it only has to be that small below ~340px.
   Public Sans is 17% narrower than mono on this string (mono charges a flat
   0.6em for every "i" and "l"; the mixed-case average here is 0.477em), so
   38 characters run 227px instead of 274px and reach one line by 360px.
   From 700px there is room for --fs-micro, which retires the sub-legible
   step from the scale everywhere it was avoidable. */
@media (min-width: 700px) { .brand-text small { font-size: var(--fs-micro); } }

/* --- burger --- */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  background: transparent;
  border: 1px solid rgb(255 255 255 / 0.35);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.nav-toggle span {
  position: relative;
  display: block;
  width: 20px; height: 2px;
  background: #FFFFFF;
  transition: transform var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.nav-toggle span::before,
.nav-toggle span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 20px; height: 2px;
  background: #FFFFFF;
  transition: transform var(--dur) var(--ease), top var(--dur) var(--ease);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { top: 0; transform: rotate(-45deg); }

/* --- mobile: full-screen overlay menu --- */
.nav-panel {
  position: fixed;
  top: var(--nav-h);
  left: 0;
  right: 0;
  /* The height is an explicit length, NOT the leftover space between a top and
     a bottom inset. That distinction is the whole fix. Written as
     `inset: var(--nav-h) 0 0 0` the panel's height is whatever room is left
     inside its containing block, so anything that quietly turns an ancestor
     into that containing block — a filter, backdrop-filter, transform,
     perspective, contain or will-change, see the .site-head::before note
     above — squeezes it down to the height of the bar and you see the first
     menu item and nothing else. An explicit height cannot be squeezed by an
     ancestor, so the menu stays usable no matter which box it resolves
     against. vh first as the fallback for older browsers, then svh, which is
     the viewport height with the mobile URL bar showing: that way the bottom
     of the list is never stranded behind browser chrome. */
  height: calc(100vh - var(--nav-h));
  height: calc(100svh - var(--nav-h));
  z-index: 99;
  display: grid;
  align-content: start;
  gap: 0.25rem;
  padding: 1.5rem max(1.25rem, env(safe-area-inset-left)) 3rem;
  background: var(--abyss);
  overflow-y: auto;
  overscroll-behavior: contain;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur);
}
.nav-panel.is-open { opacity: 1; visibility: visible; transform: none; }

.nav-link {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  padding: 0.85rem 0.25rem;
  font-family: var(--font-display);
  font-weight: var(--fw-head);
  font-size: 1.25rem;
  letter-spacing: var(--track-caps-lg);
  text-transform: uppercase;
  text-decoration: none;
  color: #FFFFFF;
  border-bottom: 1px solid var(--line-dark);
}
.nav-link .n {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  color: var(--kelp);
  letter-spacing: var(--track-caps);
  flex: none;
}
.nav-link:hover, .nav-link[aria-current="true"] { color: var(--buoy); }
.nav-link:hover .n, .nav-link[aria-current="true"] .n { color: var(--buoy); }

/* --- desktop: inline nav --- */
@media (min-width: 1000px) {
  .nav-toggle { display: none; }

  .nav-panel {
    position: static;
    /* Every geometry property the mobile overlay sets has to be undone here,
       individually. Miss the height and the desktop nav becomes a full-height
       navy column down the side of the page instead of a row of links in the
       bar. */
    top: auto;
    left: auto;
    right: auto;
    height: auto;
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0;
    background: transparent;
    overflow: visible;
    opacity: 1;
    visibility: visible;
    transform: none;
  }
  .nav-link {
    display: block;
    padding: 0.5rem 0.7rem;
    font-size: var(--fs-micro);
    border-bottom: 0;
    border-radius: var(--r-sm);
    white-space: nowrap;
  }
  .nav-link .n { display: none; }
  .nav-link:hover { background: rgb(255 255 255 / 0.1); color: #FFFFFF; }
  .nav-link[aria-current="true"] { color: var(--buoy); }
}

@media (min-width: 1180px) {
  .nav-link { padding-inline: 0.9rem; }
}


/* ==========================================================================
   7. HERO
   Crossfading dive photography, held down by a gradient veil so the type
   stays legible whichever photo is showing.
   ========================================================================== */

.hero {
  position: relative;
  min-height: 100svh;          /* svh keeps mobile browser chrome from jumping */
  min-height: 100vh;           /* fallback first, svh wins where supported */
  display: grid;
  align-items: end;
  overflow: hidden;
  background: var(--abyss);
  isolation: isolate;
}
@supports (min-height: 100svh) { .hero { min-height: 100svh; } }

.hero-media { position: absolute; inset: 0; z-index: -2; }

.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 45%;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 1500ms var(--ease), transform 9000ms linear;
}
.hero-slide.is-active { opacity: 1; transform: scale(1); }

.hero-veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg,
      rgb(8 25 43 / 0.78) 0%,
      rgb(8 25 43 / 0.30) 32%,
      rgb(8 25 43 / 0.52) 66%,
      rgb(8 25 43 / 0.94) 100%);
}

.hero-inner {
  width: var(--wrap);
  margin-inline: auto;
  padding-block: clamp(2.5rem, 12vh, 6rem) clamp(4.5rem, 14vh, 7rem);
  color: #FFFFFF;
  text-align: center;
}
.hero-mark {
  width: clamp(72px, 20vw, 132px);
  margin: 0 auto clamp(1rem, 3vw, 1.75rem);
  filter: drop-shadow(0 4px 18px rgb(0 0 0 / 0.45));
}
/* Sits inside the h1 so the heading reads as the club's full name, but is
   set as a quiet mono kicker rather than part of the display line. */
.hero-eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: clamp(0.6875rem, 2.4vw, 0.9375rem);
  font-weight: var(--fw-label);
  line-height: 1.3;
  letter-spacing: var(--track-hero);
  text-transform: uppercase;
  text-shadow: none;
  color: #A7E8DA;
  margin-bottom: 0.5rem;
}
.hero-title {
  font-size: var(--fs-hero);
  font-weight: var(--fw-hero);
  line-height: 0.9;
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  color: #FFFFFF;
  text-shadow: 0 4px 30px rgb(0 0 0 / 0.4);
}
.hero-rotator {
  min-height: 1.9em;                /* reserve the line so nothing reflows */
  margin-top: clamp(0.75rem, 2.5vw, 1.25rem);
  font-size: clamp(1rem, 3.6vw, 1.5rem);
  font-weight: var(--fw-body);
  color: #FFFFFF;
}
.hero-rotator .cursor {
  display: inline-block;
  width: 2px;
  height: 1.05em;
  margin-left: 3px;
  background: var(--buoy);
  vertical-align: -0.14em;
  animation: blink 1.1s steps(2, start) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: clamp(1.5rem, 4vw, 2.25rem);
}

/* --- slide controls --- */
.hero-dots {
  position: absolute;
  left: 50%;
  bottom: calc(1.5rem + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  gap: 0.5rem;
  z-index: 3;
}
.hero-dots button {
  width: 36px; height: 4px;
  padding: 0;
  background: rgb(255 255 255 / 0.35);
  border: 0;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease);
}
.hero-dots button[aria-current="true"] { background: var(--buoy); }
.hero-dots button:hover { background: rgb(255 255 255 / 0.7); }

.hero-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  display: none;                    /* pointer-only affordance */
  place-items: center;
  width: 48px; height: 48px;
  background: rgb(8 25 43 / 0.4);
  border: 1px solid rgb(255 255 255 / 0.3);
  border-radius: 50%;
  color: #FFFFFF;
  cursor: pointer;
}
.hero-arrow:hover { background: rgb(8 25 43 / 0.75); }
.hero-arrow.prev { left: clamp(0.75rem, 2vw, 2rem); }
.hero-arrow.next { right: clamp(0.75rem, 2vw, 2rem); }
@media (hover: hover) and (min-width: 780px) { .hero-arrow { display: grid; } }

.hero-scroll {
  position: absolute;
  left: 50%;
  bottom: calc(3.25rem + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 3;
  font-family: var(--font-body);
  font-weight: var(--fw-label);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-hero);
  text-transform: uppercase;
  text-decoration: none;
  color: rgb(255 255 255 / 0.8);
  display: none;
}
/* Showing the cue and reserving room for it are the same decision, so both
   declarations live in one query and cannot drift apart. The cue is absolutely
   positioned against the hero's bottom edge and occupies 105.8px of it: a
   3.25rem offset, a 12px label at the inherited line-height 1.65, an 8px gap
   and a 26px rule. `.hero-inner`'s own bottom padding was clamp(4.5rem, 14vh,
   7rem) — only 86.8px at a 620px-tall viewport — so "Scroll down" climbed up
   into the two CTA pills anywhere between 620px and 756px of viewport height,
   by as much as 19px. Worse, the cue adds env(safe-area-inset-bottom) to its
   offset and that padding did not, so with viewport-fit=cover (which
   index-2026.html sets) it overlapped on a home-indicator iPhone at *every*
   height, tall ones included.
   7.75rem = 124px leaves 18px of clearance, and it is deliberately a flat
   length: this query resolves against the large viewport while `.hero`'s
   min-height resolves against svh, so the old 14vh and 100svh were measuring
   two different things. Keep this >= 7rem. */
@media (min-height: 620px) {
  .hero-scroll { display: block; }
  /* 0px fallback spelled out: if this one declaration were ever dropped as
     invalid the overlap comes straight back, unlike the cosmetic env() uses
     on .hero-dots and .hero-scroll above. */
  .hero-inner  { padding-bottom: calc(7.75rem + env(safe-area-inset-bottom, 0px)); }
}
.hero-scroll:hover { color: #FFFFFF; }
.hero-scroll span {
  display: block;
  width: 1px; height: 26px;
  margin: 0.5rem auto 0;
  background: linear-gradient(180deg, var(--buoy), transparent);
  animation: sink 2.1s var(--ease) infinite;
}
@keyframes sink {
  0%   { transform: scaleY(0.2); transform-origin: top; opacity: 0; }
  40%  { transform: scaleY(1);   transform-origin: top; opacity: 1; }
  100% { transform: scaleY(1);   transform-origin: bottom; opacity: 0; }
}


/* ==========================================================================
   8. NOTICE STRIP
   The club's "last updated / watch this space" message.
   ========================================================================== */

.notice {
  background: var(--buoy);
  color: var(--abyss);
  padding-block: 0.85rem;
}
.notice .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.35rem 0.85rem;
  text-align: center;
}
.notice b {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}
.notice p { font-size: var(--fs-small); font-weight: var(--fw-label); }


/* ==========================================================================
   9. ABOUT
   ========================================================================== */

.about-grid { display: grid; gap: var(--gap); }

@media (min-width: 860px) {
  .about-grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: clamp(2rem, 4vw, 3.5rem);
    align-items: start;
  }
  /* sticky portrait on wide screens, so the photo travels with the copy */
  .about-figure { position: sticky; top: calc(var(--nav-h) + 1.5rem); }
}

.about-figure { margin: 0; }
.about-figure img {
  width: 100%;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  aspect-ratio: 3 / 4;
  object-fit: cover;
}
.about-figure figcaption {
  margin-top: 0.7rem;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  color: var(--mist);
}

.about-body > * + * { margin-top: 1.05rem; }
.about-body .lead {
  font-size: var(--fs-lead);
  font-weight: var(--fw-body);
  color: var(--ink);
}

/* What the club offers — four plain rows, not decorative cards. */
.offer {
  list-style: none;
  padding: 0;
  margin-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.offer li {
  margin: 0;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--line);
  display: grid;
  grid-template-columns: 1.6rem 1fr;
  gap: 0.9rem;
  align-items: start;
}
.offer svg { width: 1.5rem; height: 1.5rem; color: var(--kelp); margin-top: 0.15rem; }
.offer b { display: block; color: var(--navy); font-family: var(--font-display); font-weight: var(--fw-head); }
.offer span { color: var(--mist); font-size: var(--fs-small); }


/* ==========================================================================
   10. SEASON TIMELINE  — the signature element
   The club year runs down a rail that fades from surface-teal to deep navy.
   Events past their date dim automatically; the next one gets the buoy.
   ========================================================================== */

.season {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.5rem);
}
.season > li { margin: 0; }

.ev {
  position: relative;
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: 0 1rem;
}
@media (min-width: 700px) {
  .ev { grid-template-columns: 3.5rem minmax(0, 1fr); gap: 0 1.5rem; }
}

/* --- the rail --- */
.ev-rail { position: relative; }
.ev-rail::before {
  content: "";
  position: absolute;
  top: 0; bottom: calc(-1 * clamp(1rem, 2.5vw, 1.5rem));
  left: 50%;
  width: 2px;
  margin-left: -1px;
  background: var(--line);
}
.ev:last-child .ev-rail::before { bottom: auto; height: 2rem; }

.ev-dot {
  position: absolute;
  top: 1.65rem;
  left: 50%;
  width: 14px; height: 14px;
  margin-left: -7px;
  border-radius: 50%;
  background: var(--card);
  border: 3px solid var(--kelp);
  z-index: 1;
}

/* --- the card --- */
.ev-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.ev-card:hover { box-shadow: var(--shadow-2); }

.ev-text { padding: clamp(1.1rem, 3vw, 1.6rem); }

.ev-when {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--kelp);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.ev-title { font-size: var(--fs-h3); margin-bottom: 0.6rem; }
.ev-where {
  font-weight: var(--fw-label);
  color: var(--ink);
  margin-bottom: 0.5rem;
}
.ev-text p { font-size: var(--fs-small); color: var(--mist); }
.ev-text p + p { margin-top: 0.5rem; }
.ev-text ul { font-size: var(--fs-small); color: var(--mist); margin-top: 0.5rem; }
.ev-text .btn { margin-top: 1rem; }

.ev-media { display: block; }
.ev-media img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-top: 1px solid var(--line);
}
/* Posters carry their own layout, so show them whole rather than cropped. */
.ev-media.is-poster img {
  aspect-ratio: auto;
  object-fit: contain;
  background: #F0F4F7;
  max-height: 420px;
}

/* On wide screens the card splits: copy left, photo right. */
@media (min-width: 880px) {
  .ev-card.has-media { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
  .ev-card.has-media .ev-media img {
    height: 100%;
    min-height: 260px;
    aspect-ratio: auto;
    border-top: 0;
    border-left: 1px solid var(--line);
  }
  .ev-card.has-media .ev-media.is-poster img { max-height: none; }
}

/* --- status chips --- */
.chip {
  display: inline-block;
  padding: 0.2rem 0.55rem;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  white-space: nowrap;
}
.chip-next   { background: var(--buoy); color: var(--abyss); }
.chip-weekly { background: #E1F0ED; color: var(--kelp-ink); }
.chip-tbc    { background: #EDF1F5; color: var(--mist); }
.chip-past   { background: #EDF1F5; color: var(--mist); }

/* --- next up --- */
.ev.is-next .ev-dot {
  border-color: var(--buoy);
  background: var(--buoy);
  box-shadow: 0 0 0 6px rgb(255 107 26 / 0.18);
}
.ev.is-next .ev-card { border-color: var(--buoy); box-shadow: var(--shadow-2); }
.ev.is-next .ev-when { color: var(--buoy-ink); }

/* --- already happened: dim, but still readable and still there --- */
.ev.is-past .ev-card { background: #FBFCFD; box-shadow: none; }
.ev.is-past .ev-dot { border-color: var(--line); background: var(--line); }
.ev.is-past .ev-text { opacity: 0.62; }
.ev.is-past .ev-media img { filter: grayscale(1); opacity: 0.5; }

/* Weekly standing item reads as the anchor of the season. */
.ev.is-standing .ev-dot { border-color: var(--kelp); background: var(--kelp); }
.ev.is-standing .ev-card { border-left: 3px solid var(--kelp); }


/* ==========================================================================
   11. QUALIFIED BAND
   ========================================================================== */

.officers {
  list-style: none;
  padding: 0;
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  display: grid;
  gap: 1rem;
}
@media (min-width: 720px) { .officers { grid-template-columns: repeat(3, 1fr); } }

.officers li {
  margin: 0;
  padding: 1.25rem;
  background: rgb(255 255 255 / 0.06);
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
}
.officers .role {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: #7FD8C6;
  margin-bottom: 0.35rem;
}
.officers .who {
  font-family: var(--font-display);
  font-weight: var(--fw-head);
  font-size: var(--fs-lead);
  color: #FFFFFF;
}
.officers .what { font-size: var(--fs-small); color: #B7CADB; margin-top: 0.3rem; }


/* ==========================================================================
   12. CONTACT TILES
   ========================================================================== */

.tiles {
  display: grid;
  gap: var(--gap);
  grid-template-columns: 1fr;
}
@media (min-width: 620px)  { .tiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .tiles { grid-template-columns: repeat(4, 1fr); } }

.tile {
  display: flex;
  flex-direction: column;
  padding: clamp(1.25rem, 3vw, 1.75rem);
  background: rgb(255 255 255 / 0.06);
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
  transition: background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.tile:hover { background: rgb(255 255 255 / 0.11); transform: translateY(-3px); }

.tile-icon {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  margin-bottom: 1rem;
  border-radius: var(--r-sm);
  background: rgb(255 107 26 / 0.16);
  color: var(--buoy);
}
.tile-icon svg { width: 24px; height: 24px; }

.tile h3 { font-size: var(--fs-lead); text-transform: uppercase; letter-spacing: var(--track-caps-lg); }
.tile p { font-size: var(--fs-small); color: #B7CADB; margin-top: 0.5rem; }
.tile .handle {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: #FFFFFF;
  margin-top: 0.5rem;
}
.tile-links { margin-top: auto; padding-top: 1rem; display: grid; gap: 0.4rem; justify-items: start; }
.tile-links a { font-size: var(--fs-small); font-weight: var(--fw-label); }


/* ==========================================================================
   13. GALLERY + LIGHTBOX
   ========================================================================== */

.filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: clamp(1.5rem, 4vw, 2.25rem);
}
.filter-btn {
  min-height: 42px;
  padding: 0.5rem 1.1rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--mist);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.filter-btn:hover { border-color: var(--kelp); color: var(--kelp-ink); }
.filter-btn[aria-pressed="true"] {
  background: var(--navy);
  border-color: var(--navy);
  color: #FFFFFF;
}
.filter-btn .count { opacity: 0.65; margin-left: 0.35rem; }

.grid-gallery {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 0.5rem;
}
@media (min-width: 700px)  { .grid-gallery { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 0.75rem; } }
@media (min-width: 1100px) { .grid-gallery { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); } }

.grid-gallery > li { margin: 0; }
.grid-gallery [hidden] { display: none; }

.shot {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: #DCE5EC;
  cursor: zoom-in;
  aspect-ratio: 1;
}
.shot img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 500ms var(--ease), filter var(--dur) var(--ease);
}
.shot:hover img { transform: scale(1.06); }

/* play badge on video thumbnails */
.shot.is-video::after {
  content: "";
  position: absolute;
  inset: 50% auto auto 50%;
  translate: -50% -50%;
  width: 46px; height: 46px;
  border-radius: 50%;
  background: rgb(8 25 43 / 0.6) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E") no-repeat 55% 50% / 20px 20px;
  border: 2px solid rgb(255 255 255 / 0.85);
  transition: background-color var(--dur) var(--ease);
}
.shot.is-video:hover::after { background-color: var(--buoy); }

.gallery-empty {
  text-align: center;
  color: var(--mist);
  padding-block: 3rem;
}

/* --- lightbox (native <dialog>) --- */
.lightbox {
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  padding: 0;
  border: 0;
  background: rgb(8 25 43 / 0.97);
  color: #FFFFFF;
}
.lightbox::backdrop { background: rgb(8 25 43 / 0.9); }
.lightbox[open] { display: grid; grid-template-rows: auto 1fr auto; }

.lb-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.85rem max(1rem, env(safe-area-inset-left));
  border-bottom: 1px solid var(--line-dark);
}
.lb-count {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--track-caps);
  color: #B7CADB;
  margin-right: auto;
}
.lb-btn {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  background: rgb(255 255 255 / 0.1);
  border: 1px solid var(--line-dark);
  border-radius: var(--r-sm);
  color: #FFFFFF;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease);
}
.lb-btn:hover { background: var(--buoy); color: var(--abyss); border-color: var(--buoy); }
.lb-btn svg { width: 20px; height: 20px; }

.lb-stage {
  display: grid;
  place-items: center;
  padding: 1rem;
  min-height: 0;
}
.lb-stage img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-3);
}
.lb-stage iframe {
  width: 100%;
  max-width: 1100px;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-3);
}
.lb-nav {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  padding: 0.85rem 1rem calc(0.85rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line-dark);
}


/* ==========================================================================
   14. DOCUMENTS
   ========================================================================== */

.docs { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.6rem; }
.docs > li { margin: 0; }

.doc {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.9rem;
  min-height: 56px;
  padding: 0.9rem 1.1rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r);
  text-decoration: none;
  color: var(--ink);
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.doc:hover {
  border-color: var(--kelp);
  transform: translateX(3px);
  box-shadow: var(--shadow-1);
  color: var(--ink);
}
.doc .kind {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: var(--fw-label);
  letter-spacing: var(--track-caps);
  padding: 0.25rem 0.45rem;
  border-radius: var(--r-sm);
  background: #E1F0ED;
  color: var(--kelp-ink);
}
.doc .kind.pdf { background: #FDE8DF; color: var(--buoy-ink); }
.doc .name { font-weight: var(--fw-label); }
.doc .name small { display: block; font-weight: var(--fw-body); font-size: var(--fs-small); color: var(--mist); }
.doc .go { color: var(--kelp); display: grid; place-items: center; }
.doc .go svg { width: 20px; height: 20px; }


/* ==========================================================================
   15. FOOTER
   ========================================================================== */

.site-foot {
  padding-block: clamp(2.5rem, 6vw, 4rem) calc(clamp(2rem, 5vw, 3rem) + env(safe-area-inset-bottom));
  text-align: center;
}
.foot-mark { width: 84px; margin: 0 auto 1.5rem; }
.foot-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.5rem;
  margin-bottom: 1.75rem;
  list-style: none;
  padding: 0;
}
.foot-links li { margin: 0; }
.foot-links a {
  font-family: var(--font-body);
  font-weight: var(--fw-label);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  color: #B7CADB;
}
.foot-links a:hover { color: var(--buoy); }

.foot-meta { font-size: var(--fs-small); color: #8FA6BB; }
.foot-meta p + p { margin-top: 0.4rem; }
.foot-badges {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 1.5rem;
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line-dark);
}
.foot-badges img { height: 42px; width: auto; opacity: 0.9; }

/* The BSAC mark is navy on transparent, so it needs a white plate to be
   visible against the dark footer. */
.foot-badges .plate {
  display: grid;
  place-items: center;
  padding: 0.55rem 0.9rem;
  background: #FFFFFF;
  border-radius: var(--r-sm);
}
.foot-badges .plate img { opacity: 1; }


/* ==========================================================================
   16. SUB-PAGE (INTERIOR) STYLES
   Used by the calendar, pub games and membership pages.
   ========================================================================== */

.page-head {
  padding-top: calc(var(--nav-h) + clamp(2rem, 6vw, 3.5rem));
  padding-bottom: clamp(2rem, 6vw, 3.5rem);
}
.page-head h1 { font-size: var(--fs-h2); text-transform: uppercase; }
.page-head .lead { margin-top: 0.9rem; font-size: var(--fs-lead); color: #CBDAE8; max-width: 62ch; }

.back {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
  font-family: var(--font-body);
  font-weight: var(--fw-label);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  color: #7FD8C6;
}
.back:hover { color: var(--buoy); }
.back svg { width: 1rem; height: 1rem; }

/* A panel of prose — pub game rules, membership steps. */
.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: clamp(1.25rem, 4vw, 2.5rem);
}
.panel + .panel { margin-top: var(--gap); }
.panel > * + * { margin-top: 1rem; }
.panel h2 { font-size: var(--fs-h3); }
.panel h3 {
  font-size: var(--fs-lead);
  text-transform: uppercase;
  letter-spacing: var(--track-caps-lg);
  color: var(--kelp-ink);
  margin-top: 1.75rem;
}
.panel img { border-radius: var(--r); margin-top: 1.25rem; }
.panel figure { margin: 1.5rem 0 0; }
.panel figure img { margin-top: 0; border: 1px solid var(--line); }
.panel figcaption {
  margin-top: 0.6rem;
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  color: var(--mist);
}
.panel ul, .panel ol { color: var(--ink); }
.panel ul ul { margin-top: 0.4em; color: var(--mist); font-size: var(--fs-small); }

/* Money / bank details — mono so digits line up and can't be misread. */
.money {
  font-family: var(--font-mono);
  font-weight: var(--fw-label);
  color: var(--buoy-ink);
}
.detail {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  background: #EDF3F7;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 0.15rem 0.4rem;
  white-space: nowrap;
}
.callout {
  border-left: 3px solid var(--buoy);
  background: #FFF6F0;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 0.9rem 1.1rem;
  font-size: var(--fs-small);
}
.callout b { color: var(--buoy-ink); }

/* Fee summary line */
.total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.85rem;
  padding: 1rem 1.25rem;
  background: var(--deep);
  color: #FFFFFF;
  border-radius: var(--r);
}
.total .amount {
  font-family: var(--font-display);
  font-weight: var(--fw-hero);
  font-size: var(--fs-figure);
  color: var(--buoy);
  line-height: 1;
}
.total .label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: #B7CADB;
}

/* Numbered steps — used where the content really is a sequence. */
.steps { list-style: none; padding: 0; counter-reset: step; display: grid; gap: 1rem; }
.steps > li {
  margin: 0;
  counter-increment: step;
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
}
.steps > li::before {
  content: counter(step);
  display: grid;
  place-items: center;
  width: 2.25rem; height: 2.25rem;
  border-radius: 50%;
  background: var(--navy);
  color: #FFFFFF;
  font-family: var(--font-mono);
  font-weight: var(--fw-label);
  font-size: var(--fs-small);
}
/* The step heading has to sit level with its number, and .panel > * + * can't
   reach inside the step, so spacing is re-declared here. */
.steps > li > div > * + * { margin-top: 0.85rem; }
.steps h3 { margin-top: 0; line-height: 1.35; }
.steps { margin-top: 1.5rem; }

/* Responsive iframe wrapper (Google Calendar) */
.embed {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.embed iframe { width: 100%; height: 70svh; min-height: 520px; border: 0; display: block; }

.embed + .callout { margin-top: var(--gap); }

/* A row of one or two buttons closing a section. */
.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}
/* Two ways in: the row inherits centring from a .center wrapper, or it carries
   .center itself. The second is for a lone button sitting in left-aligned body
   copy, where centring the whole column would drag the paragraphs with it.
   `.center` on its own would do nothing here — a flex container ignores
   text-align for its items, so the row needs this rule to pick it up. */
.center .cta-row,
.cta-row.center { justify-content: center; }

/* Jump list. Only on pages long enough that scrolling past content you don't
   want costs real thumb-work — the pub games and the fee breakdown. */
.jump {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--gap);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  /* The top edge of every pill on a line has to be level. The pill fills its
     <li> (next rule) so it is not sitting inside it as an inline-block on the
     item's text baseline, and flex-start stops one item's height stretching
     its neighbours. Between them, every pill's top edge is the flex line's own
     top edge — level by construction, not by all five happening to measure the
     same height. */
  align-items: flex-start;
  /* Centred while the row wraps; flush left from 620px (rule at the end of this
     block). The five games pills come to ~518px, so they actually fit on one
     line from about 550px up — the switch is deliberately set above that rather
     than at it, because erring this way costs nothing (a row that fits looks
     fine centred) whereas erring the other way puts an orphan pill flush left
     under four others, which is the exact thing that looked broken. */
  justify-content: center;
}

/* `margin: 0` is the whole reason the pills line up, and it is not optional.
   The base typography layer sets `li + li { margin-top: 0.4em }` (line 159) to
   space out prose lists. That selector matches any <li> preceded by another
   one, so in this row it hit pills two to five and skipped the first — and with
   flex-start aligning margin boxes, four pills sat ~7px lower than Woodruff.
   That is the "one button misaligned with the others" defect. Every other list
   in this stylesheet neutralises the same rule the same way (.season > li,
   .docs > li, .foot-links li, .steps > li, .options > li, .offer li); this row
   was the one that had been left out. If you ever delete this line, the pills
   go ragged again.
   `display: grid` is belt and braces on top: it blockifies the <a> so the pill
   fills its item instead of sitting inside it on the item's text baseline,
   where its offset would depend on inherited font metrics rather than the box.
   The cell is content-sized, so pill widths are unaffected. */
.jump li { margin: 0; display: grid; }
.jump a {
  display: inline-block;
  /* 0.6rem across, down from 0.9rem, which trimmed 9.6px off every pill and is
     why the five games pills fit on one line at all. The row is now ~537px:
     these five labels average 0.636em in Public Sans caps (they are unusually
     narrow-lettered — three L, two F, two I) plus 0.12em tracking, wrapped in
     21.2px of padding and border each, plus four 8px gaps.
     This moved from mono to Public Sans in B1 and the row grew ~19px. That was
     checked rather than assumed, because a proportional face could have gone
     either way: even at a pessimistic 0.72em average the row is 581px, still
     inside the 620px breakpoint below which .jump stays centred. So the row can
     never leave a single pill flush left under four others, which is the defect
     that made this look broken in the first place — re-run that sum if the
     labels, the tracking or the 620px switch ever change. */
  padding: 0.5rem 0.6rem;
  font-family: var(--font-body);
  font-weight: var(--fw-label);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--navy);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  transition: background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.jump a:hover { background: var(--navy); border-color: var(--navy); color: #FFFFFF; }
@media (min-width: 620px) { .jump { justify-content: flex-start; } }

/* A game's penalty / the one line that matters, pulled out of the prose. */
.verdict {
  font-family: var(--font-display);
  font-weight: var(--fw-head);
  font-size: var(--fs-lead);
  text-transform: uppercase;
  letter-spacing: var(--track-caps-lg);
  color: var(--buoy-ink);
  border-top: 2px solid var(--buoy);
  padding-top: 0.9rem;
}

/* Fee option cards — the three branch memberships are alternatives, not steps,
   so they get parallel cards rather than a numbered list. */
.options {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.85rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
}
.options > li {
  margin: 0;
  padding: 1rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.options .fee {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--fw-hero);
  font-size: var(--fs-figure);
  line-height: 1;
  color: var(--navy);
}
.options .kind {
  display: block;
  margin: 0.35rem 0 0.5rem;
  font-family: var(--font-body);
  font-weight: var(--fw-label);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--kelp-ink);
}
.options p { margin: 0; font-size: var(--fs-small); color: var(--mist); }


/* ==========================================================================
   17. MOTION & SCROLL REVEAL
   Everything here is opt-out: with reduced motion the page is simply static.
   ========================================================================== */

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 700ms var(--ease), transform 700ms var(--ease);
}
[data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .hero-slide { transform: none; }
  .hero-scroll span { animation: none; }
  .hero-rotator .cursor { animation: none; }
}


/* ==========================================================================
   18. PRINT
   Membership fees and risk assessments do get printed.
   ========================================================================== */

@media print {
  .site-head, .nav-panel, .hero, .notice, .filters, .grid-gallery,
  .lightbox, .hero-dots, .hero-arrow, .skip { display: none !important; }
  body { background: #FFFFFF; color: #000000; font-size: 11pt; }
  .band-dark, .band-deep { background: #FFFFFF !important; color: #000000 !important; }
  .band-dark h2, .band-dark h3, .band-dark p { color: #000000 !important; }
  .panel { border: 1px solid #999999; box-shadow: none; break-inside: avoid; }
  a { color: #000000; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; word-break: break-all; }
}
