/* ==========================================================================
   Sitges Olímpic Club — Design System
   ==========================================================================

   ACCESSIBILITY / CONTRAST RULE (verbatim — do not violate anywhere in this
   file or in HTML that consumes it):

     Navy-on-white (#171C35 on #FFFFFF)  = 16.75:1  → PASSES AA/AAA
     Navy-on-gold / gold-on-navy
       (#171C35 on #EFA527 / #EFA527 on #171C35) = 8.04:1 → PASSES AA/AAA
     Gold-on-white / gold on light backgrounds (#EFA527 on #FFFFFF) = 2.08:1
       → FAILS AA. Gold is an ACCENT / CTA-fill / text-on-navy colour ONLY.
       Never use gold as body text or link text on a light background.

   Consumers of this stylesheet (HTML authors, component authors) must keep
   this rule in mind when introducing new colour combinations.

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

/* --------------------------------------------------------------------------
   1. Fonts
   Two families, both Google Fonts / SIL OFL 1.1, self-hosted locally under
   assets/fonts/ — no runtime request to Google's CDN. Each ships two subset
   files (latin + latin-ext) so the browser only downloads what it needs;
   latin-ext covers the accented characters used across Catalan/Spanish.
   License: assets/fonts/LICENSE.txt (SIL Open Font License 1.1).

     Bebas Neue — display/header font ONLY (h1-h6, brand wordmark/slogan).
       Single weight (400); the face is inherently a bold condensed
       all-caps display style, no separate bold cut exists or is needed.
     Work Sans — everything else: body copy and UI (buttons, form fields,
       nav, badges, etc). Weights 400 (regular) and 700 (bold UI text).
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Bebas Neue';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/bebasneue-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Bebas Neue';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/bebasneue-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/worksans-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/worksans-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/worksans-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/worksans-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* --------------------------------------------------------------------------
   2. Design tokens
   -------------------------------------------------------------------------- */

:root {
  /* Brand colours */
  --color-navy: #171C35;
  --color-navy-light: #232A4D; /* lighter navy, for hover states on navy surfaces */
  --color-gold: #EFA527;
  --color-gold-dark: #D6900F; /* hover/active shade for gold fills */
  --color-white: #FFFFFF;

  /* Neutrals */
  --color-gray-50: #F7F7F9;   /* page background tint */
  --color-gray-100: #EDEEF2;  /* card / input backgrounds */
  --color-gray-200: #DADCE3;  /* borders */
  --color-gray-500: #6B7080;  /* secondary text on light backgrounds */
  --color-danger: #B3261E;    /* form validation errors — navy/red, never gold-on-light */
  --color-danger-bg: #FBEAE9;

  /* Spacing scale (4px base) */
  --space-1: 0.25rem;  /* 4px */
  --space-2: 0.5rem;   /* 8px */
  --space-3: 0.75rem;  /* 12px */
  --space-4: 1rem;     /* 16px */
  --space-5: 1.5rem;   /* 24px */
  --space-6: 2rem;     /* 32px */
  --space-7: 3rem;     /* 48px */
  --space-8: 4rem;     /* 64px */

  /* Type scale */
  --text-sm: 0.875rem;   /* 14px */
  --text-base: 1rem;     /* 16px */
  --text-lg: 1.125rem;   /* 18px */
  --text-xl: 1.375rem;   /* 22px */
  --text-2xl: 1.75rem;   /* 28px */
  --text-3xl: 2.25rem;   /* 36px */
  --text-4xl: 3rem;      /* 48px */
  --text-5xl: 3.75rem;   /* 60px */

  /* Font families — see section 1 for which elements use which */
  --font-sans: 'Work Sans', -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Bebas Neue', 'Work Sans', -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* Misc */
  --radius-sm: 2px;
  --radius-md: 4px;
  --shadow-card: 0 1px 2px rgba(23, 28, 53, 0.06), 0 4px 12px rgba(23, 28, 53, 0.08);
  --transition-fast: 150ms ease;
  --transition-base: 250ms ease;
  --header-height: 72px;
  --ticker-height: 40px; /* must match .ticker's actual rendered height -- see that rule */
}

/* --------------------------------------------------------------------------
   3. Base / reset
   -------------------------------------------------------------------------- */

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

* {
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  overflow-x: hidden;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* overflow-x: hidden is a defensive backstop against any element (now or
   later) overflowing the viewport width and making the whole page
   horizontally swipeable -- seen on mobile as the page "splitting" between
   the navy header and the white body past the real content edge. The real
   fix for a given overflow is still to find and constrain that element;
   this just guarantees a bug like that can never break the whole page. */
body {
  overflow-x: hidden;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--color-navy);
  background-color: var(--color-white);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}

a {
  color: var(--color-navy);
  text-decoration-color: var(--color-gold);
  text-underline-offset: 0.15em;
}

a:not([class]) {
  text-decoration: underline;
}

img {
  max-width: 100%;
  display: block;
}

button {
  font-family: inherit;
  cursor: pointer;
}

ul[class],
ol[class] {
  list-style: none;
}

/* --------------------------------------------------------------------------
   4. Focus visibility (accessibility) — applied broadly, never removed
   without this replacement anywhere in the stylesheet.
   -------------------------------------------------------------------------- */

:focus-visible {
  outline: 3px solid var(--color-gold);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   5. Layout helpers
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--space-5);
}

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

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

/* Vertical rhythm for long-form content (about/privacy pages). The global
   reset zeroes all margins, so headings/paragraphs need this to read as
   separated blocks rather than being flush against each other. */
.prose > * + * {
  margin-top: var(--space-4);
}

.prose h2 {
  margin-top: var(--space-8);
  font-size: var(--text-2xl);
}

.prose h2:first-of-type {
  margin-top: var(--space-6);
}

.prose p {
  max-width: 70ch;
}

/* Generic hidden-state utility (complements the more specific
   .consent-banner.is-hidden rule below, which wins on specificity for that
   component). Used anywhere JS needs to show/hide an element, e.g. the
   contact form's per-field and consent error messages. */
.is-hidden {
  display: none;
}

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

/* --------------------------------------------------------------------------
   6. Skip link
   Visually hidden until keyboard-focused; jumps straight to #main so
   keyboard/screen-reader users can bypass the nav on every page.
   -------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  top: -60px;
  left: var(--space-4);
  z-index: 1000;
  background: var(--color-gold);
  color: var(--color-navy);
  font-weight: 700;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  transition: top var(--transition-fast);
}

.skip-link:focus {
  top: var(--space-4);
}

/* --------------------------------------------------------------------------
   7. Site header / navigation
   Minimal, hamburger-first header (inspired by PSG's site structure, not
   its colours/content) -- .nav__toggle is the one way into the full link
   list on mobile, where every item (including About us / Work with us)
   already appears in the hamburger overlay. On phones the header itself
   only surfaces the icon-only toggle, the brand mark, the language
   switcher, and one accent CTA; there isn't room for more without
   overflowing real phone viewports (confirmed on iPhone). From the 768px
   breakpoint up there's room to also show "About us" / "Work with us" as
   persistent text links and the toggle's "Menu" label.
   Structure expected in HTML:
     header.site-header
       div.container.nav
         div.nav__start
           button.nav__toggle (icon always visible, "Menu" label 768px+)
           a.nav__brand (crest img + wordmark)
           a.nav__link × N (About us, Work with us -- hidden below 768px)
         div.nav__end
           div.nav__lang (language switcher, ca/es/en -- always visible)
           a.nav__link--cta (single accent link, e.g. Join -- always visible)
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-navy);
  /* min-height, not height: --header-height is still the size every other
     calc() in this file assumes (e.g. .hero--home's viewport-height math),
     but a hard height clipped real content in cramped mobile scenarios
     (confirmed on iPhone: the CTA link wrapping to 3 lines got cut off).
     min-height keeps the common case identical while letting the row grow
     if it ever genuinely needs more room, instead of clipping. */
  min-height: var(--header-height);
  display: flex;
  align-items: center;
}

.nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
}

.nav__start {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/* Below the tablet breakpoint, the persistent "About us" / "Work with us"
   text links (plus the toggle's "Menu" label, see .nav__toggle-label) push
   the header row past real phone viewport widths -- confirmed on iPhone as
   the language switcher getting squeezed off-screen and the whole page
   becoming horizontally scrollable. On mobile they're reachable through
   the hamburger overlay instead, which already lists every page; the
   768px+ override below restores them as persistent header links once
   there's room. */
.nav__start .nav__link {
  display: none;
}

.nav__end {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-white);
  font-weight: 700;
  font-size: var(--text-lg);
  flex-shrink: 0;
  white-space: nowrap;
  text-decoration: none;
}

.nav__brand img {
  height: 40px;
  width: auto;
}

.nav__link {
  position: relative;
  color: var(--color-white);
  font-weight: 400;
  font-size: var(--text-base);
  text-decoration: none;
  padding-block: var(--space-2);
}

/* Gold sliding/growing underline on hover/focus, built with a pseudo-element
   so it never affects layout (transform + width transition). */
.nav__link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: var(--color-gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--transition-base);
}

.nav__link:hover::after,
.nav__link:focus-visible::after,
.nav__link.is-active::after {
  transform: scaleX(1);
}

/* The one header CTA (e.g. "Fes-te'n soci") -- gold text so it reads as the
   priority action against the rest of the (white) header content, same
   spirit as ticket/shop prominence on the reference site, no filled-button
   weight needed since it's sitting in a slim header bar. */
.nav__link--cta {
  color: var(--color-gold);
  font-weight: 700;
  text-transform: uppercase;
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
}

.nav__link--cta::after {
  background: var(--color-gold);
}

/* Language switcher — three-way toggle CA / ES / EN. Two copies in the
   markup, shown one at a time by breakpoint (both wired up automatically:
   i18n.js targets every [data-lang] element on the page, not a specific
   one):
     .nav__start .nav__lang -- next to the brand, compact/no border chrome
       so it fits next to "SOC" on real phone widths (confirmed on iPhone
       that a bordered-button version there visually overlapped the
       wordmark). Visible below the tablet breakpoint.
     .nav__end .nav__lang -- next to the CTA, matching where it visually
       sat before the mobile fixes. Visible from the tablet breakpoint up,
       where "next to SOC" reads as cramped against the brand instead of
       as a clean list (feedback after checking the mobile fix on
       desktop).
   No longer duplicated in the hamburger overlay — one of the two copies
   above is always visible at any width, so a third copy there was pure
   redundancy. */
.nav__start .nav__lang {
  display: flex;
}

.nav__end .nav__lang {
  display: none;
}

.nav__lang {
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.nav__lang-btn {
  white-space: nowrap;
  background: transparent;
  border: none;
  color: var(--color-white);
  font-size: var(--text-sm);
  font-weight: 700;
  padding: var(--space-1);
  opacity: 0.6;
  transition: opacity var(--transition-fast);
}

.nav__lang-btn:hover {
  opacity: 1;
}

.nav__lang-btn.is-active {
  opacity: 1;
  color: var(--color-gold);
  text-decoration: underline;
  text-decoration-color: var(--color-gold);
}

/* Hamburger — always visible, the single entry point into navigation at
   every breakpoint (see comment above the section for why). */
.nav__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: transparent;
  border: none;
  padding: var(--space-2);
  color: var(--color-white);
  /* flex-shrink: 0 on this, .nav__brand and .nav__lang below: without it,
     when .nav__start doesn't have enough room, the browser shrinks these
     nested flex containers below their own children's content size rather
     than respecting it (the well-known flexbox nested min-width:auto
     gotcha) -- confirmed via direct measurement that .nav__brand's own
     box was narrower than its "SOC" text needed, so the text overflowed
     past its container and visually sat on top of the language switcher
     next to it. Pinning these to their natural size means the row can
     still run out of room overall, but individual items can no longer
     overlap each other -- worst case is the CTA link wrapping to a second
     line, which .site-header's min-height (not a hard height) allows for
     without clipping. */
  flex-shrink: 0;
}

.nav__toggle-icon {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 22px;
  height: 22px;
}

.nav__toggle-bar {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--color-white);
  transition: transform var(--transition-fast), opacity var(--transition-fast);
}

/* Icon-only hamburger below the tablet breakpoint -- see the .nav__start
   .nav__link comment above for why header-row space is tight on phones.
   The button still has its aria-label, so this loses no accessible name. */
.nav__toggle-label {
  display: none;
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* When JS toggles .is-open on the toggle button, morph into an X */
.nav__toggle.is-open .nav__toggle-bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav__toggle.is-open .nav__toggle-bar:nth-child(2) {
  opacity: 0;
}
.nav__toggle.is-open .nav__toggle-bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* --------------------------------------------------------------------------
   8. Navigation menu — white panel over a dark backdrop
   Directly inspired by the reference site's mega-menu: a white panel slides
   in from the left carrying the link list, while a moody dark-navy pane
   remains visible to its right (decorative only -- not page content, kept
   simple since this site has no sub-menus to show there). Below the
   backdrop-visible breakpoint the panel just takes the full screen, same as
   the previous mobile treatment.
   JS toggles `.is-open` on `.nav-overlay`; body scroll-lock unchanged.
   Structure expected:
     div.nav-overlay
       div.nav-overlay__panel
         div.nav-overlay__panel-header
           span.nav-overlay__wordmark
           button.nav-overlay__close
         nav > a.nav-overlay__link (one per page, flat list)
       div.nav-overlay__backdrop (aria-hidden, decorative)
   -------------------------------------------------------------------------- */

.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition-base), visibility var(--transition-base);
}

.nav-overlay.is-open {
  opacity: 1;
  visibility: visible;
}

.nav-overlay__panel {
  width: 100%;
  height: 100%;
  background: var(--color-white);
  display: flex;
  flex-direction: column;
  padding: var(--space-5);
  box-shadow: 8px 0 32px rgba(23, 28, 53, 0.25);
  transform: translateX(-24px);
  transition: transform var(--transition-base);
  /* The link list plus the language switcher below can outgrow a short
     phone screen's height -- scroll the panel itself rather than clip. */
  overflow-y: auto;
}

.nav-overlay.is-open .nav-overlay__panel {
  transform: translateX(0);
}

.nav-overlay__panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-7);
}

/* Placeholder lockup until the club settles on a real slogan -- swap the
   text content in the HTML when that's decided, styling stays the same. */
.nav-overlay__wordmark {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--color-navy);
}

.nav-overlay__close {
  background: transparent;
  border: none;
  color: var(--color-navy);
  font-size: var(--text-2xl);
  line-height: 1;
  padding: var(--space-2);
}

/* The semantic <nav> landmark wrapping the overlay links is kept for a11y
   but must not introduce its own box in the flex layout — its <a> children
   become direct flex items of .nav-overlay__panel. */
.nav-overlay__panel nav {
  display: contents;
}

.nav-overlay__link {
  position: relative;
  color: var(--color-navy);
  font-size: var(--text-2xl);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-decoration: none;
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--color-gray-200);
}

.nav-overlay__link:hover,
.nav-overlay__link:focus-visible,
.nav-overlay__link.is-active {
  color: var(--color-gold-dark);
}

/* Decorative dark pane, hidden until there's room for it (see breakpoints) */
.nav-overlay__backdrop {
  display: none;
  flex: 1;
  height: 100%;
  background: radial-gradient(circle at 30% 25%, var(--color-navy-light), var(--color-navy) 65%);
}

/* Lock body scroll while the overlay is open — JS toggles this on <body> */
body.nav-open {
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   9. Hero
   .hero is a full-bleed navy section. The crest watermark is applied via
   ::before (NOT via opacity on the section itself, which would also fade
   the text) — absolutely positioned behind the content, low opacity.
   Structure expected:
     section.hero
       div.container.hero__inner
         p.hero__eyebrow
         h1.hero__headline (span.accent for gold emphasis words)
         p.hero__subhead
         div.hero__actions (.btn.btn-primary / .btn.btn-secondary)
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  background: radial-gradient(circle at 20% 15%, var(--color-navy-light), var(--color-navy) 60%);
  color: var(--color-white);
  padding-block: var(--space-8);
  overflow: hidden;
  isolation: isolate;
}

/* Bottom-right corner accent, deliberately bled off both edges (not
   centered) so it never sits directly behind the left-aligned headline and
   never reads as an accidental crop -- the section's own overflow:hidden
   clips it at a fixed, intentional offset past the corner every time. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url('../img/crest.png');
  background-repeat: no-repeat;
  background-position: calc(100% + 60px) calc(100% + 60px);
  background-size: min(38%, 420px);
  opacity: 0.13;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   9b. Homepage hero variant — big centered crest on a solid navy field.
   Only index.html uses .hero--home; every other page keeps the plain
   .hero corner-accent treatment above, since they still have real heading
   and body text the crest needs to stay clear of.
   -------------------------------------------------------------------------- */

/* Fills exactly the viewport height not already taken by the ticker and
   header, so on load the very first screenful is only navy + crest --
   the white "Why join now" section below only appears once the visitor
   actually scrolls, not by default on shorter/taller screens. */
.hero--home {
  background: var(--color-navy);
  padding-block: var(--space-8);
  /* dvh (dynamic viewport height) accounts for mobile browsers' address bar
     showing/hiding; vh above is the fallback for browsers that don't
     support dvh yet -- unsupported values are simply ignored, so newer
     browsers use the second (more accurate) declaration. */
  min-height: calc(100vh - var(--header-height) - var(--ticker-height));
  min-height: calc(100dvh - var(--header-height) - var(--ticker-height));
  display: flex;
  align-items: center;
}

/* The corner-accent background-image crest (used on every other page) is
   switched off here entirely -- the homepage renders the crest as a real
   <img> in normal document flow instead (see .hero__crest-mark below), so
   it's guaranteed to sit below the eyebrow text, not just usually clear of
   it depending on background-position math. */
.hero--home::before {
  content: none;
}

.hero--home .hero__inner {
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.hero__crest-mark {
  width: min(28%, 200px);
  height: auto;
  margin-top: var(--space-6);
  margin-bottom: var(--space-6);
}

/* Homepage-only, smaller than the page-title .hero__headline used
   elsewhere: this one shares the hero with the crest and the stats row
   below, so it stays a supporting slogan rather than a full headline. */
.hero__headline--slogan {
  font-size: var(--text-2xl);
  margin-bottom: 0;
  max-width: 32ch;
}

/* Founders / inaugural season / club's home -- three-up on a light top
   border, gold Bebas Neue numbers over a muted uppercase label, echoing
   .hero__eyebrow's treatment at a smaller scale. */
.hero__stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-6) var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  padding-top: var(--space-5);
  width: 100%;
  max-width: 560px;
}

.hero__stat-value {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 400;
  color: var(--color-gold);
}

.hero__stat-label {
  font-size: var(--text-sm);
  color: var(--color-white);
  opacity: 0.7;
  margin-top: var(--space-1);
}

.hero__inner {
  max-width: 760px;
}

.hero__eyebrow {
  color: var(--color-gold);
  font-weight: 700;
  font-size: var(--text-sm);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: var(--space-3);
}

.hero__headline {
  font-size: var(--text-4xl);
  font-weight: 700;
  color: var(--color-white);
  margin-bottom: var(--space-4);
}

/* Emphasis words inside headlines/body copy — gold on navy passes contrast
   (8.04:1). Never apply .accent on a light/white background. */
.hero__headline .accent,
.accent {
  color: var(--color-gold);
}

.hero__subhead {
  font-size: var(--text-lg);
  font-weight: 400;
  color: var(--color-white);
  opacity: 0.9;
  margin-bottom: var(--space-6);
  max-width: 60ch;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

/* --------------------------------------------------------------------------
   10. Buttons
   .btn is the shared base. Pair with exactly one modifier.
   .btn-primary  — solid gold fill, navy text. Use for the main CTA.
   .btn-secondary — outline/ghost. Auto-adapts via .btn-secondary--on-navy
                    for use on navy backgrounds (white outline+text).
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--text-base);
  line-height: 1;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  border: 2px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--transition-fast), color var(--transition-fast),
    border-color var(--transition-fast), transform var(--transition-fast);
}

.btn:active {
  transform: translateY(1px);
}

/* Solid gold CTA — for use on light or navy backgrounds alike */
.btn-primary {
  background-color: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-navy);
}

.btn-primary:hover {
  background-color: var(--color-gold-dark);
  border-color: var(--color-gold-dark);
}

/* Ghost/outline button, default variant: navy border+text — use on light
   (white/gray) backgrounds only, per the contrast rule at the top of this
   file (gold-on-light fails AA, so this variant intentionally uses navy). */
.btn-secondary {
  background-color: transparent;
  border-color: var(--color-navy);
  color: var(--color-navy);
}

.btn-secondary:hover {
  background-color: var(--color-navy);
  color: var(--color-white);
}

/* White ghost/outline variant — use instead of .btn-secondary when the
   button sits on a navy background (e.g. inside .hero or .consent-banner). */
.btn-secondary--on-navy {
  background-color: transparent;
  border-color: var(--color-white);
  color: var(--color-white);
}

.btn-secondary--on-navy:hover {
  background-color: var(--color-white);
  color: var(--color-navy);
}

.btn-sm {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

/* --------------------------------------------------------------------------
   11. Cards
   Generic content card: white background, subtle border+shadow, gold top
   accent bar. Used for value-prop cards, News/Shop "coming soon" cards,
   membership category cards, etc.
   Structure: div.card > (h3.card__title, p.card__body, optional .badge)
   -------------------------------------------------------------------------- */

.card {
  position: relative;
  background: var(--color-white);
  border: 1px solid var(--color-gray-200);
  border-top: 4px solid var(--color-gold);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: var(--space-5);
}

.card__title {
  font-size: var(--text-xl);
  font-weight: 700;
  margin-bottom: var(--space-2);
}

.card__body {
  color: var(--color-gray-500);
  font-size: var(--text-base);
}

/* Grid wrapper for groups of cards — mobile 1 col, see breakpoints for
   tablet/desktop column counts. */
.card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

/* "Coming soon" is the same .card with a .badge inside it — no separate
   variant class needed. See News/Shop pages: div.card > span.badge + copy. */

/* Founders grid: 1 column on mobile (base .card-grid rule above), then all
   4 side by side from the tablet breakpoint up -- see the minmax(0, 1fr)
   override in the 768px breakpoint below. minmax(0, 1fr), not plain 1fr:
   grid items default to min-width: auto (their content's minimum size), so
   a plain repeat(4, 1fr) can't shrink columns below that and overflows the
   container instead of staying side by side at narrower desktop widths.
   minmax(0, 1fr) lets each column shrink all the way down, so 4 always fit
   without ever running off-screen. */

/* --------------------------------------------------------------------------
   12. Badges / pills
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  background: var(--color-gold);
  color: var(--color-navy);
  font-weight: 700;
  font-size: var(--text-sm);
  padding: var(--space-1) var(--space-4);
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Muted variant -- for a "not yet" status (e.g. a locked product) sitting
   next to a regular gold .badge used for the "available now" state, so
   the two read as distinct at a glance without introducing a new brand
   colour (gray-100/gray-500 is already an approved pairing elsewhere,
   e.g. .card__body text). */
.badge--muted {
  background: var(--color-gray-100);
  color: var(--color-gray-500);
}

/* --------------------------------------------------------------------------
   13. Diagonal section dividers
   Usage: add `.divider-diagonal` to a section wrapper to angle-cut its
   bottom edge (clip-path), creating an angular navy/white transition with
   the section that follows. Pair with a negative top margin (e.g.
   margin-top: -1 * the diagonal depth, roughly --space-7) on the following
   section if you need the two to visually interlock without a gap.
   Modifiers:
     .divider-diagonal--top     angle-cuts the TOP edge instead of bottom
     .divider-diagonal--reverse flips the diagonal direction
   -------------------------------------------------------------------------- */

.divider-diagonal {
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 48px), 0 100%);
  padding-bottom: var(--space-8);
}

.divider-diagonal--top {
  clip-path: polygon(0 48px, 100% 0, 100% 100%, 0 100%);
  padding-top: var(--space-8);
}

.divider-diagonal--reverse {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 calc(100% - 48px));
}

/* --------------------------------------------------------------------------
   14. Forms
   Structure expected: div.form-group > label + input/select/textarea,
   with an optional p.form-error (role/aria-live handled in HTML/JS) and
   .form-checkbox for the consent row.
   -------------------------------------------------------------------------- */

.form-group {
  margin-bottom: var(--space-5);
}

.form-label {
  display: block;
  font-weight: 700;
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
}

.form-input,
.form-select,
.form-textarea {
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  color: var(--color-navy);
  background: var(--color-white);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.form-textarea {
  min-height: 140px;
  resize: vertical;
}

.form-input:hover,
.form-select:hover,
.form-textarea:hover {
  border-color: var(--color-gray-500);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
  border-color: var(--color-navy);
  outline: none;
  box-shadow: 0 0 0 3px rgba(23, 28, 53, 0.12);
}

/* Invalid state — JS toggles this alongside a visible .form-error message */
.form-input.is-invalid,
.form-select.is-invalid,
.form-textarea.is-invalid {
  border-color: var(--color-danger);
}

.form-checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.form-checkbox {
  width: 18px;
  height: 18px;
  margin-top: 3px;
  accent-color: var(--color-navy);
  flex-shrink: 0;
}

.form-checkbox-row label {
  font-size: var(--text-sm);
  color: var(--color-gray-500);
}

/* Error text — high-contrast danger colour (never gold-on-light). Intended
   to sit inside an element with aria-live="polite" set in the HTML/JS. */
.form-error {
  display: block;
  color: var(--color-danger);
  font-size: var(--text-sm);
  font-weight: 700;
  margin-top: var(--space-2);
}

/* Optional inline banner style for a form-level (not per-field) error */
.form-error-banner {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border: 1px solid var(--color-danger);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  font-size: var(--text-sm);
  font-weight: 700;
  margin-bottom: var(--space-5);
}

/* Form-level success banner -- navy, not a new green, to stay inside the
   site's navy/gold/gray/danger palette (see the contrast rule at the top
   of this file). Used by contact-form.js to confirm a submission without
   navigating away from the page. */
.form-success-banner {
  background: var(--color-gray-100);
  color: var(--color-navy);
  border: 1px solid var(--color-navy);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  font-size: var(--text-sm);
  font-weight: 700;
  margin-bottom: var(--space-5);
}

/* Honeypot field — visually hidden, kept in the tab order out (HTML should
   also set tabindex="-1" and aria-hidden="true"). */
.form-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   15. Consent banner
   Fixed bottom bar. Structure expected:
     div.consent-banner
       p.consent-banner__text (+ a link to privacy.html)
       div.consent-banner__actions > button.btn.btn-primary.btn-sm
       button.consent-banner__close (optional secondary dismiss "x")
   -------------------------------------------------------------------------- */

.consent-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 300;
  background: var(--color-navy);
  color: var(--color-white);
  padding: var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.2);
}

.consent-banner__text {
  font-size: var(--text-sm);
  max-width: 70ch;
}

.consent-banner__text a {
  color: var(--color-gold);
}

.consent-banner__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.consent-banner__close {
  background: transparent;
  border: none;
  color: var(--color-white);
  font-size: var(--text-lg);
  padding: var(--space-2);
  opacity: 0.7;
}

.consent-banner__close:hover {
  opacity: 1;
}

/* Hidden state — JS adds this once the user has acknowledged / dismissed */
.consent-banner.is-hidden {
  display: none;
}

/* --------------------------------------------------------------------------
   16. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--color-navy);
  color: var(--color-white);
  padding-block: var(--space-7);
}

.site-footer a {
  color: var(--color-white);
  opacity: 0.85;
}

.site-footer a:hover {
  opacity: 1;
  color: var(--color-gold);
}

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

.footer__tagline {
  opacity: 0.75;
  font-size: var(--text-sm);
  margin-top: var(--space-2);
}

.footer__copyright {
  opacity: 0.6;
  font-size: var(--text-sm);
  margin-top: var(--space-6);
}

.footer__social {
  display: flex;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

/* --------------------------------------------------------------------------
   17. Responsive breakpoints (mobile-first)
   -------------------------------------------------------------------------- */

/* The menu panel takes the full screen below this point (matches the old
   mobile-only overlay behaviour); from here up, it settles to a fixed width
   with the decorative dark pane filling the rest of the viewport. */
@media (min-width: 640px) {
  .nav-overlay__panel {
    width: min(440px, 90vw);
  }

  .nav-overlay__backdrop {
    display: block;
  }
}

@media (min-width: 768px) {
  .nav__start .nav__lang {
    display: none;
  }

  .nav__end .nav__lang {
    display: flex;
  }

  .nav__start .nav__link {
    display: inline;
  }

  .nav__toggle-label {
    display: block;
  }

  .hero__headline {
    font-size: var(--text-5xl);
  }

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

  /* Compound selector (not just .card-grid--4col) so this beats the
     later, equal-specificity ".card-grid { repeat(3, 1fr) }" rule at the
     1024px breakpoint below -- without it, cascade order alone let the
     generic 3-column rule win on laptop-sized screens, dropping the 4th
     founder card to its own second row. */
  .card-grid.card-grid--4col {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .footer__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1024px) {
  .container {
    padding-inline: var(--space-6);
  }

  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .card-grid--2col {
    grid-template-columns: repeat(2, 1fr);
  }

  .hero__inner {
    max-width: 820px;
  }
}

@media (min-width: 1440px) {
  .container {
    max-width: 1320px;
  }
}

/* --------------------------------------------------------------------------
   18. Reduced motion
   -------------------------------------------------------------------------- */

@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;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   19. Calendar
   Month-grid view rendered into #calendar-root by assets/js/calendar.js.
   Structure is generated by that script (see its render() function) --
   these rules just style whatever it produces: div.calendar__header (prev/
   next buttons + month label) followed by table.calendar__table.
   -------------------------------------------------------------------------- */

.calendar__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

.calendar__month-label {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--color-navy);
}

.calendar__nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: var(--color-gray-50);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-md);
  color: var(--color-navy);
  font-size: var(--text-lg);
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.calendar__nav-btn:hover {
  background: var(--color-gray-100);
  border-color: var(--color-navy);
}

.calendar__table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.calendar__table th {
  padding-block: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-gray-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.calendar__cell {
  height: 64px;
  vertical-align: top;
  padding: var(--space-2);
  border: 1px solid var(--color-gray-200);
}

.calendar__cell--empty {
  background: var(--color-gray-50);
  border-color: var(--color-gray-50);
}

.calendar__date {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  font-size: var(--text-sm);
  font-weight: 700;
}

.calendar__cell--today .calendar__date {
  background: var(--color-gold);
  color: var(--color-navy);
  border-radius: 999px;
  padding-inline: var(--space-1);
}

.calendar__cell--has-events {
  background: var(--color-gray-50);
}

.calendar__events {
  margin-top: var(--space-1);
}

/* Wraps instead of truncating -- confirmed titles were getting cut off to
   an unreadable "PRESE..." in the ~13%-of-container-wide day column.
   .calendar__cell's own height is a soft minimum in table layout (no
   overflow:hidden there), so the row just grows taller for a day with a
   longer title instead of clipping it. */
.calendar__event {
  font-size: var(--text-sm);
  color: var(--color-navy);
  background: var(--color-gold);
  border-radius: var(--radius-sm);
  padding: 2px var(--space-2);
  margin-top: 2px;
  white-space: normal;
  word-break: break-word;
  line-height: 1.3;
}

.calendar__empty-note {
  margin-top: var(--space-5);
  color: var(--color-gray-500);
  font-size: var(--text-sm);
  text-align: center;
}

/* Narrow screens: the fixed-height grid gets cramped -- shrink cells and
   drop event-label text down to just a dot indicator instead of trying to
   fit text in a ~40px-wide column. */
@media (max-width: 480px) {
  .calendar__cell {
    height: 56px;
    padding: var(--space-1);
  }

  .calendar__event {
    width: 6px;
    height: 6px;
    padding: 0;
    border-radius: 999px;
    overflow: visible;
  }

  .calendar__events {
    display: flex;
    gap: 3px;
    flex-wrap: wrap;
  }

  /* Homepage hero on small phones: crest mark and section padding were
     tall enough together to push the hero past one screen (confirmed
     against real phone viewport heights), so this trims the parts that
     are purely decorative spacing rather than content. */
  .hero--home {
    padding-block: var(--space-6);
  }

  .hero__crest-mark {
    width: min(20%, 120px);
    margin-top: var(--space-4);
    margin-bottom: var(--space-4);
  }
}

/* --------------------------------------------------------------------------
   20. Announcement ticker
   Sitewide scrolling banner above the header. Seamless-marquee technique:
   .ticker__track holds MANY identical copies of the content back to back,
   animated from translateX(0) to translateX(-50%) -- when the first half
   of the copies has scrolled fully off, the second half is exactly where
   the first started, so the loop is invisible.

   The copy count matters: the first HALF of the copies (i.e. what's on
   screen before the loop point) must together be wider than the widest
   realistic browser viewport, or there's a visible gap of empty banner
   before it loops (confirmed: 2 copies was nowhere near enough -- the
   short message only filled a few hundred px, leaving most of any real
   window empty). 16 copies -- 8 per half -- comfortably covers desktop
   and ultrawide widths for a message this short.

   Only the FIRST copy is a real, focusable link; the other 15 are
   aria-hidden + tabindex="-1" (purely visual filler), so keyboard/screen
   reader users encounter the announcement exactly once, not 16 times.
   Structure: div.ticker > div.ticker__track > a.ticker__link (x16)
   -------------------------------------------------------------------------- */

.ticker {
  height: var(--ticker-height);
  display: flex;
  align-items: center;
  background: var(--color-navy);
  overflow: hidden;
  white-space: nowrap;
}

.ticker__track {
  display: inline-flex;
  width: max-content;
}

.ticker__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-2);
  padding-inline: var(--space-6);
  color: var(--color-white);
  font-size: var(--text-sm);
  text-decoration: none;
  white-space: nowrap;
}

.ticker__link .accent {
  font-weight: 700;
  text-decoration: underline;
  text-decoration-color: var(--color-gold);
}

@media (prefers-reduced-motion: no-preference) {
  .ticker__track {
    animation: ticker-scroll 25s linear infinite;
  }

  .ticker:hover .ticker__track,
  .ticker:focus-within .ticker__track {
    animation-play-state: paused;
  }

  @keyframes ticker-scroll {
    from {
      transform: translateX(0);
    }
    to {
      transform: translateX(-50%);
    }
  }
}

/* --------------------------------------------------------------------------
   21. Founder cards
   Same .card base as section 11, plus a circular monogram avatar in place
   of a photo -- no real founder photos exist yet, and a placeholder image
   file would read as broken/unfinished. Initials-on-navy is a deliberate,
   presentable placeholder, not a bug.
   Structure: div.founder-card > (div.founder-avatar, p.founder-name,
   p.founder-role, p.founder-bio)
   -------------------------------------------------------------------------- */

.founder-card {
  text-align: center;
}

.founder-avatar {
  width: 88px;
  height: 88px;
  margin: 0 auto var(--space-4);
  border-radius: 50%;
  background: var(--color-navy);
  color: var(--color-gold);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  letter-spacing: 0.04em;
}

.founder-name {
  font-weight: 700;
  margin-bottom: var(--space-1);
}

.founder-role {
  color: var(--color-navy);
  text-transform: uppercase;
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  font-weight: 700;
  margin-bottom: var(--space-3);
}

.founder-bio {
  color: var(--color-gray-500);
  font-size: var(--text-sm);
  font-style: italic;
}

/* --------------------------------------------------------------------------
   22. Privacy policy dialog
   Native <dialog> so Escape-to-close and focus containment come from the
   browser, not hand-rolled JS. It wraps an <iframe src="privacy.html"> --
   same-origin, so it shares localStorage with the parent page and picks up
   the current language automatically -- rather than duplicating the full
   policy text into every page. privacy.html itself detects it's embedded
   (see privacy-dialog.js) and hides its own header/ticker/footer via
   .is-embedded, showing just the policy content.
   Structure: dialog.privacy-dialog > (div.privacy-dialog__header >
   span + button.privacy-dialog__close, iframe.privacy-dialog__frame)
   -------------------------------------------------------------------------- */

/* display must stay gated behind [open] -- an unconditional "display: flex"
   here would override the browser's own "dialog:not([open]) { display:
   none }" rule (author styles always beat user-agent styles), leaving the
   dialog visually stuck open forever even after .close() removes the
   [open] attribute. The explicit :not([open]) rule below makes that
   intent unmistakable rather than leaning on the browser default alone. */
.privacy-dialog:not([open]) {
  display: none;
}

.privacy-dialog {
  width: min(720px, 92vw);
  max-height: 85vh;
  padding: 0;
  border: none;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
}

.privacy-dialog[open] {
  display: flex;
  flex-direction: column;
}

.privacy-dialog::backdrop {
  background: rgba(23, 28, 53, 0.6);
}

.privacy-dialog__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-gray-200);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--color-navy);
}

.privacy-dialog__close {
  background: transparent;
  border: none;
  color: var(--color-navy);
  font-size: var(--text-2xl);
  line-height: 1;
  padding: var(--space-1) var(--space-2);
}

.privacy-dialog__frame {
  flex: 1;
  width: 100%;
  min-height: 60vh;
  border: none;
}

/* Applied to <html> by privacy-dialog.js when privacy.html detects it is
   running inside the dialog's iframe -- keeps this a single-source-of-truth
   page (no duplicated policy text elsewhere) while showing only the policy
   content inside the popup. */
html.is-embedded .ticker,
html.is-embedded .site-header,
html.is-embedded .nav-overlay,
html.is-embedded .site-footer,
html.is-embedded .consent-banner,
html.is-embedded .hero {
  display: none;
}

/* --------------------------------------------------------------------------
   23. About page — mission / values / respect / identity / Sitges life
   Six content sections on about.html, between the Founders section and the
   final CTA. Reuses .section/.container/.card/.card-grid/.text-center
   wherever they already do the job; only the pieces below are new.
   -------------------------------------------------------------------------- */

/* Mission — punchy, minimal, centered statement above the supporting body
   copy. */
.mission-statement {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  color: var(--color-navy);
  margin-top: var(--space-5);
}

.mission-body {
  font-size: var(--text-lg);
  color: var(--color-gray-500);
  max-width: 60ch;
  margin-inline: auto;
  margin-top: var(--space-5);
}

/* Values — same .card base as Founders / the homepage "why join now" cards
   (section 11), plus a self-hosted inline SVG icon (stroke=currentColor,
   no icon font or CDN request). */
.value-card {
  text-align: center;
}

.value-icon {
  width: 40px;
  height: 40px;
  margin: 0 auto var(--space-4);
  color: var(--color-gold-dark);
}

.value-icon svg {
  width: 100%;
  height: 100%;
}

.values-closing {
  font-weight: 700;
}

/* Dark-navy section variant — same navy/white pairing as the header,
   footer, and hero (sections 7, 9, 16), reused here for any content block
   that needs to visually break away from the surrounding light sections.
   Colour cascades from the section into its heading/body text
   automatically, so no separate overrides are needed on them. */
.section--dark {
  background: var(--color-navy);
  color: var(--color-white);
}

/* Identity — light section with a gold top/bottom border (decorative only,
   never gold text on this light background — see the contrast rule at the
   top of this file) and a low-opacity crest watermark using the same
   ::before technique as .hero (section 9) above, at a much lower opacity
   suited to a light background. */
.identity-section {
  position: relative;
  background: var(--color-gray-50);
  border-top: 4px solid var(--color-gold);
  border-bottom: 4px solid var(--color-gold);
  overflow: hidden;
  isolation: isolate;
}

.identity-section::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url('../img/crest.png');
  background-repeat: no-repeat;
  background-position: calc(100% + 60px) calc(100% + 60px);
  background-size: min(38%, 420px);
  opacity: 0.06;
  pointer-events: none;
}

/* Pull-quote line — used for the Identity and Sitges Life "highlight"
   fields: bigger/bolder than body copy, same display font as headings. */
.pull-quote {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  color: var(--color-navy);
  margin-top: var(--space-6);
}

/* Closing quote above the final CTA button on about.html. */
.closing-quote {
  font-style: italic;
  font-size: var(--text-xl);
  color: var(--color-navy);
  max-width: 640px;
  margin-inline: auto;
  margin-bottom: var(--space-6);
}

/* --------------------------------------------------------------------------
   25. About page — Sitges Life background photo
   Same navy (#171C35, matches --color-navy) scrim technique as .hero::before
   / .identity-section::before, but as a real photo instead of a low-opacity
   crest watermark, and strong enough (2 stacked rgba layers) to keep white
   text readable over any part of the photo -- literal rgba values, not
   var(--color-navy) with alpha, since custom properties can't carry alpha
   into rgba() without color-mix(); keep this in sync with --color-navy by
   hand if that token ever changes.
   -------------------------------------------------------------------------- */
/* Photo re-cropped to a wide 1920x700 (2.74:1) banner focused on the
   church/promenade band -- the original 1920x1276 shot was mostly empty
   night sky and dark sand, which meant a plain background-size: cover on
   a short, very wide section scaled it up so much the church (sitting at
   roughly 30% across, not dead centre) got cropped out or pushed to the
   edge (confirmed: same underlying issue as .hero--team's photo, see that
   section's comment). background-position biases toward that 30% mark
   instead of the 50% default so the church stays in frame even when the
   section is much wider than this crop's own aspect ratio. */
.sitges-life-section {
  position: relative;
  background:
    linear-gradient(rgba(23, 28, 53, 0.72), rgba(23, 28, 53, 0.82)),
    url('../img/about-sitges-town-wide.webp') 30% center / cover no-repeat;
  color: var(--color-white);
}

.sitges-life-section p {
  opacity: 0.92;
}

.sitges-life-section .pull-quote,
.sitges-life-section h2 {
  color: var(--color-white);
}

/* --------------------------------------------------------------------------
   26. Calendar page — two-column layout with an events panel
   Structure:
     div.calendar-layout > div.calendar-layout__calendar (wraps the existing
                            #calendar-root widget, untouched)
                          > div.calendar-layout__events > div.event-card × N
   Mobile-first: one column (calendar above events) by default, side by
   side from the 1024px breakpoint up, same tier the rest of the site uses
   for its widest multi-column layouts.
   -------------------------------------------------------------------------- */

.section--tight {
  padding-block: var(--space-5);
}

.calendar-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}

.calendar-layout__events {
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  background: var(--color-gray-50);
}

.calendar-layout__events h2 {
  margin-bottom: var(--space-5);
}

.event-card + .event-card {
  margin-top: var(--space-4);
}

.event-card__date {
  color: var(--color-gold-dark);
  font-weight: 700;
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: var(--space-2);
}

.event-card__title-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.event-card__icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--color-navy);
}

.event-card__icon svg {
  width: 100%;
  height: 100%;
}

.event-card__location {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-gray-500);
  font-size: var(--text-sm);
  margin-bottom: var(--space-3);
}

.event-card__location-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.event-card__location-icon svg {
  width: 100%;
  height: 100%;
}

@media (min-width: 1024px) {
  .calendar-layout {
    grid-template-columns: 1.2fr 1fr;
    align-items: stretch;
  }
}

/* --------------------------------------------------------------------------
   27. Team page hero — photo background
   Swaps the default corner-crest watermark (.hero::before, section 9) for
   a full-bleed player/pitch photo under the same navy-scrim technique as
   .sitges-life-section, so .hero's existing white heading text needs no
   separate color override -- only the watermark layer changes.
   -------------------------------------------------------------------------- */
.hero--team::before {
  background-image:
    linear-gradient(rgba(23, 28, 53, 0.75), rgba(23, 28, 53, 0.85)),
    url('../img/team-hero-wide.webp');
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 1;
}

/* The photo is a wide crop (900x580) of a much taller portrait shot -- on
   a short, very wide desktop hero, background-size: cover has to scale it
   up so much to fill the width that only a thin sliver of height stays
   visible, cropping the ball/feet out (confirmed: fine on mobile, where
   the hero's aspect ratio is much closer to the photo's, but not on wide
   desktop viewports). Giving the section itself more height at wider
   breakpoints keeps enough of the crop on screen without touching the
   mobile layout, which already looks right. */
@media (min-width: 768px) {
  .hero--team {
    min-height: 360px;
    display: flex;
    align-items: center;
  }
}

/* --------------------------------------------------------------------------
   28. About page — Identity section kit placeholder cards
   Two cards (home/away kit) inside .identity-section, above the section's
   own pull-quote. Structure:
     div.kit-cards > div.kit-card > (div.kit-card__thumb, div.kit-card__content)
   No real product photos exist yet (kit reveal planned end of August
   2026) -- .kit-card__thumb is a flat icon tile standing in for a photo,
   not a broken <img>. Left-aligned text inside, even though the section
   around it is .text-center, since card copy reads better left-aligned.
   -------------------------------------------------------------------------- */
.kit-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  margin-top: var(--space-6);
  margin-bottom: var(--space-6);
  text-align: left;
}

.kit-card {
  background: var(--color-white);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}

.kit-card__thumb {
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
}

.kit-card__thumb--available {
  background: var(--color-gray-100);
  color: var(--color-gray-500);
}

/* Locked/coming-soon tile uses the same navy/gold pairing as the site's
   dark sections -- gold icon on navy passes the file's own contrast rule
   (8.04:1), same as gold-on-navy text elsewhere. */
.kit-card__thumb--locked {
  background: var(--color-navy);
  color: var(--color-gold);
}

.kit-card__thumb svg {
  width: 64px;
  height: 64px;
}

.kit-card__content {
  padding: var(--space-5);
}

@media (min-width: 640px) {
  .kit-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}
