/* ═══════════════════════════════════════════════════════════════════════
   Eldoraigne bespoke landing — design system
   --------------------------------------------------------------------
   Colour palette: navy + cream + tennis green (club brand). All colours
   are CSS custom properties so they can be overridden later via an
   inline <style> from club_website_settings (hero_color / surface_color /
   footer_color / cta_color). Night mode flips the surface + text only —
   brand navy / cta green stay locked.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Palette tokens ─────────────────────────────────────────────────── */
/* Aligned to the club brand accent (#020c92 royal navy) — same colour the
   cart drawer, My Memberships drawer and other --club-accent consumers
   use. Body sits on a soft light-blue / white, dark navy text on light
   surfaces, white text on navy surfaces. Sky-blue + tennis-green kept as
   sparingly-used highlight accents. */
:root {
    /* ── Builder-shared palette vars (consumed by club-site.css) ──
       Lock the club's navy accent at :root-level so the shared cart
       drawer / My Memberships drawer / global scrollbars / .cs-btn--accent
       all use navy on EVERY bespoke page — not just the ones where
       applyClubTheme() has finished resolving the /api/public/club
       fetch. The builder CSS's fallback was orange (245,166,35), which
       is what leaked through on subpages before this. */
    --club-accent:      #020c92;
    --club-accent-rgb:  2, 12, 146;
    --club-accent-text: #ffffff;

    --el-hero:        #020c92;   /* club-brand royal navy — nav + hero banner */
    --el-hero-deep:   #000659;   /* darker shade for gradient bottoms */
    --el-surface:     #e8f1f8;   /* light blue — body */
    --el-surface-alt: #ffffff;   /* white — alt rows */
    --el-footer:      #020c92;   /* royal navy — footer */

    --el-cta:         #020c92;   /* royal navy — primary CTA on light surfaces */
    --el-cta-text:    #ffffff;   /* white on navy */
    --el-cta-inv:     #ffffff;   /* white — CTA on dark surfaces */
    --el-cta-inv-text:#020c92;   /* navy on white */

    --el-text:        #020c92;   /* royal navy body text on light */
    --el-text-muted:  rgba(2, 12, 146, 0.65);
    --el-text-inv:    #ffffff;   /* white on navy */
    --el-text-inv-muted: rgba(255, 255, 255, 0.75);

    --el-accent:      #7dd3fc;   /* sky blue — flourish + highlights (sparing) */
    --el-accent-strong:#3b82f6;  /* mid blue — active underline, focus ring */
    --el-green:       #bcff00;   /* tennis-ball green — used for loud CTAs (Book a Court pill, etc.) */
    --el-green-text:  #020c92;   /* navy text on green for contrast */

    --el-border:      rgba(2, 12, 146, 0.12);
    --el-border-inv:  rgba(255, 255, 255, 0.14);
    --el-radius:      14px;
    --el-radius-sm:   8px;
    --el-radius-lg:   24px;
    --el-shadow-sm:   0 2px 8px rgba(2, 12, 146, 0.08);
    --el-shadow:      0 12px 40px rgba(2, 12, 146, 0.14);
    --el-max-w:       1200px;
    --el-gutter:      clamp(20px, 4vw, 48px);
    --el-ease-soft:   cubic-bezier(0.22, 1, 0.36, 1);
    /* Sticky-nav rendered height — 60px min-height + 10px vertical
       padding + 1px bottom border ≈ 81px. Docked surfaces (Ace rail)
       reference this so they slot BELOW the sticky nav instead of
       sliding underneath it. */
    --el-nav-h:       81px;

    /* Shared card glow — sky-blue idle ring + halo, intense bloom on
       hover. One source of truth so every preview card, court card,
       membership card, testimonial card AND the event timeline all
       read as one visual language across the bespoke landing. */
    --el-glow-idle:
        0 0 0 1.5px rgba(125, 211, 252, 0.5),
        0 0 14px rgba(125, 211, 252, 0.35),
        0 0 32px rgba(125, 211, 252, 0.22),
        0 0 60px rgba(125, 211, 252, 0.14);
    --el-glow-hover:
        0 0 0 2px rgba(125, 211, 252, 1),
        0 0 0 6px rgba(125, 211, 252, 0.5),
        0 0 24px rgba(125, 211, 252, 0.85),
        0 0 60px rgba(125, 211, 252, 0.55),
        0 0 120px rgba(125, 211, 252, 0.35);
}

html.night-mode {
    /* Keep the club-accent locked even in night mode — the cart drawer
       / My Memberships drawer / scrollbar should still read as navy,
       not fall back to the builder's orange default. */
    --club-accent:      #020c92;
    --club-accent-rgb:  2, 12, 146;
    --club-accent-text: #ffffff;

    /* True dark mode — near-black surfaces, pure white text. Brand navy
       (--el-hero / --el-footer) stays locked so the nav + footer keep
       their royal-navy identity; only the body flips.
       Surface-alt carries a subtle navy/sky tinge (matching the hero
       overlay) so card-strip sections don't read as pure black —
       fixes the "too much black, no brand colour" feel where the
       weather strip, membership grid and other alt-rows used to
       blend into the body. */
    --el-surface:        #050505;
    --el-surface-alt:    #08152e;   /* deep navy, sky-tinged — mirrors hero in dark mode */
    --el-text:           #ffffff;
    --el-text-muted:     rgba(255, 255, 255, 0.62);
    --el-border:         rgba(255, 255, 255, 0.1);
    --el-shadow-sm:      0 2px 12px rgba(0, 0, 0, 0.5);
    --el-shadow:         0 12px 48px rgba(0, 0, 0, 0.65);
    /* On dark pages, primary CTA flips to white-on-navy (still reads as
       "the primary action"). */
    --el-cta:           #ffffff;
    --el-cta-text:      #020c92;
    /* Hint the UA to render native form widgets (select option popups,
       scrollbars, date pickers) in dark theme — otherwise the <select>
       dropdown panel falls back to white which is jarring. */
    color-scheme: dark;

    /* Night-mode card glow — same sky-blue tint but softer at idle
       (dark card surfaces are already reflective enough) and a still-
       intense bloom on hover so the accent pops off the black canvas. */
    --el-glow-idle:
        0 0 0 1.5px rgba(125, 211, 252, 0.28),
        0 0 14px rgba(125, 211, 252, 0.18),
        0 0 32px rgba(125, 211, 252, 0.1),
        0 0 60px rgba(125, 211, 252, 0.05);
    --el-glow-hover:
        0 0 0 2px rgba(125, 211, 252, 0.95),
        0 0 0 6px rgba(125, 211, 252, 0.45),
        0 0 24px rgba(125, 211, 252, 0.7),
        0 0 60px rgba(125, 211, 252, 0.4),
        0 0 120px rgba(125, 211, 252, 0.2);
}

/* ── Reset + base ───────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
    -webkit-text-size-adjust: 100%;
    /* `clip` instead of `hidden` on the html element keeps wide
       animations contained without making the page a scroll
       container. `overflow-x: hidden` on <body> killed the browser's
       native momentum-scroll deceleration on touch devices — flicks
       stopped dead instead of coasting. `clip` clips overflow without
       creating a scroll context, so iOS / Android momentum scroll
       returns to normal.
       NOTE: `scroll-behavior: smooth` was REMOVED from this rule —
       on iOS Safari + some Android Chromes it overrides the native
       kinetic scroll, producing a constant-speed glide instead of
       flick-velocity-driven momentum. Programmatic smooth scrolls
       (anchor links, scrollIntoView) still pass `behavior: 'smooth'`
       at the call site where needed. */
    overflow-x: clip;
    overscroll-behavior-y: auto;
}
/* Re-enable smooth scroll ONLY for hash-based anchor navigation
   (e.g. /preview/memberships#el-ms-grid). Doesn't affect touch. */
html:focus-within { scroll-behavior: smooth; }
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    color: var(--el-text);
    background: var(--el-surface);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    min-height: 100dvh;
    /* Defensive clamp — symptom on real Android Chrome was a white
       strip on the right side after scrolling past the hero (FABs
       become visible at that point — see is-fab-hidden). Audit found
       all FABs + drawers ARE position:fixed (out of flow), so the
       overflow source is elusive. `overflow-x: clip` here belts +
       braces the html-level clip (which alone wasn't enough on some
       mobile Chrome builds) and CANNOT regress iOS momentum scroll
       the way `overflow-x: hidden` did historically — `clip` does
       NOT create a scroll context. */
    overflow-x: clip;
    /* And cap width to 100vw so a rogue 100vw element + scrollbar
       can't push the body 10-15px wider than the visible viewport. */
    max-width: 100vw;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }

/* ── Typography primitives ──────────────────────────────────────────── */
.el-display {
    font-family: 'Inter', sans-serif;
    font-weight: 900;
    line-height: 1.02;
    letter-spacing: -0.02em;
}
.el-eyebrow {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}
/* Sky-blue italic flourish — the accent word used inside section
   titles and hero headings ("News & Events", "Membership for Every
   Player", "Club News & Updates" etc.). The Eldoraigne wordmark
   logo is set in a calligraphic humanist italic (looks like Lucida
   Calligraphy or Apple Chancery) — we use Cormorant Garamond Italic
   here as the closest FREE webfont match. It carries the same
   binocular-loop 'g' descender + rounded humanist letterforms
   that read as "of one piece" with the wordmark. Sits at 2× the
   surrounding text size. The day-mode text-shadow is layered navy
   with strong alpha + a tight 1px halo so the sky-blue letters
   keep visible weight against cream / sky-light surfaces. */
.el-italic {
    font-family: 'Cormorant Garamond', 'Apple Chancery', 'Lucida Calligraphy', Georgia, 'Times New Roman', serif;
    font-style: italic;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--el-accent);
    font-size: 2em;
    line-height: 0.92;
    padding: 0 0.04em;
    display: inline-block;
    vertical-align: baseline;
    text-shadow:
        0 1px 0 rgba(2, 12, 146, 0.55),
        0 2px 2px rgba(2, 12, 146, 0.45),
        0 4px 10px rgba(2, 12, 146, 0.4),
        0 10px 28px rgba(2, 12, 146, 0.32);
}
html.night-mode .el-italic {
    color: var(--el-accent);   /* explicit — don't let any descendant colour rule win */
    text-shadow:
        0 1px 0 rgba(0, 0, 0, 0.55),
        0 4px 14px rgba(0, 0, 0, 0.55),
        0 10px 28px rgba(0, 0, 0, 0.4);
}

/* ── Layout container ───────────────────────────────────────────────── */
.el-container {
    width: 100%;
    max-width: var(--el-max-w);
    margin: 0 auto;
    padding-left: var(--el-gutter);
    padding-right: var(--el-gutter);
}

/* ── Breadcrumb ─────────────────────────────────────────────────────── */
.el-breadcrumb {
    font-size: 0.82rem;
    color: var(--el-text-inv-muted);
    margin-bottom: 18px;
}
.el-breadcrumb a { opacity: 0.7; transition: opacity 0.15s; }
.el-breadcrumb a:hover { opacity: 1; }
.el-breadcrumb-sep { opacity: 0.5; margin: 0 8px; }

/* ── Nav ────────────────────────────────────────────────────────────── */
.el-nav {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--el-hero);
    color: var(--el-text-inv);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
/* Full-viewport-width grid: 1fr | auto | 1fr — the two 1fr rails on
   either side balance each other so the nav link list sits perfectly
   centred in the viewport, while the action buttons hug the far-right
   gutter. The nav itself spans the whole page width, not the 1200px
   content column. */
.el-nav-inner {
    max-width: none;
    width: 100%;
    margin: 0;
    padding: 10px var(--el-gutter);
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 24px;
    min-height: 60px;
}
.el-nav-links {
    grid-column: 2;
    display: flex;
    gap: 0;
    justify-content: center;
}
.el-nav-links a {
    padding: 10px 11px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--el-text-inv);
    opacity: 0.75;
    border-radius: 6px;
    position: relative;
    transition: opacity 0.2s, background 0.2s;
    white-space: nowrap;
}
.el-nav-links a:hover { opacity: 1; }
.el-nav-links a.is-active {
    opacity: 1;
    color: var(--el-accent);
}
.el-nav-links a.is-active::after {
    content: '';
    position: absolute;
    left: 14px; right: 14px;
    bottom: 4px;
    height: 2px;
    background: var(--el-accent);
    border-radius: 2px;
}
/* Home — icon-only pill at the start of the nav row. Compact so it
   doesn't push other links out of the row, and visually distinct
   (slight bg) so it reads as a 'back to start' affordance. */
.el-nav-links a.el-nav-home {
    padding: 8px 10px;
    font-size: 1.05rem;
    background: rgba(255, 255, 255, 0.06);
    line-height: 1;
    margin-right: 4px;
}
.el-nav-links a.el-nav-home:hover {
    background: rgba(125, 211, 252, 0.18);
    color: var(--el-accent);
}
.el-nav-links a.el-nav-home i { display: inline-flex; align-items: center; }

/* Community hub — dropdown that consolidates Events / News / Gallery /
   Lost & Found. Server rewrite (server.js _rewriteNavWithCommunityHub)
   injects the container; populate-club-data.js wires click-to-open,
   click-outside-close, and Escape. */
.el-nav-hub {
    position: relative;
    display: inline-flex;
    align-items: center;
}
.el-nav-hub-btn {
    /* Match .el-nav-links a so the button sits flush with sibling links. */
    padding: 10px 11px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--el-text-inv);
    opacity: 0.75;
    border: 0;
    background: transparent;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: inherit;
    white-space: nowrap;
    transition: opacity 0.2s, background 0.2s, color 0.2s;
}
.el-nav-hub-btn:hover,
.el-nav-hub-btn:focus-visible { opacity: 1; }
.el-nav-hub-btn:focus-visible {
    outline: 2px solid var(--el-accent);
    outline-offset: 2px;
}
.el-nav-hub-btn.is-active {
    opacity: 1;
    color: var(--el-accent);
}
.el-nav-hub-caret {
    font-size: 1em;
    transition: transform 0.18s ease;
    line-height: 1;
}
.el-nav-hub-btn[aria-expanded="true"] .el-nav-hub-caret { transform: rotate(180deg); }

.el-nav-hub-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 220px;
    background: var(--el-hero, #001a4d);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--el-radius, 12px);
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.42);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 1000;
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
}
.el-nav-hub-menu:not([hidden]) {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.el-nav-hub-menu[hidden] { display: flex; } /* keep flex layout so transitions animate */
.el-nav-hub-menu a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    border-radius: 6px;
    color: var(--el-text-inv, #fff);
    text-decoration: none;
    text-transform: none;
    font-weight: 600;
    font-size: 0.9rem;
    letter-spacing: 0;
    opacity: 0.88;
    transition: background 0.15s, opacity 0.15s, color 0.15s;
    white-space: nowrap;
}
.el-nav-hub-menu a:hover,
.el-nav-hub-menu a:focus-visible {
    background: rgba(255, 255, 255, 0.08);
    opacity: 1;
    color: var(--el-accent);
    outline: none;
}
.el-nav-hub-menu a i.mdi {
    width: 18px;
    text-align: center;
    opacity: 0.85;
    font-size: 1.05em;
}

.el-nav-actions {
    grid-column: 3;
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 10px;
}

/* Reused `cs-*` ids — style them with our palette instead of the builder's. */
#cs-night-toggle,
#cs-cart-btn {
    background: rgba(255, 255, 255, 0.08);
    border: 0;   /* hard border dropped — lifted glow carries the affordance */
    color: var(--el-text-inv);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    position: relative;
    box-shadow:
        0 4px 14px rgba(0, 0, 0, 0.35),
        0 0 0 1px rgba(255, 255, 255, 0.06),
        inset 0 1px 0 rgba(255, 255, 255, 0.15);
    transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
}
#cs-night-toggle:hover,
#cs-cart-btn:hover {
    background: rgba(255, 255, 255, 0.14);
    transform: translateY(-2px);
    box-shadow:
        0 8px 22px rgba(0, 0, 0, 0.45),
        0 0 0 1px rgba(125, 211, 252, 0.35),
        0 0 18px rgba(125, 211, 252, 0.35),
        inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
#cs-cart-badge {
    position: absolute;
    top: -4px; right: -4px;
    min-width: 18px; height: 18px; padding: 0 5px;
    background: var(--el-accent);
    color: var(--el-hero);
    font-size: 0.7rem; font-weight: 700;
    border-radius: 9px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* Login + user pill also rendered as 40px circles so the three action
   buttons (night / cart / login-or-user) read as a matched trio. Label
   text is hidden; mdi icon does the work. */
#cs-member-login-btn,
#cs-nav-user {
    background: rgba(255, 255, 255, 0.08);
    border: 0;
    color: var(--el-text-inv);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    padding: 0;
    box-shadow:
        0 4px 14px rgba(0, 0, 0, 0.35),
        0 0 0 1px rgba(255, 255, 255, 0.06),
        inset 0 1px 0 rgba(255, 255, 255, 0.15);
    transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
}
#cs-member-login-btn:hover,
#cs-nav-user:hover {
    background: rgba(255, 255, 255, 0.14);
    transform: translateY(-2px);
    box-shadow:
        0 8px 22px rgba(0, 0, 0, 0.45),
        0 0 0 1px rgba(125, 211, 252, 0.35),
        0 0 18px rgba(125, 211, 252, 0.35),
        inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
#cs-member-login-btn span,
#cs-nav-user span {
    /* Accessible label for screen readers; visual text hidden */
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
}

/* "Book a Court" nav pill — white on navy nav for strong contrast
   (inverse of the primary CTA pattern on the rest of the site). */
.el-btn-book {
    padding: 10px 18px;
    border-radius: 999px;
    background: #ffffff;
    color: var(--el-hero);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border: 0;
    transition: filter 0.15s, transform 0.15s, box-shadow 0.15s;
    white-space: nowrap;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2);
}
.el-btn-book:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.3);
    background: var(--el-accent);
}

.el-nav-hamburger {
    display: none;
    grid-column: 3;
    justify-self: end;
    background: none;
    border: 0;
    color: var(--el-text-inv);
    font-size: 1.6rem;
    padding: 8px;
}

/* ── Hero (page-agnostic — uses data-page modifiers for copy variants) ── */
.el-hero {
    background: var(--el-hero);
    color: var(--el-text-inv);
    padding: 72px 0 92px;
    position: relative;
    overflow: hidden;
}
.el-hero--home {
    /* Full-display-height hero. `100dvh` honours mobile browser chrome
       (URL bars collapse/expand) without the overflow that 100vh causes;
       fallback to 100vh for browsers that don't support dvh. */
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 120px 0 140px;
    text-align: center;
}
.el-hero::after {
    /* Minimal navy wash — just enough to keep the hero text readable
       without obscuring the photo. Near-transparent over the centre
       (where the copy sits) and only a light edge tint. */
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at center, rgba(2, 12, 146, 0.08) 0%, rgba(2, 12, 146, 0.18) 70%, rgba(0, 6, 89, 0.3) 100%),
        linear-gradient(180deg, transparent 0%, transparent 50%, rgba(0, 6, 89, 0.18) 100%);
    pointer-events: none;
    z-index: 0;
}
/* Hero logo — editable via data-img-slot="hero-logo". Light mode
   carries a soft sky-blue drop-shadow glow; night mode plays a
   fluorescent-tube startup flicker on every page mount and on every
   night-mode toggle (via the .is-hero-glow class re-applied by
   eldoraigne.js). */
.el-hero-logo {
    display: block;
    /* Anchored at bottom-centre — committee can resize via the
       edit-mode slider and the bottom edge stays fixed (logo grows
       upward + outward). The width is `base × (--img-size-pct / 100)`
       where the base scales with viewport via clamp(). */
    --img-size-pct: 100;
    margin: 0 auto 28px;
    width: calc(clamp(180px, 22vw, 320px) * (var(--img-size-pct) / 100));
    height: auto;
    object-fit: contain;
    position: relative;
    z-index: 1;
    transform-origin: bottom center;
    /* Day-mode glow */
    filter:
        drop-shadow(0 0 6px rgba(125, 211, 252, 0.55))
        drop-shadow(0 0 18px rgba(125, 211, 252, 0.4))
        drop-shadow(0 0 36px rgba(125, 211, 252, 0.25));
    transition: filter 0.6s ease, width 0.18s ease;
}
@media (max-width: 720px) {
    /* Logo was too small on phones — the hero headline below it ended
       up dwarfing the brand mark. Bumped baseline + viewport-share so
       the logo reads as the dominant element on narrow screens. */
    .el-hero-logo {
        margin-bottom: 22px;
        width: calc(clamp(220px, 60vw, 340px) * (var(--img-size-pct, 100) / 100));
    }
}
/* Night-mode flicker animation — sharp random flickers for the
   first ~1 s like a cold fluorescent tube striking, then a soft
   steady accent halo over the remaining ~4 s. */
@keyframes el-hero-flicker-logo {
    0%, 1%   { filter: drop-shadow(0 0 0 transparent); }
    2%       { filter: drop-shadow(0 0 6px rgba(255,255,255,0.85)) drop-shadow(0 0 14px var(--el-accent)); }
    3%, 5%   { filter: drop-shadow(0 0 0 transparent); }
    6%       { filter: drop-shadow(0 0 8px rgba(255,255,255,0.9))  drop-shadow(0 0 18px var(--el-accent)); }
    7%, 9%   { filter: drop-shadow(0 0 0 transparent); }
    10%      { filter: drop-shadow(0 0 5px rgba(255,255,255,0.6))  drop-shadow(0 0 12px var(--el-accent)); }
    11%, 13% { filter: drop-shadow(0 0 2px rgba(255,255,255,0.3)); }
    16%      { filter: drop-shadow(0 0 4px rgba(255,255,255,0.4))  drop-shadow(0 0 10px var(--el-accent)); }
    100%     { filter:
                drop-shadow(0 0 2px var(--el-accent))
                drop-shadow(0 0 14px var(--el-accent))
                drop-shadow(0 0 32px var(--el-accent)); }
}
html.night-mode .el-hero-logo {
    animation: el-hero-flicker-logo 5s cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
}
html.night-mode .el-hero.is-hero-glow .el-hero-logo {
    /* Replay the flicker — JS removes + re-adds .is-hero-glow on
       toggle so we use a different animation-name here to force a
       restart even when the keyframes are identical. */
    animation: el-hero-flicker-logo 5s cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
}
@media (prefers-reduced-motion: reduce) {
    html.night-mode .el-hero-logo {
        animation: none;
        filter:
            drop-shadow(0 0 2px var(--el-accent))
            drop-shadow(0 0 14px var(--el-accent))
            drop-shadow(0 0 32px var(--el-accent));
    }
}

.el-hero-eyebrow {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--el-accent);
    opacity: 0.9;
    margin-bottom: 18px;
}
.el-hero-title {
    font-size: clamp(2.4rem, 5.5vw, 4.5rem);
    margin: 0 0 14px;
}
.el-hero-title--home {
    font-size: clamp(3.2rem, 9vw, 6.8rem);
    line-height: 0.98;
}
/* Hero italic — sky blue flourish on the navy hero. The home hero is
   already massive (clamp 3.2–6.8rem) so its italic stays in-line at
   1em to avoid blowing out the layout. Inner-page heroes are more
   modest (clamp 2.4–4.5rem) so their italic doubles to 2em for a
   proper "fancy flourish" moment. Drop-shadow swaps to a deeper
   black so the flourish lifts cleanly off the dark hero surface. */
.el-hero-title .el-italic {
    color: var(--el-accent);
    font-size: 1em;
    line-height: 1;
    padding: 0 0.06em;
    display: inline-block;
    text-shadow:
        0 10px 32px rgba(0, 0, 0, 0.55),
        0 4px 12px rgba(0, 0, 0, 0.4),
        0 2px 4px rgba(0, 0, 0, 0.3);
}
.el-hero-title:not(.el-hero-title--home) .el-italic {
    font-size: 2em;
    line-height: 0.92;
    /* Non-home heroes ditch the black drop-shadow and pick up a
       white-and-sky shimmer instead — two stacked halos that
       cross-fade on a 4.5 s loop so the italic flourish breathes
       between bright-white and sky-blue dominance. */
    text-shadow:
        0 0 12px rgba(255, 255, 255, 0.55),
        0 0 28px rgba(125, 211, 252, 0.45),
        0 0 56px rgba(125, 211, 252, 0.25);
    animation: el-hero-italic-shimmer 4.5s ease-in-out infinite;
}
@keyframes el-hero-italic-shimmer {
    0%, 100% {
        text-shadow:
            0 0 12px rgba(255, 255, 255, 0.55),
            0 0 28px rgba(125, 211, 252, 0.45),
            0 0 56px rgba(125, 211, 252, 0.25);
    }
    50% {
        text-shadow:
            0 0 14px rgba(125, 211, 252, 0.70),
            0 0 32px rgba(255, 255, 255, 0.40),
            0 0 64px rgba(125, 211, 252, 0.30);
    }
}
@media (prefers-reduced-motion: reduce) {
    .el-hero-title:not(.el-hero-title--home) .el-italic {
        animation: none;
    }
}
.el-hero-sub {
    font-size: clamp(0.95rem, 1.4vw, 1.1rem);
    max-width: 620px;
    color: var(--el-text-inv-muted);
    margin: 0 auto 24px;
    line-height: 1.55;
}
.el-hero--home .el-hero-sub { margin-inline: auto; }
.el-hero:not(.el-hero--home) .el-hero-sub { margin-inline: 0; }
.el-hero-meta {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    font-size: 0.82rem;
    color: var(--el-text-inv-muted);
}
.el-hero-meta .mdi { font-size: 1rem; margin-right: 4px; vertical-align: -2px; color: var(--el-accent); }
.el-hero-chips {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 20px;
}
.el-hero-chip {
    padding: 6px 14px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.16);
    font-size: 0.78rem;
    color: var(--el-text-inv);
}
.el-hero-ctas {
    display: flex;
    gap: 14px;
    justify-content: center;
    margin-top: 32px;
    flex-wrap: wrap;
}

/* ── Buttons ────────────────────────────────────────────────────────── */
.el-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px 28px;
    border-radius: 999px;
    font-size: 0.9rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border: 0;
    transition: transform 0.2s var(--el-ease-soft), filter 0.2s, box-shadow 0.2s;
    white-space: nowrap;
}
/* Primary CTA. On light surfaces → navy bg, white text. On dark surfaces
   (e.g. inside .el-hero) the .el-btn--inverse modifier flips to white bg
   navy text so it still reads as "the primary action". */
.el-btn--cta {
    background: var(--el-cta);
    color: var(--el-cta-text);
    box-shadow: 0 8px 24px rgba(2, 12, 146, 0.25);
}
.el-btn--cta:hover {
    transform: translateY(-2px);
    filter: brightness(1.1);
    box-shadow: 0 12px 32px rgba(2, 12, 146, 0.35);
}
/* Inverse primary — used inside the hero (dark surface) where a navy
   button would disappear. White bg, navy text. */
.el-btn--inverse {
    background: var(--el-cta-inv);
    color: var(--el-cta-inv-text);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}
.el-btn--inverse:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
    filter: brightness(1.02);
}
/* Secondary outline — transparent bg with white border on dark surfaces.
   Scoped inside .el-hero so it adapts to the dark context automatically. */
.el-btn--outline {
    background: transparent;
    color: var(--el-text);
    border: 1.5px solid var(--el-border);
}
.el-btn--outline:hover {
    background: rgba(2, 12, 146, 0.06);
    border-color: var(--el-text);
}
/* When an outline button sits inside the hero, flip to a light-border
   variant so it reads on the navy canvas. */
.el-hero .el-btn--outline {
    color: var(--el-text-inv);
    border-color: rgba(255, 255, 255, 0.4);
}
.el-hero .el-btn--outline:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.7);
}
.el-btn--ghost {
    background: transparent;
    color: var(--el-text);
    padding: 10px 18px;
    font-size: 0.8rem;
    border: 1.5px solid var(--el-border);
}
.el-btn--ghost:hover {
    border-color: var(--el-text);
    transform: translateY(-1px);
}

/* ── Section ────────────────────────────────────────────────────────── */
.el-section {
    padding: clamp(56px, 9vw, 120px) 0;
    position: relative;
}
.el-section--alt { background: var(--el-surface-alt); }  /* alt-row on surface */
/* Night mode — alt-rows blend with the surrounding base sections.
   The page reads as one near-black field with the section-edge glow
   above acting as the only divider between rows. To dial in a richer
   blue-transparent treatment for a specific section, add the
   `el-section--hero-blue` modifier alongside `--alt`. */
html.night-mode .el-section--alt {
    background: var(--el-surface);
}

/* ── Hero-blue section modifier ──────────────────────────────────────
   Opt-in night-mode treatment: paints a soft navy + sky-blue wash over
   the section surface (subtle — the dark base still shows through) and
   turns every inner card — view toggles, year/month strip, timeline
   rect, calendar wrapper, day cells — into transparent cutouts framed
   in faint sky blue. Active items (current view, focused chip, has-event
   days) lift with a stronger sky tint + glow so they read as the focal
   points. Day mode is unchanged. Apply per-section as we approve each. */
html.night-mode .el-section--hero-blue {
    /* Flat navy tint over the dark surface — same idea as the gradient
       but uniform across the section. Low alpha keeps it subtle so the
       starfield and cutouts still read clearly. */
    background:
        linear-gradient(rgba(2, 12, 146, 0.18), rgba(2, 12, 146, 0.18)),
        var(--el-surface);
}
html.night-mode .el-section--hero-blue .el-res-today,
html.night-mode .el-section--hero-blue .el-res-view,
html.night-mode .el-section--hero-blue .el-res-day {
    background: transparent;
    border: 1px solid rgba(125, 211, 252, 0.18);
    box-shadow:
        inset 0 0 12px rgba(125, 211, 252, 0.05),
        0 0 6px rgba(125, 211, 252, 0.06);
    color: var(--el-text);
}
html.night-mode .el-section--hero-blue .el-res-view {
    box-shadow:
        inset 0 0 0 2px rgba(125, 211, 252, 0.18),
        inset 0 0 12px rgba(125, 211, 252, 0.05),
        0 0 6px rgba(125, 211, 252, 0.06);
    border: 0;
}
html.night-mode .el-section--hero-blue .el-res-view.is-active,
html.night-mode .el-section--hero-blue .el-res-day.is-active {
    background: rgba(125, 211, 252, 0.12);
    border-color: rgba(125, 211, 252, 0.45);
    color: var(--el-text);
    box-shadow:
        inset 0 0 0 2px rgba(125, 211, 252, 0.45),
        inset 0 0 22px rgba(125, 211, 252, 0.14),
        0 0 18px rgba(125, 211, 252, 0.28);
}
/* Outer wrappers (timeline rect, calendar card, day grid) keep their
   default night-mode dark fill — they're the "container" the cutouts
   sit inside. The day cells below render transparent so the dark
   wrapper bg shows through them, not the section's navy tint. */
html.night-mode .el-section--hero-blue .el-ev-cal-cell {
    background: transparent;
    border-color: rgba(125, 211, 252, 0.28);
    box-shadow:
        inset 0 0 18px rgba(125, 211, 252, 0.10),
        0 0 14px rgba(125, 211, 252, 0.14);
    transition:
        transform 0.18s var(--el-ease-soft, ease-out),
        box-shadow 0.25s var(--el-ease-soft, ease-out),
        border-color 0.25s var(--el-ease-soft, ease-out);
    will-change: transform;
}
html.night-mode .el-section--hero-blue .el-ev-cal-cell.has-event:not(.is-today) {
    background: rgba(125, 211, 252, 0.14);
    border-color: rgba(125, 211, 252, 0.55);
    box-shadow:
        inset 0 0 26px rgba(125, 211, 252, 0.22),
        0 0 28px rgba(125, 211, 252, 0.42);
}
/* Hover lift — slight scale + intensified glow on any day cell that
   isn't blank. Today already has its solid navy fill so we leave it
   alone (a glow doesn't add much to a solid colour). */
html.night-mode .el-section--hero-blue .el-ev-cal-cell:not(.el-ev-cal-cell--blank):not(.is-today):hover {
    transform: scale(1.04);
    border-color: rgba(125, 211, 252, 0.7);
    box-shadow:
        inset 0 0 30px rgba(125, 211, 252, 0.20),
        0 0 32px rgba(125, 211, 252, 0.45);
    z-index: 2;
}
html.night-mode .el-section--hero-blue .el-ev-cal-cell.has-event:not(.is-today):hover {
    transform: scale(1.04);
    border-color: rgba(125, 211, 252, 0.85);
    box-shadow:
        inset 0 0 34px rgba(125, 211, 252, 0.32),
        0 0 42px rgba(125, 211, 252, 0.62);
    z-index: 2;
}
/* Override the generic .el-ev-cal-cell.is-clickable.has-event:hover
   white-wash that ships earlier in the file — within hero-blue we want
   the sky-blue hover treatment to win. */
html.night-mode .el-section--hero-blue .el-ev-cal-cell.is-clickable.has-event:hover {
    background: rgba(125, 211, 252, 0.18);
    border-color: rgba(125, 211, 252, 0.85);
}
/* News cards inside a hero-blue section are CONTAINERS (image + text
   inside) — they should keep a solid dark fill so the section's blue
   tint shows around them but never bleeds through the card surface.
   This overrides the global .el-news-card transparent rule which was
   designed for the older tinted-section treatment. */
html.night-mode .el-section--hero-blue .el-news-card,
html.night-mode .el-section--hero-blue .el-news-featured {
    background: #12141b;
    border: 1px solid rgba(125, 211, 252, 0.18);
}
html.night-mode .el-section--hero-blue .el-news-card:hover {
    border-color: rgba(125, 211, 252, 0.45);
    box-shadow:
        var(--el-glow-hover),
        0 0 28px rgba(125, 211, 252, 0.28);
}
/* Member-Benefits exception — when the benefits section gets the
   hero-blue treatment, the section bg shifts to the standard tinted
   dark surface, but the BENEFIT CARDS should KEEP their existing
   bright-navy look (the original section design used navy cards on a
   navy gradient and the user wants that visual preserved). Force a
   solid navy fill on the cards so they read as blue tiles regardless
   of the new section backdrop. */
html.night-mode .el-section--hero-blue.el-ms-benefits .el-ms-benefit {
    background:
        linear-gradient(rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.04)),
        var(--el-hero);
}
html.night-mode .el-section--hero-blue.el-ms-benefits .el-ms-benefit:hover {
    background:
        linear-gradient(rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.08)),
        var(--el-hero);
}

/* ── Compare-table interactions: column hover + populate cascade ────
   These rules are NOT scoped to .el-section--hero-blue — the table
   is currently rendered in only one place but the behaviour is part
   of the table itself, not the section theming. */

/* Column hover — every cell with data-col-i in the hovered column
   gets a sky-blue tint. Pairs with the existing tr:hover row tint. */
html.night-mode .el-ms-compare [data-col-i].is-col-hover {
    background: rgba(125, 211, 252, 0.10);
}
.el-ms-compare [data-col-i].is-col-hover {
    background: color-mix(in srgb, var(--el-accent, #7dd3fc) 12%, transparent);
}
/* Frozen first column overrides the hover tint with its own bg, so
   re-apply the hover layer when the first column itself is hovered. */
html.night-mode .el-ms-compare thead th[data-col-i="0"].is-col-hover,
html.night-mode .el-ms-compare tbody th[data-col-i="0"].is-col-hover {
    background: color-mix(in srgb, var(--el-accent, #7dd3fc) 14%, #0a0a0f);
}

/* Populate cascade — every cell starts faded + slightly down, then
   reveals with a per-column delay when the table is `.is-populated`.
   Removing the class (when scrolled out of view) reverses it, so
   re-entering the section replays the cascade. */
.el-ms-compare [data-col-i] {
    opacity: 0;
    transform: translateY(8px);
    transition:
        opacity 0.5s var(--el-ease-soft, cubic-bezier(0.22, 1, 0.36, 1)),
        transform 0.5s var(--el-ease-soft, cubic-bezier(0.22, 1, 0.36, 1)),
        background 0.18s ease;
    transition-delay: calc(var(--col-i, 0) * 60ms), calc(var(--col-i, 0) * 60ms), 0s;
}
.el-ms-compare.is-populated [data-col-i] {
    opacity: 1;
    transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
    .el-ms-compare [data-col-i] {
        opacity: 1;
        transform: none;
        transition: background 0.18s ease;
    }
}

/* ── Section edge glow ─────────────────────────────────────────────────
   Every section / preview strip / footer gets a luminous navy line at
   the top edge with a soft outer bloom, so boundaries between sections
   read as glowing seams rather than hard steps. The ::before sits
   absolutely on the section's own top edge and fades to transparent at
   the horizontal ends so it doesn't clash with the page gutter. */
.el-section::before,
.el-preview-strip::before,
.el-footer::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(2, 12, 146, 0.35) 12%,
        rgba(2, 12, 146, 0.75) 50%,
        rgba(2, 12, 146, 0.35) 88%,
        transparent 100%);
    box-shadow:
        0 0 14px rgba(2, 12, 146, 0.55),
        0 0 30px rgba(2, 12, 146, 0.3);
    pointer-events: none;
    z-index: 2;
}
.el-preview-strip { position: relative; }
.el-footer        { position: relative; }

/* Night-mode edge glow — switch to a white glow so it pops off the
   black surfaces instead of disappearing into the navy-on-black. */
html.night-mode .el-section::before,
html.night-mode .el-preview-strip::before,
html.night-mode .el-footer::before {
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.18) 12%,
        rgba(255, 255, 255, 0.45) 50%,
        rgba(255, 255, 255, 0.18) 88%,
        transparent 100%);
    box-shadow:
        0 0 14px rgba(255, 255, 255, 0.28),
        0 0 30px rgba(255, 255, 255, 0.16);
}
/* Section + preview headers are ALWAYS centre-justified across the
   bespoke site. Sub copy is capped to a readable width and centred
   with auto margins. The text-align override reaches into the
   preview-header wrapper-div that the home-page strips use. */
.el-section-header,
.el-preview-header {
    margin-bottom: 40px;
    text-align: center;
}
.el-preview-header > div {
    /* preview-header wraps its eyebrow/title/sub inside an extra
       <div> so flexbox can align them next to a CTA column on the
       right. When we centre, kill that flex flow and let the wrapper
       span the available width so auto-margins work. */
    width: 100%;
    max-width: 780px;
    margin: 0 auto;
}
.el-preview-header {
    justify-content: center;
}
.el-section-eyebrow {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    margin-bottom: 10px;
}
.el-section-title {
    font-size: clamp(1.8rem, 3.6vw, 2.6rem);
    font-weight: 800;
    line-height: 1.12;
    letter-spacing: -0.02em;
    color: var(--el-text);
    margin: 0;
}
.el-section-sub {
    font-size: 0.98rem;
    color: var(--el-text-muted);
    max-width: 620px;
    /* auto left/right keeps the copy centred under the title when
       the header wrapper's text-align:center can't carry block-level
       paragraphs alone. */
    margin: 12px auto 0;
    line-height: 1.6;
}
/* Optional centered CTA below a grid (court cards, etc.) */
.el-section-cta {
    display: flex;
    justify-content: center;
    margin-top: 40px;
}

/* ── Card ───────────────────────────────────────────────────────────── */
.el-card {
    background: #ffffff;
    border: 1px solid var(--el-border);
    border-radius: var(--el-radius);
    padding: 24px;
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s;
}
html.night-mode .el-card {
    background: rgba(255, 255, 255, 0.04);
    border-color: var(--el-border);
}
.el-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--el-shadow);
}
.el-card-title { font-size: 1.1rem; font-weight: 700; margin: 0 0 8px; }
.el-card-sub   { font-size: 0.88rem; color: var(--el-text-muted); margin: 0; }

/* ── Coming-soon placeholder card (Phase 1 stubs) ───────────────────── */
.el-coming-soon {
    max-width: 540px;
    margin: 0 auto;
    padding: 56px 32px;
    text-align: center;
    background: #ffffff;
    border: 1px dashed var(--el-border);
    border-radius: var(--el-radius);
    box-shadow: var(--el-shadow-sm);
}
html.night-mode .el-coming-soon {
    background: rgba(255, 255, 255, 0.03);
    border-color: rgba(255, 255, 255, 0.1);
}
.el-coming-soon .mdi {
    font-size: 3rem;
    color: var(--el-accent);
    opacity: 0.7;
    margin-bottom: 12px;
}
.el-coming-soon h2 {
    font-size: 1.4rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    margin: 0 0 10px;
}
.el-coming-soon p {
    color: var(--el-text-muted);
    margin: 0;
    font-size: 0.95rem;
}
.el-coming-soon a {
    color: var(--el-accent-strong);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ── Footer ─────────────────────────────────────────────────────────── */
.el-footer {
    background: var(--el-footer);
    color: var(--el-text-inv);
    padding: 64px 0 28px;
    margin-top: auto;
}
.el-footer-grid {
    display: grid;
    /* Six explicit columns on wide desktop: Brand, Explore, More,
       Club Info, Hours, Legal (Legal only rendered when club has
       published docs — see populate-club-data.js injectLegalFooter).
       Mixing 1.4fr with repeat(auto-fit) was unreliable — auto-fit
       and fractional siblings don't compose well. Explicit tracks
       with an intermediate 3-col breakpoint below give predictable
       layout at every width. */
    grid-template-columns: 1.4fr 1fr 1fr 1.2fr 1.2fr 1fr;
    gap: 32px;
    margin-bottom: 40px;
}
.el-footer-brand { display: flex; flex-direction: column; gap: 10px; }
.el-footer-logo  { display: flex; align-items: center; gap: 10px; font-weight: 700; }
/* Belt-and-braces: some clubs' hero-logo blob is very large intrinsically,
   and populate-club-data.js swaps the footer-logo src to that same blob.
   Force 32×32 regardless of container class or intrinsic dimensions. */
.el-footer-logo img,
.el-footer img[data-img-slot="footer-logo"] {
    width: 32px !important;
    height: 32px !important;
    max-width: 32px !important;
    max-height: 32px !important;
    object-fit: contain;
    border-radius: 50%;
    background: rgba(255,255,255,0.1);
    flex-shrink: 0;
}
.el-footer-tag   { font-size: 0.85rem; color: var(--el-text-inv-muted); }
.el-footer-socials { display: flex; gap: 10px; margin-top: 6px; }
.el-footer-socials a {
    width: 36px; height: 36px;
    border-radius: 50%;
    background: rgba(255,255,255,0.08);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    color: var(--el-text-inv);
    transition: background 0.15s, transform 0.15s;
}
.el-footer-socials a:hover { background: var(--el-accent); color: var(--el-hero); transform: translateY(-2px); }
.el-footer-col-title {
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--el-text-inv);
    opacity: 0.9;
    margin-bottom: 14px;
}
.el-footer-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.el-footer-list a, .el-footer-list li {
    font-size: 0.86rem;
    color: var(--el-text-inv-muted);
    transition: color 0.15s;
}
.el-footer-list a:hover { color: var(--el-accent); }
.el-footer-list .mdi { margin-right: 8px; color: var(--el-accent); opacity: 0.9; font-size: 0.95rem; vertical-align: -1px; }
.el-footer-sub { font-size: 0.76rem; color: var(--el-text-inv-muted); margin-top: 2px; }
.el-footer-bar {
    border-top: 1px solid rgba(255,255,255,0.08);
    padding-top: 20px;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    font-size: 0.78rem;
    color: var(--el-text-inv-muted);
}
.el-footer-bar a { color: inherit; opacity: 0.85; }
.el-footer-bar a:hover { opacity: 1; color: var(--el-accent); }
.el-footer-legal { display: inline-flex; gap: 8px; align-items: center; }
.el-footer-legal span { opacity: 0.4; }

/* ── Animation — stagger fade-in on scroll ──────────────────────────── */
.el-reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.9s var(--el-ease-soft), transform 0.9s var(--el-ease-soft);
}
.el-reveal.is-visible {
    opacity: 1;
    transform: translate(0, 0);
}

/* ── Section-header scroll animation (every pass) ─────────────────
   Applied to .el-section-header + .el-preview-header on every page.
   Eyebrow → title → sub fade in staggered when scrolling INTO
   view; reverse stagger (with the sub using a clip-path top-to-
   bottom exit so the TOP line fades first) when the header
   scrolls ABOVE the viewport. Classes (el-hdr-in / el-hdr-out-top
   / el-hdr-out-bottom) are toggled by an IntersectionObserver in
   eldoraigne.js — see the "Section-header scroll-in / scroll-out"
   block there.
   ───────────────────────────────────────────────────────────── */
.el-section-header .el-section-eyebrow,
.el-preview-header .el-preview-eyebrow,
.el-section-header .el-section-title,
.el-preview-header .el-preview-title,
.el-section-header .el-section-sub,
.el-preview-header .el-preview-sub {
    transition-property: opacity, transform, clip-path;
    transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
}
/* Default + exit-to-bottom state — hidden, sits 30px below its
   final position (entry origin) */
.el-section-header .el-section-eyebrow,
.el-preview-header .el-preview-eyebrow {
    opacity: 0;
    transform: translateY(30px);
    transition-duration: 0.5s;
}
.el-section-header .el-section-title,
.el-preview-header .el-preview-title {
    opacity: 0;
    transform: translateY(30px);
    transition-duration: 0.6s;
}
.el-section-header .el-section-sub,
.el-preview-header .el-preview-sub {
    opacity: 0;
    clip-path: inset(0 0 100% 0);   /* hidden, about to reveal top-first */
    transition-duration: 0.7s;
}
/* Entry — staggered eyebrow → title → sub */
.el-hdr-in .el-section-eyebrow,
.el-hdr-in .el-preview-eyebrow {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 0.08s;
}
.el-hdr-in .el-section-title,
.el-hdr-in .el-preview-title {
    opacity: 1;
    transform: translateY(0);
    transition-delay: 0.22s;
}
.el-hdr-in .el-section-sub,
.el-hdr-in .el-preview-sub {
    opacity: 1;
    clip-path: inset(0 0 0 0);
    transition-delay: 0.4s;
}
/* Exit via TOP — same stagger order, upward slide for eyebrow +
   title, sub clips top-to-bottom so its TOP line disappears first */
.el-hdr-out-top .el-section-eyebrow,
.el-hdr-out-top .el-preview-eyebrow {
    opacity: 0;
    transform: translateY(-30px);
    transition-delay: 0s;
}
.el-hdr-out-top .el-section-title,
.el-hdr-out-top .el-preview-title {
    opacity: 0;
    transform: translateY(-30px);
    transition-delay: 0.12s;
}
.el-hdr-out-top .el-section-sub,
.el-hdr-out-top .el-preview-sub {
    opacity: 0;
    clip-path: inset(100% 0 0 0);   /* top line fades first */
    transition-delay: 0.28s;
}
/* ── Hero + footer scroll animation — same stagger as section headers
   Eyebrow → title → sub; exit reverses direction. Wired to the same
   IntersectionObserver that toggles el-hdr-in / el-hdr-out-top on
   .el-section-header (see eldoraigne.js). */
.el-hero .el-hero-eyebrow,
.el-hero .el-hero-title,
.el-hero .el-hero-sub {
    transition-property: opacity, transform, clip-path;
    transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
}
.el-hero .el-hero-eyebrow {
    opacity: 0;
    transform: translateY(30px);
    transition-duration: 0.5s;
}
.el-hero .el-hero-title {
    opacity: 0;
    transform: translateY(30px);
    transition-duration: 0.6s;
}
.el-hero .el-hero-sub {
    opacity: 0;
    clip-path: inset(0 0 100% 0);
    transition-duration: 0.7s;
}
.el-hero.el-hdr-in .el-hero-eyebrow { opacity: 1; transform: translateY(0); transition-delay: 0.08s; }
.el-hero.el-hdr-in .el-hero-title   { opacity: 1; transform: translateY(0); transition-delay: 0.22s; }
.el-hero.el-hdr-in .el-hero-sub     { opacity: 1; clip-path: inset(0 0 0 0); transition-delay: 0.4s; }
.el-hero.el-hdr-out-top .el-hero-eyebrow { opacity: 0; transform: translateY(-30px); transition-delay: 0s; }
.el-hero.el-hdr-out-top .el-hero-title   { opacity: 0; transform: translateY(-30px); transition-delay: 0.12s; }
.el-hero.el-hdr-out-top .el-hero-sub     { opacity: 0; clip-path: inset(100% 0 0 0); transition-delay: 0.28s; }

/* Per-page CTA card (.el-cta-card) — staggered eyebrow → title →
   sub → actions → contact line, mirroring the section-header timing.
   Reverse direction when scrolled past the top. */
.el-cta-card .el-cta-card-eyebrow,
.el-cta-card .el-cta-card-title,
.el-cta-card .el-cta-card-sub,
.el-cta-card .el-cta-card-actions,
.el-cta-card .el-cta-card-contact {
    transition-property: opacity, transform, clip-path;
    transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
}
.el-cta-card .el-cta-card-eyebrow,
.el-cta-card .el-cta-card-title,
.el-cta-card .el-cta-card-actions,
.el-cta-card .el-cta-card-contact {
    opacity: 0;
    transform: translateY(28px);
    transition-duration: 0.5s;
}
.el-cta-card .el-cta-card-sub {
    opacity: 0;
    clip-path: inset(0 0 100% 0);
    transition-duration: 0.65s;
}
.el-cta-card.el-hdr-in .el-cta-card-eyebrow  { opacity: 1; transform: translateY(0); transition-delay: 0.08s; }
.el-cta-card.el-hdr-in .el-cta-card-title    { opacity: 1; transform: translateY(0); transition-delay: 0.22s; }
.el-cta-card.el-hdr-in .el-cta-card-sub      { opacity: 1; clip-path: inset(0 0 0 0); transition-delay: 0.4s; }
.el-cta-card.el-hdr-in .el-cta-card-actions  { opacity: 1; transform: translateY(0); transition-delay: 0.55s; }
.el-cta-card.el-hdr-in .el-cta-card-contact  { opacity: 1; transform: translateY(0); transition-delay: 0.7s; }
.el-cta-card.el-hdr-out-top .el-cta-card-eyebrow  { opacity: 0; transform: translateY(-28px); transition-delay: 0s; }
.el-cta-card.el-hdr-out-top .el-cta-card-title    { opacity: 0; transform: translateY(-28px); transition-delay: 0.12s; }
.el-cta-card.el-hdr-out-top .el-cta-card-sub      { opacity: 0; clip-path: inset(100% 0 0 0); transition-delay: 0.28s; }
.el-cta-card.el-hdr-out-top .el-cta-card-actions  { opacity: 0; transform: translateY(-28px); transition-delay: 0.42s; }
.el-cta-card.el-hdr-out-top .el-cta-card-contact  { opacity: 0; transform: translateY(-28px); transition-delay: 0.55s; }

/* Ready-to-Play closing CTA — same stagger feel as section headers.
   Eyebrow, title, sub, and the CTA row each fade up with their own
   delay; reverse direction when scrolled past the top. */
.el-ready .el-ready-eyebrow,
.el-ready .el-ready-title,
.el-ready .el-ready-sub,
.el-ready .el-ready-ctas {
    transition-property: opacity, transform, clip-path;
    transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
}
.el-ready .el-ready-eyebrow { opacity: 0; transform: translateY(28px); transition-duration: 0.5s; }
.el-ready .el-ready-title   { opacity: 0; transform: translateY(28px); transition-duration: 0.6s; }
.el-ready .el-ready-sub     { opacity: 0; clip-path: inset(0 0 100% 0); transition-duration: 0.7s; }
.el-ready .el-ready-ctas    { opacity: 0; transform: translateY(28px); transition-duration: 0.55s; }
.el-ready.el-hdr-in .el-ready-eyebrow { opacity: 1; transform: translateY(0); transition-delay: 0.08s; }
.el-ready.el-hdr-in .el-ready-title   { opacity: 1; transform: translateY(0); transition-delay: 0.22s; }
.el-ready.el-hdr-in .el-ready-sub     { opacity: 1; clip-path: inset(0 0 0 0); transition-delay: 0.4s; }
.el-ready.el-hdr-in .el-ready-ctas    { opacity: 1; transform: translateY(0); transition-delay: 0.55s; }
.el-ready.el-hdr-out-top .el-ready-eyebrow { opacity: 0; transform: translateY(-28px); transition-delay: 0s; }
.el-ready.el-hdr-out-top .el-ready-title   { opacity: 0; transform: translateY(-28px); transition-delay: 0.12s; }
.el-ready.el-hdr-out-top .el-ready-sub     { opacity: 0; clip-path: inset(100% 0 0 0); transition-delay: 0.28s; }
.el-ready.el-hdr-out-top .el-ready-ctas    { opacity: 0; transform: translateY(-28px); transition-delay: 0.42s; }

/* Footer — brand/tag + bottom bar fade in with the same feel; the
   four content columns cascade via .el-footer-grid > * below. */
.el-footer .el-footer-brand,
.el-footer .el-footer-bar {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.el-footer.el-hdr-in .el-footer-brand { opacity: 1; transform: translateY(0); transition-delay: 0.1s; }
.el-footer.el-hdr-in .el-footer-bar   { opacity: 1; transform: translateY(0); transition-delay: 0.45s; }
.el-footer.el-hdr-out-top .el-footer-brand { opacity: 0; transform: translateY(-24px); transition-delay: 0s; }
.el-footer.el-hdr-out-top .el-footer-bar   { opacity: 0; transform: translateY(-24px); transition-delay: 0.15s; }

/* Reduced-motion — skip the stagger entirely */
@media (prefers-reduced-motion: reduce) {
    .el-section-header .el-section-eyebrow,
    .el-preview-header .el-preview-eyebrow,
    .el-section-header .el-section-title,
    .el-preview-header .el-preview-title,
    .el-section-header .el-section-sub,
    .el-preview-header .el-preview-sub,
    .el-hero .el-hero-eyebrow,
    .el-hero .el-hero-title,
    .el-hero .el-hero-sub,
    .el-footer .el-footer-brand,
    .el-footer .el-footer-bar {
        opacity: 1;
        transform: none;
        clip-path: none;
        transition: none;
    }
}

/* ── Card-grid cascade (every pass) ───────────────────────────────
   Children of any of the grid selectors below slide UP from +48px
   with fading opacity, staggered by --card-idx (set by
   eldoraigne.js on first observe). Classes on the parent grid:
     el-cascade-in         → children slide up into place
     el-cascade-out-top    → children slide UP off the top and fade
     el-cascade-out-bottom → default hidden state (below viewport)
   ───────────────────────────────────────────────────────────── */
.el-preview-cards > *,
.el-court-cards > *,
.el-ms-grid > *,
.el-testimonial-grid > *,
.el-sp-grid > *,
.el-coach-grid > *,
.el-coach-progs > *,
.el-ms-benefits-grid > *,
.el-visit-grid > *,
.el-weekly-grid > *,
.el-sp-stats > *,
.el-tourn-list > *,
.el-news-grid > *,
.el-ev-list > *,
.el-weather-bands > *,
.el-about-stats > *,
.el-footer-grid > *,
.el-hero-ctas > * {
    opacity: 0;
    transform: translateY(38px);
    transition: opacity 0.45s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
    /* "Piano-key" stagger — 55ms between children for a snappy
       percussive cascade rather than a leisurely wave. */
    transition-delay: calc(var(--card-idx, 0) * 55ms);
}
.el-cascade-in > * {
    opacity: 1;
    transform: translateY(0);
}
.el-cascade-out-top > * {
    opacity: 0;
    transform: translateY(-38px);
}

/* ── Timeline + calendar populate stagger ────────────────────────
   When the dot timeline (.el-preview-timeline) or month calendar
   grid (.el-ev-cal-grid) renders, JS stamps each child with a
   --dot-idx / --cell-idx ordinal then adds .is-populated on the
   next frame. The CSS staggers an opacity (+ tiny scale) entrance
   so the data "lights up" left-to-right rather than appearing as
   a wall. */

/* Timeline dots — fade in via opacity + short drop. Transition list
   keeps hover transform + box-shadow animations alive (the bare
   .el-preview-timeline-dot rule below would otherwise overwrite the
   transition shorthand → scale on hover would snap).
   2026-07-30: cascade is now driven by a per-dot IntersectionObserver
   (see attachDotWaterfallObserver in events.js). Each dot animates in
   the moment it enters the scroll container's visible strip — so
   FUTURE-side dots that live off-screen at initial render also
   waterfall in as the operator scrolls right. Transition-delay
   removed here; the JS staggers via setTimeout. */
.el-preview-timeline .el-preview-timeline-dot {
    opacity: 0;
    /* Pre-populate state: dot drops from ~10px above its final
       position so the entrance reads as a lively land, not a
       flat fade. Final transform preserves the --lane vertical
       offset the base rule sets. */
    transform: translate(-50%, calc(-50% - (var(--lane, 0) * 22px) - 10px));
    transition:
        opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1),
        transform 0.55s cubic-bezier(0.22, 1, 0.36, 1),
        box-shadow 0.18s,
        filter 0.25s;
    will-change: opacity, transform;
}
/* Container reveal — SCOPED to timelines WITHOUT the --per-dot
   modifier. Used by home-previews.js on the club-site home page,
   where the timeline strip doesn't scroll horizontally — all dots
   fit in view + cascade as one wave when the strip enters the
   browser viewport. The `:not(.el-preview-timeline--per-dot)` guard
   makes this rule INERT on the events.js timeline (which sets
   --per-dot). That avoids a specificity war with the per-dot rules
   below — the browser skips this rule entirely when --per-dot is
   present. Previous attempt used higher-specificity :not() rules
   to override this, but browsers were still applying it in edge
   cases; scoping the source rule is bulletproof. */
.el-preview-timeline:not(.el-preview-timeline--per-dot).is-populated .el-preview-timeline-dot {
    opacity: 1;
    transform: translate(-50%, calc(-50% - (var(--lane, 0) * 22px)));
    transition-delay:
        calc(var(--dot-idx, 0) * 60ms),
        calc(var(--dot-idx, 0) * 60ms),
        0s, 0s;
}

/* Per-dot mode (events.js only) — dots stay hidden until per-dot
   `.is-in-view` is set by attachDotWaterfallObserver. Base rule
   above already handles opacity:0; this only sets the visible state
   + zeroes transition-delay so the JS-side setTimeout stagger
   drives the cascade solo (no double-staggering with CSS delay).
   Older browsers without IntersectionObserver hit the JS fallback
   which adds `.is-in-view` immediately — no cascade but everything
   renders. */
.el-preview-timeline--per-dot .el-preview-timeline-dot {
    transition-delay: 0s;
}
.el-preview-timeline--per-dot .el-preview-timeline-dot.is-in-view {
    opacity: 1;
    transform: translate(-50%, calc(-50% - (var(--lane, 0) * 22px)));
}
/* Today line + window pill + axis labels — fade in last */
.el-preview-timeline .el-preview-timeline-today,
.el-preview-timeline .el-preview-timeline-today-line,
.el-preview-timeline .el-ev-day-tl-window,
.el-preview-timeline .el-preview-timeline-line,
.el-preview-timeline .el-preview-timeline-label {
    opacity: 0;
    transition: opacity 0.45s ease 0.05s;
}
.el-preview-timeline.is-populated .el-preview-timeline-today,
.el-preview-timeline.is-populated .el-preview-timeline-today-line,
.el-preview-timeline.is-populated .el-ev-day-tl-window,
.el-preview-timeline.is-populated .el-preview-timeline-line,
.el-preview-timeline.is-populated .el-preview-timeline-label {
    opacity: 1;
}

/* Calendar cells — wave fade in by row-major index. Keeps the
   background/border-color hover transition alive alongside the
   populate fade so cell hover-states still animate after the
   wave finishes. */
.el-ev-cal-grid > * {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
    transition:
        opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1),
        transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
        background 0.15s,
        border-color 0.15s,
        filter 0.25s;
    transition-delay: calc(var(--cell-idx, 0) * 18ms), calc(var(--cell-idx, 0) * 18ms), 0s, 0s, 0s;
}
.el-ev-cal-grid.is-populated > * {
    opacity: 1;
    transform: translateY(0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
    .el-preview-timeline .el-preview-timeline-dot {
        opacity: 1;
        /* Dots are absolutely positioned + lane-offset; keep that transform,
           just skip the extra 10px drop animation. Same 22px spread as the
           base rule so lanes stay separated. */
        transform: translate(-50%, calc(-50% - (var(--lane, 0) * 22px)));
    }
    .el-preview-timeline .el-preview-timeline-today,
    .el-preview-timeline .el-preview-timeline-today-line,
    .el-preview-timeline .el-ev-day-tl-window,
    .el-preview-timeline .el-preview-timeline-line,
    .el-preview-timeline .el-preview-timeline-label,
    .el-ev-cal-grid > * {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ── Card-content micro-animations ───────────────────────────────
   Layered ON TOP of the card cascade above. Each card frame slides
   up first; THEN its image fades in with a soft blur-clear + slight
   zoom, and the body text rises a few pixels. Delays use the same
   --card-idx so card 1's content lands before card 2's. The whole
   grid being .el-cascade-in is the gate — when the parent grid
   isn't in view, all of this stays hidden. */
.el-preview-cards img,
.el-court-cards img,
.el-weekly-grid img,
.el-tourn-list img,
.el-news-grid img,
.el-coach-grid img,
.el-coach-progs img,
.el-sp-grid img,
.el-testimonial-grid img {
    opacity: 0;
    filter: blur(10px);
    transform: scale(1.04);
    transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
                filter 0.7s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: calc(var(--card-idx, 0) * 55ms + 0.15s);
}
.el-cascade-in.el-preview-cards img,
.el-cascade-in.el-court-cards img,
.el-cascade-in.el-weekly-grid img,
.el-cascade-in.el-tourn-list img,
.el-cascade-in.el-news-grid img,
.el-cascade-in.el-coach-grid img,
.el-cascade-in.el-coach-progs img,
.el-cascade-in.el-sp-grid img,
.el-cascade-in.el-testimonial-grid img {
    opacity: 1;
    filter: blur(0);
    transform: scale(1);
}

/* Body / text containers inside each card — secondary fade up with
   a slightly longer delay so the card frame + image arrive first. */
.el-preview-card-body,
.el-news-card-body,
.el-tourn-body,
.el-court-card-body,
.el-weekly-card-body,
.el-coach-card > *,
.el-coach-prog-body,
.el-sp-card > *:not(.el-sp-card-media),
.el-testimonial > *,
.el-mship-card > *,
.el-mship-bullets > * {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: calc(var(--card-idx, 0) * 55ms + 0.25s);
}
.el-cascade-in .el-preview-card-body,
.el-cascade-in .el-news-card-body,
.el-cascade-in .el-tourn-body,
.el-cascade-in .el-court-card-body,
.el-cascade-in .el-weekly-card-body,
.el-cascade-in .el-coach-card > *,
.el-cascade-in .el-coach-prog-body,
.el-cascade-in .el-sp-card > *:not(.el-sp-card-media),
.el-cascade-in .el-testimonial > *,
.el-cascade-in .el-mship-card > *,
.el-cascade-in .el-mship-bullets > * {
    opacity: 1;
    transform: translateY(0);
}

/* Reverse on exit — same elements fade up + away when the grid
   leaves through the top of the viewport. */
.el-cascade-out-top .el-preview-card-body,
.el-cascade-out-top .el-news-card-body,
.el-cascade-out-top .el-tourn-body,
.el-cascade-out-top .el-court-card-body,
.el-cascade-out-top .el-weekly-card-body,
.el-cascade-out-top .el-coach-card > *,
.el-cascade-out-top .el-coach-prog-body,
.el-cascade-out-top .el-sp-card > *:not(.el-sp-card-media),
.el-cascade-out-top .el-testimonial > *,
.el-cascade-out-top .el-mship-card > *,
.el-cascade-out-top .el-mship-bullets > * {
    opacity: 0;
    transform: translateY(-10px);
}

@media (prefers-reduced-motion: reduce) {
    .el-preview-cards img, .el-court-cards img, .el-weekly-grid img,
    .el-tourn-list img,    .el-news-grid img,    .el-coach-grid img,
    .el-coach-progs img,   .el-sp-grid img,      .el-testimonial-grid img,
    .el-preview-card-body, .el-news-card-body,   .el-tourn-body,
    .el-court-card-body,   .el-weekly-card-body, .el-coach-card > *,
    .el-coach-prog-body,   .el-sp-card > *,
    .el-testimonial > *,   .el-mship-card > *,   .el-mship-bullets > * {
        opacity: 1;
        filter: none;
        transform: none;
        transition: none;
    }
}

/* ── Split-column 2-col sections (every pass) ──────────────────── */
/* First child (text / copy column) slides in from the LEFT; second
   child (image / glyph column) slides in from the RIGHT. On exit
   via the top of the viewport each column slides back out its
   respective side. */
.el-about-grid > *:first-child,
.el-coach-academy > *:first-child,
.el-coach-cta-grid > *:first-child,
.el-contact-combo > *:first-child,
.el-sp-form-grid > *:first-child,
.el-ms-faq-grid > *:first-child {
    opacity: 0;
    transform: translateX(-80px);
    transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
.el-about-grid > *:nth-child(n+2),
.el-coach-academy > *:nth-child(n+2),
.el-coach-cta-grid > *:nth-child(n+2),
.el-contact-combo > *:nth-child(n+2),
.el-sp-form-grid > *:nth-child(n+2),
.el-ms-faq-grid > *:nth-child(n+2) {
    opacity: 0;
    transform: translateX(80px);
    transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
/* IN-VIEW — both columns slide to resting position */
.el-split-in > *:first-child,
.el-split-in > *:nth-child(n+2) {
    opacity: 1;
    transform: translateX(0);
}
/* OUT-TOP — reverse: first child back to left, others back to right */
.el-split-out-top > *:first-child {
    opacity: 0;
    transform: translateX(-80px);
}
.el-split-out-top > *:nth-child(n+2) {
    opacity: 0;
    transform: translateX(80px);
}

/* Reduced-motion — skip card cascade + split animations */
@media (prefers-reduced-motion: reduce) {
    .el-preview-cards > *,
    .el-court-cards > *,
    .el-ms-grid > *,
    .el-testimonial-grid > *,
    .el-sp-grid > *,
    .el-coach-grid > *,
    .el-coach-progs > *,
    .el-ms-benefits-grid > *,
    .el-visit-grid > *,
    .el-weekly-grid > *,
    .el-sp-stats > *,
    .el-tourn-list > *,
    .el-news-grid > *,
    .el-ev-list > *,
    .el-about-grid > *,
    .el-coach-academy > *,
    .el-coach-cta-grid > *,
    .el-contact-combo > *,
    .el-sp-form-grid > *,
    .el-ms-faq-grid > * {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* Directional variants — slide IN from the side rather than the
   default 24px upward nudge.
   ───────────────────────────────────────────────────────────────
   IMPORTANT: the offset MUST be small (a few dozen px, not viewport
   widths). IntersectionObserver observes the element's post-
   transform bounding box; if we translate the element 100vw off-
   screen at init, its bbox sits 100vw away from the viewport and
   the observer may never fire — leaving the whole block
   permanently invisible (classic on grid-based layouts like the
   memberships FAQ + sticky aside + the sponsors enquiry form).
   48px of slide still reads as a clear side-in without breaking
   the scroll-triggered reveal. */
.el-reveal--from-left  { transform: translateX(-48px); }
.el-reveal--from-right { transform: translateX( 48px); }
.el-reveal[data-delay="1"] { transition-delay: 0.08s; }
.el-reveal[data-delay="2"] { transition-delay: 0.18s; }
.el-reveal[data-delay="3"] { transition-delay: 0.28s; }
.el-reveal[data-delay="4"] { transition-delay: 0.40s; }
.el-reveal[data-delay="5"] { transition-delay: 0.52s; }
.el-reveal[data-delay="6"] { transition-delay: 0.62s; }
@media (prefers-reduced-motion: reduce) {
    .el-reveal { opacity: 1; transform: none; transition: none; }
}

/* ── Hero Ken Burns background image ────────────────────────────────── */
/* Both day + night images mount at page-load and share the SAME animation
   (name, duration, easing, iteration). Because they started at the same
   tick, they're always at the same zoom/translate phase — toggling night
   mode just crossfades opacity, so there's zero desync.

   Photo is the dominant layer (high opacity, no blend mode) — the navy
   brand tint comes from the .el-hero::after vignette below, sized to
   keep the copy area readable without drowning the image. */
.el-hero-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    z-index: 0;
    animation: el-ken-burns 22s var(--el-ease-soft) infinite alternate;
    pointer-events: none;
    transition: opacity 0.5s ease;
}
.el-hero-bg--day   { opacity: 1; }
.el-hero-bg--night { opacity: 0; }
html.night-mode .el-hero-bg--day   { opacity: 0; }
html.night-mode .el-hero-bg--night { opacity: 1; }

@keyframes el-ken-burns {
    from { transform: scale(1) translateY(0); }
    to   { transform: scale(1.08) translateY(-1%); }
}
.el-hero .el-container { position: relative; z-index: 1; }

/* ── Home-specific preview strips (Courts / Events / Memberships) ──── */
.el-preview-strip {
    padding: clamp(48px, 7vw, 96px) 0;
}
.el-preview-strip--dark {
    background: var(--el-hero);  /* navy — matches nav + footer */
    color: var(--el-text-inv);
}
/* Sky variant — soft light-blue gradient used by the Latest Stories
   strip and the Weather strip so they feel editorial / airy against
   the surrounding white/cream sections. */
.el-preview-strip--sky {
    background: linear-gradient(180deg, #e7eefa 0%, #dce6f5 100%);
}
html.night-mode .el-preview-strip--sky {
    background: linear-gradient(180deg, #12141b 0%, #0d0f14 100%);
}
.el-preview-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 20px;
    margin-bottom: 32px;
}
.el-preview-eyebrow {
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    opacity: 0.85;
    margin-bottom: 8px;
}
.el-preview-title {
    font-size: clamp(1.6rem, 3.2vw, 2.3rem);
    font-weight: 800;
    margin: 0;
    line-height: 1.15;
    letter-spacing: -0.02em;
}
.el-preview-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 12px 22px;
    border-radius: 999px;
    border: 1.5px solid;
    font-weight: 700;
    font-size: 0.82rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    transition: transform 0.2s, background 0.2s, color 0.2s;
}
.el-preview-link .mdi { font-size: 1rem; }
.el-preview-strip--dark .el-preview-link { border-color: rgba(255,255,255,0.5); color: #fff; }
.el-preview-strip--dark .el-preview-link:hover { background: #fff; color: var(--el-hero); border-color: #fff; transform: translateX(4px); }
.el-preview-strip--light .el-preview-link { border-color: var(--el-border); color: var(--el-text); }
.el-preview-strip--light .el-preview-link:hover { background: var(--el-hero); color: #fff; border-color: var(--el-hero); transform: translateX(4px); }

/* Supporting copy beneath the preview strip heading */
.el-preview-sub {
    margin: 12px auto 0;
    font-size: 0.98rem;
    line-height: 1.55;
    color: var(--el-text-muted);
    max-width: 620px;
}
.el-preview-strip--dark .el-preview-sub {
    color: var(--el-text-inv-muted);
}

/* ── Preview card grid (3 cards) ────────────────────────────────────
   Used by the three home-page preview strips (Events / Memberships
   / Coaching). Single grid definition — per-strip modifier classes
   tweak the card media aspect + palette. */
.el-preview-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 24px;
    margin-top: 8px;
}
@media (min-width: 1000px) {
    .el-preview-cards { grid-template-columns: repeat(3, 1fr); }
}

.el-preview-loading,
.el-preview-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 32px 20px;
    color: var(--el-text-muted);
    font-size: 0.92rem;
}
.el-preview-loading i,
.el-preview-empty i {
    font-size: 1.3rem;
    margin-right: 6px;
    vertical-align: -3px;
}
.el-preview-loading i { animation: elPreviewSpin 1s linear infinite; }
@keyframes elPreviewSpin { to { transform: rotate(360deg); } }
.el-preview-strip--dark .el-preview-loading,
.el-preview-strip--dark .el-preview-empty {
    color: var(--el-text-inv-muted);
}

/* Preview card — shared sky-blue glow via --el-glow-idle / --el-glow-hover.
   One source of truth so every card on the landing reads as one
   visual language (see :root + html.night-mode for the var defs). */
.el-preview-card {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    border: none; /* box-shadow handles the edge so we don't get a double-line */
    box-shadow: var(--el-glow-idle);
    transition:
        box-shadow 0.35s var(--el-ease-soft),
        transform 0.35s var(--el-ease-soft);
}
.el-preview-card:hover {
    transform: translateY(-5px);
    box-shadow: var(--el-glow-hover);
}
.el-preview-strip--dark .el-preview-card {
    background: rgba(255, 255, 255, 0.04);
    color: var(--el-text-inv);
}
.el-preview-strip--dark .el-preview-card:hover {
    background: rgba(255, 255, 255, 0.06);
}
html.night-mode .el-preview-card {
    background: #12141b;
}

.el-preview-card-link {
    display: flex;
    flex-direction: column;
    height: 100%;
    text-decoration: none;
    color: inherit;
}

/* Photo / icon hero for each card */
.el-preview-card-media {
    aspect-ratio: 16 / 10;
    background: var(--el-surface-alt);
    overflow: hidden;
    position: relative;
}
.el-preview-card-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s var(--el-ease-soft);
}
.el-preview-card:hover .el-preview-card-media img { transform: scale(1.05); }
.el-preview-card-media-fallback {
    width: 100%; height: 100%;
    display: grid;
    place-items: center;
    color: rgba(2, 12, 146, 0.25);
    font-size: 3.2rem;
    background: linear-gradient(135deg, #e0e7f5, #f2f5fa);
}
html.night-mode .el-preview-card-media-fallback {
    color: rgba(255, 255, 255, 0.2);
    background: linear-gradient(135deg, #1a1d24, #12141b);
}
.el-preview-strip--dark .el-preview-card-media-fallback {
    background: linear-gradient(135deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
    color: rgba(255, 255, 255, 0.35);
}

/* Membership-tier variant — solid colour block with an icon, no photo */
.el-preview-card-media--tier {
    --tier-hue: var(--club-accent);
    background: linear-gradient(135deg, color-mix(in srgb, var(--tier-hue) 85%, #fff 0%), color-mix(in srgb, var(--tier-hue) 100%, #000 18%));
    display: grid;
    place-items: center;
    color: #ffffff;
    aspect-ratio: 16 / 10;
}
.el-preview-card-media--tier i { font-size: 3.4rem; opacity: 0.9; }

/* Coach portrait variant — square photo */
.el-preview-card-media--portrait {
    aspect-ratio: 4 / 3;
}

/* Card body */
.el-preview-card-body {
    padding: 20px 22px 22px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex-grow: 1;
}
.el-preview-strip--dark .el-preview-card-body { color: var(--el-text-inv); }
.el-preview-card-title {
    font-size: 1.18rem;
    font-weight: 800;
    color: var(--el-text);
    margin: 0;
    line-height: 1.22;
    letter-spacing: -0.01em;
}
.el-preview-strip--dark .el-preview-card-title { color: var(--el-text-inv); }
.el-preview-card-sub {
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--el-text-muted);
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.el-preview-strip--dark .el-preview-card-sub { color: var(--el-text-inv-muted); }

/* Top-row pill + type dot (used on event cards) */
.el-preview-card-tagline {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.el-preview-pill {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    background: #e33e41;
    color: #ffffff;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.el-preview-pill--social      { background: #e33e41; }
.el-preview-pill--competition { background: #c0392b; }
.el-preview-pill--junior      { background: #f0a30a; color: #1a1a1a; }
.el-preview-pill--coaching    { background: #3b82f6; }
.el-preview-pill--community   { background: #16a34a; }
.el-preview-pill--maintenance { background: #64748b; }
.el-preview-pill--sponsor     { background: #9333ea; }
.el-preview-pill--news        { background: var(--club-accent); }
.el-preview-pill--other       { background: var(--club-accent); }
.el-preview-pill--tier {
    background: var(--club-accent);
    color: #ffffff;
}
html.night-mode .el-preview-pill--tier {
    background: var(--el-green);
    color: var(--el-green-text);
}

.el-preview-type {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    color: var(--el-text-muted);
}
.el-preview-strip--dark .el-preview-type { color: var(--el-text-inv-muted); }
.el-preview-type-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--club-accent);
}
.el-preview-type-dot--social      { background: #16a34a; }
.el-preview-type-dot--junior      { background: #f59e0b; }
.el-preview-type-dot--competition { background: #dc2626; }
.el-preview-type-dot--coaching    { background: #3b82f6; }
.el-preview-type-dot--community   { background: #10b981; }
.el-preview-type-dot--maintenance { background: #64748b; }
.el-preview-type-dot--sponsor     { background: #a855f7; }
.el-preview-type-dot--news        { background: var(--club-accent); }

/* Meta row (clock, map pin, etc.) */
.el-preview-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    font-size: 0.82rem;
    color: var(--el-text-muted);
    margin-top: auto;
    padding-top: 4px;
}
.el-preview-card-meta > span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.el-preview-card-meta i {
    color: var(--club-accent);
    font-size: 0.98rem;
}
.el-preview-strip--dark .el-preview-card-meta { color: var(--el-text-inv-muted); }
.el-preview-strip--dark .el-preview-card-meta i { color: var(--el-green); }
html.night-mode .el-preview-card-meta i { color: var(--el-accent); }

/* Coach specialty chips */
.el-preview-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}
.el-preview-chip {
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(188, 255, 0, 0.16);
    color: var(--el-cta);
    font-size: 0.72rem;
    font-weight: 700;
}
.el-preview-strip--dark .el-preview-chip {
    background: rgba(188, 255, 0, 0.22);
    color: var(--el-green);
}
html.night-mode .el-preview-chip {
    background: rgba(188, 255, 0, 0.18);
    color: var(--el-green);
}

/* Past-event variant — desaturate the photo + show a "Past" ribbon
   in the top-right corner so it's immediately obvious. */
.el-preview-card--past .el-preview-card-media img {
    filter: grayscale(0.55) brightness(0.92);
}
.el-preview-past-ribbon {
    position: absolute;
    top: 12px; right: 12px;
    background: rgba(15, 23, 42, 0.82);
    color: #ffffff;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    padding: 4px 10px;
    border-radius: 999px;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

/* ── Homepage memberships preview cards ────────────────────────────
   Clean white card, category icon top-right, big price anchor,
   checkmark bullet list of key limits/benefits. The most-popular
   tier gets a "Best Value" ribbon + accent-filled Sign Up button;
   the others use a ghost "Learn More" link. Rendered into
   #el-preview-memberships by home-previews.js. */
.el-mship-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border: none; /* box-shadow handles the edge — avoids a double-line with the glow ring */
    border-radius: var(--el-radius-lg);
    padding: 28px 26px 26px;
    box-shadow: var(--el-glow-idle);
    cursor: pointer;
    transition:
        box-shadow 0.35s var(--el-ease-soft),
        transform 0.35s var(--el-ease-soft);
    overflow: hidden;
}
.el-mship-card:hover {
    transform: translateY(-5px);
    box-shadow: var(--el-glow-hover);
}
html.night-mode .el-mship-card {
    background: #12141b;
    color: var(--el-text);
}

/* Home-preview only: collapse 'extra' tiers behind an Expand button so
   the home page shows just the 3 anchor tiers (Basic / Best Value / Top).
   The dedicated /memberships page never collapses anything. */
.el-mship-card--collapsed { display: none; }
.el-preview-cards.is-expanded .el-mship-card--collapsed { display: flex; }
/* Mobile (≤ 760px): the carousel scrolls horizontally so showing all
   tiers is fine — they're swipeable. Reveal collapsed cards by default
   on narrow screens regardless of the expand toggle. */
@media (max-width: 760px) {
    .el-mship-card--collapsed { display: flex; }
}

/* Hover affordance — blur the card content + show a SELECT/DESELECT
   overlay. The CTA button stays sharp on top of the blur (z-index 3)
   so 'More Details' / 'Sign Up' is always reachable.
   - .el-mship-content holds head/price/bullets and gets blurred
   - .el-mship-hover-overlay carries the floating label
   - .el-mship-cta sits above both at z-index 3
   - .el-mship-ribbon also stays sharp at z-index 3 */
.el-mship-content {
    position: relative;
    z-index: 1;
    transition: filter 0.25s var(--el-ease-soft), opacity 0.25s var(--el-ease-soft);
}
.el-mship-card:hover .el-mship-content {
    filter: blur(4px);
    opacity: 0.55;
}
.el-mship-hover-overlay {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    /* visibility: hidden + opacity: 0 belt-and-braces — opacity-only
       gating sometimes leaves intermediate transition frames visible
       when the cursor moves quickly between cards, making it look like
       multiple cards have the label at once. visibility:hidden cuts it
       hard until hover lands. */
    visibility: hidden;
    opacity: 0;
    transition: opacity 0.2s var(--el-ease-soft), visibility 0s linear 0.2s;
}
.el-mship-card:hover .el-mship-hover-overlay {
    visibility: visible;
    opacity: 1;
    transition: opacity 0.2s var(--el-ease-soft), visibility 0s linear 0s;
}
/* Plain bold label — no pill background/border. The blurred content
   behind it provides enough contrast on its own. */
.el-mship-hover-label {
    display: none;
    font-size: clamp(1.6rem, 3.5vw, 2.4rem);
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--el-text);
    text-shadow:
        0 0 22px rgba(125, 211, 252, 0.55),
        0 4px 14px rgba(0, 0, 0, 0.20);
}
html.night-mode .el-mship-hover-label {
    color: var(--el-text-inv);
    text-shadow:
        0 0 22px rgba(125, 211, 252, 0.70),
        0 4px 14px rgba(0, 0, 0, 0.55);
}
/* Show the right label depending on selected state. */
.el-mship-card:not(.is-selected) .el-mship-hover-label--select   { display: inline-block; }
.el-mship-card.is-selected           .el-mship-hover-label--deselect { display: inline-block; }
/* CTA + ribbon must stay sharp + clickable above the blur layer. */
.el-mship-cta,
.el-mship-ribbon {
    position: relative;
    z-index: 3;
}

/* Popular variant — tighter solid sky-blue ring so the "Best Value"
   card still reads as the anchor; hover upgrade fires the full bloom. */
.el-mship-card--popular {
    box-shadow:
        0 0 0 2px var(--el-accent),
        0 0 14px rgba(125, 211, 252, 0.55),
        0 0 32px rgba(125, 211, 252, 0.3),
        0 0 60px rgba(125, 211, 252, 0.16);
}
html.night-mode .el-mship-card--popular {
    box-shadow:
        0 0 0 2px var(--el-accent),
        0 0 14px rgba(125, 211, 252, 0.4),
        0 0 32px rgba(125, 211, 252, 0.22),
        0 0 60px rgba(125, 211, 252, 0.1);
}

/* Top ribbon — sky-blue brand accent in both modes (was lime green
   in night mode which competed with the green selected-card CTA). */
.el-mship-ribbon {
    position: absolute;
    top: 0; left: 0; right: 0;
    background: var(--el-accent);
    color: var(--el-hero);
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-align: center;
    padding: 8px 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}
.el-mship-ribbon .mdi { font-size: 0.9rem; }
html.night-mode .el-mship-ribbon {
    background: var(--el-accent);
    color: var(--el-hero);
}
.el-mship-card--popular { padding-top: 54px; }

/* Header: name left, icon top-right */
.el-mship-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 18px;
}
.el-mship-name {
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--el-text);
    margin: 0;
    letter-spacing: -0.01em;
    line-height: 1.25;
}
html.night-mode .el-mship-name { color: var(--el-text); }
/* Icon tile — background + icon colour driven by the inline
   `--icon-color` CSS var set from `membership_types.color`. Falls
   back to the accent navy when the tier has no colour configured. */
.el-mship-icon {
    --icon-color: var(--club-accent);
    flex-shrink: 0;
    width: 44px; height: 44px;
    display: grid;
    place-items: center;
    border-radius: 12px;
    background: color-mix(in srgb, var(--icon-color) 14%, transparent);
    color: var(--icon-color);
    font-size: 1.4rem;
}
html.night-mode .el-mship-icon {
    background: color-mix(in srgb, var(--icon-color) 22%, transparent);
}

/* Big price anchor */
.el-mship-price {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
}
.el-mship-price-from {
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}
.el-mship-price-big {
    font-size: 2.6rem;
    font-weight: 900;
    color: var(--club-accent);
    letter-spacing: -0.03em;
    line-height: 1;
}
html.night-mode .el-mship-price-big { color: var(--el-accent); }
/* Junior tier — price in tennis-ball green. Darker shade on white for
   legibility; switches to sky-blue accent in night mode (was bright
   green which dominated the panel). */
.el-mship-card--junior .el-mship-price-big { color: #7bb60f; }
html.night-mode .el-mship-card--junior .el-mship-price-big { color: var(--el-accent); }

/* ── Coaching Programs placeholder card (Tier 3 · 3.4, 2026-07-17) ──
   Sits at the end of the tier grid as a signpost to /programs.
   Deliberately styled a touch differently from real tier cards so it
   reads as a category signpost, not a competing purchase decision.
   - Accent-tinted dashed border
   - No price bubble; a compact "PROGRAM" chip instead
   - Simple green "View Programs →" pill CTA */
.el-mship-card--programs {
    border: 2px dashed rgba(200, 230, 58, 0.4);
    background: linear-gradient(180deg, rgba(200, 230, 58, 0.02), rgba(200, 230, 58, 0.06));
    /* No hover-blur overlay used on real tier cards — this one is a
       one-tap signpost, not a selection surface. */
}
html.night-mode .el-mship-card--programs {
    background: linear-gradient(180deg, rgba(200, 230, 58, 0.04), rgba(200, 230, 58, 0.10));
    border-color: rgba(200, 230, 58, 0.5);
}
.el-mship-card--programs .el-mship-hover-overlay { display: none; }
.el-mship-programs-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    background: rgba(200, 230, 58, 0.15);
    border: 1px solid rgba(200, 230, 58, 0.4);
    color: #7bb60f;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin: 8px 0 12px;
}
html.night-mode .el-mship-programs-chip { color: var(--el-accent); }
.el-mship-programs-chip i { font-size: 0.9rem; }
.el-mship-programs-body {
    color: var(--el-text-muted);
    font-size: 0.95rem;
    line-height: 1.55;
    margin: 0 0 14px;
}
.el-mship-programs-count {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    background: rgba(0, 0, 0, 0.03);
    border-radius: 8px;
    color: var(--el-text);
    font-size: 0.82rem;
    font-weight: 600;
    margin-bottom: 14px;
}
html.night-mode .el-mship-programs-count {
    background: rgba(255, 255, 255, 0.05);
    color: var(--el-text);
}
.el-mship-programs-count i { color: var(--club-accent, #C8E63A); font-size: 1rem; }

/* CTA on the Programs card — plain green pill, no CSS label-swap
   cycle (real tier cards cycle More Details / Select / Sign Up on
   hover; this one is a direct link). */
.el-mship-cta-btn--programs {
    background: linear-gradient(180deg, #7bb60f, #5a8b0b);
    color: #ffffff;
    text-decoration: none;
    justify-content: center;
    padding: 12px 20px;
    border-radius: 999px;
    font-weight: 700;
    letter-spacing: 0.02em;
    transition: filter 0.15s ease, transform 0.15s ease;
}
.el-mship-cta-btn--programs:hover {
    filter: brightness(1.08);
    transform: translateY(-1px);
}
.el-mship-cta-btn--programs span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* Enquire card modifier — internal (committee-assigned) tiers.
   Same layout as Programs card, but a warm gold accent so operators +
   visitors read it as "by invitation" rather than a self-serve
   coaching program. Applied to `.el-mship-card--programs.el-mship-
   card--enquire` so it OVERRIDES the green Programs palette. */
.el-mship-card--enquire {
    border: 2px dashed rgba(212, 175, 55, 0.42);
    background: linear-gradient(180deg, rgba(212, 175, 55, 0.03), rgba(212, 175, 55, 0.07));
}
html.night-mode .el-mship-card--enquire {
    background: linear-gradient(180deg, rgba(212, 175, 55, 0.05), rgba(212, 175, 55, 0.11));
    border-color: rgba(212, 175, 55, 0.55);
}
.el-mship-card--enquire .el-mship-icon i { color: #b98f1a; }
html.night-mode .el-mship-card--enquire .el-mship-icon i { color: #e6c15a; }
.el-mship-programs-chip--enquire {
    background: rgba(212, 175, 55, 0.15);
    border-color: rgba(212, 175, 55, 0.42);
    color: #8a6812;
}
html.night-mode .el-mship-programs-chip--enquire { color: #e6c15a; }
.el-mship-card--enquire .el-mship-programs-count i { color: #b98f1a; }
html.night-mode .el-mship-card--enquire .el-mship-programs-count i { color: #e6c15a; }
.el-mship-cta-btn--enquire {
    background: linear-gradient(180deg, #b98f1a, #8a6812);
}
.el-mship-cta-btn--enquire:hover { filter: brightness(1.08); }
.el-mship-price-suffix {
    font-size: 1rem;
    font-weight: 700;
    color: var(--el-text-muted);
}
.el-mship-price-sub {
    font-size: 0.85rem;
    color: var(--el-text-muted);
    margin-top: 4px;
    margin-bottom: 18px;
}
.el-mship-price:not(:has(+ .el-mship-price-sub)) { margin-bottom: 18px; }

/* Family-free dependency chip — sits between the price and the bullets
   on tiers where a qualifying parent membership grants a free child slot
   (e.g. Junior comes in free when the parent holds Social Adult / Full
   Adult). Reads as a soft callout — accent tint background, accent icon,
   short one-liner. Keeps the visitor from misreading "R70/month" as
   "free for every junior". */
.el-mship-dep-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    margin: -6px 0 16px;
    background: rgba(200, 230, 58, 0.16);
    border-left: 3px solid var(--el-accent-green, #C8E63A);
    border-radius: 6px;
    font-size: 0.82rem;
    color: var(--el-text);
    line-height: 1.35;
}
.el-mship-dep-chip i {
    color: var(--el-hero, #020c92);
    font-size: 1.05rem;
    flex-shrink: 0;
}
.el-mship-dep-chip strong { color: var(--el-hero, #020c92); }
html.night-mode .el-mship-dep-chip {
    background: rgba(200, 230, 58, 0.14);
    color: var(--el-text-inv, #ffffff);
}
html.night-mode .el-mship-dep-chip i,
html.night-mode .el-mship-dep-chip strong { color: var(--el-accent-green, #C8E63A); }

/* Bullet list */
.el-mship-bullets {
    list-style: none;
    padding: 0;
    margin: 0 0 22px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    border-top: 1px solid var(--el-border);
    padding-top: 18px;
}
.el-mship-bullets li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 0.9rem;
    line-height: 1.45;
    color: var(--el-text);
}
.el-mship-bullets .mdi {
    color: var(--club-accent);
    font-size: 1.1rem;
    flex-shrink: 0;
    margin-top: 1px;
}
html.night-mode .el-mship-bullets .mdi { color: var(--el-accent); }
html.night-mode .el-mship-bullets li { color: var(--el-text); }

/* CTA row — pushed to the bottom so rows line up across cards */
.el-mship-cta {
    margin-top: auto;
}
.el-mship-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 14px 18px;
    border-radius: 999px;
    font-weight: 800;
    font-size: 0.85rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    border: 2px solid transparent;
    cursor: pointer;
    transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.2s;
}
.el-mship-btn .mdi { font-size: 1rem; }
.el-mship-btn--primary {
    background: var(--club-accent);
    color: #ffffff;
    border-color: var(--club-accent);
}
.el-mship-btn--primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(2, 12, 146, 0.28);
}
html.night-mode .el-mship-btn--primary {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-green);
}
.el-mship-btn--ghost {
    background: transparent;
    color: var(--el-text);
    border-color: var(--el-border);
}
.el-mship-btn--ghost:hover {
    background: var(--club-accent);
    color: #ffffff;
    border-color: var(--club-accent);
    transform: translateY(-2px);
}
html.night-mode .el-mship-btn--ghost {
    color: var(--el-text);
    border-color: var(--el-border);
}
html.night-mode .el-mship-btn--ghost:hover {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-green);
}

/* ── Tier card three-state CTA ─────────────────────────────────────
   Single button on each card carries three label spans; CSS swaps
   which is visible based on the card's hover/selected state.
   Resting              → "More Details"     (default span)
   Card :hover          → "Select Membership" (hover span)
   Card .is-selected    → "Sign Up"          (selected span, green pill) */
.el-mship-cta-btn {
    background: transparent;
    color: var(--el-text);
    border-color: var(--el-border);
    transition:
        background 0.25s,
        color 0.25s,
        border-color 0.25s,
        transform 0.2s,
        box-shadow 0.25s;
}
.el-mship-cta-default,
.el-mship-cta-hover,
.el-mship-cta-selected {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.el-mship-cta-hover,
.el-mship-cta-selected { display: none; }

/* Hover swap intentionally REMOVED. The card-as-a-whole is a click
   target (selects the tier), and the CTA button stays a clear
   "More Details" affordance until the card is selected — keeping
   both interactions reachable without the user having to guess. The
   button keeps a subtle hover lift via .el-mship-cta-btn:hover below. */
.el-mship-cta-btn:hover {
    transform: translateY(-1px);
    border-color: rgba(125, 211, 252, 0.45);
}

/* Selected — green pill with navy outline + halo, mirroring
   .el-btn--green. Card itself gains a sky-blue ring so the chosen
   tier is obvious at a glance. */
.el-mship-card.is-selected .el-mship-cta-default { display: none; }
.el-mship-card.is-selected .el-mship-cta-selected { display: inline-flex; }
.el-mship-card.is-selected .el-mship-cta-btn {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-hero);
    box-shadow:
        0 0 28px rgba(2, 12, 146, 0.45),
        0 8px 24px rgba(188, 255, 0, 0.20);
}
.el-mship-card.is-selected .el-mship-cta-btn:hover {
    filter: brightness(1.08);
    transform: translateY(-2px);
    box-shadow:
        0 0 38px rgba(2, 12, 146, 0.60),
        0 12px 32px rgba(188, 255, 0, 0.30);
}
html.night-mode .el-mship-card.is-selected .el-mship-cta-btn {
    box-shadow:
        0 0 28px rgba(125, 211, 252, 0.45),
        0 8px 24px rgba(188, 255, 0, 0.22);
}
html.night-mode .el-mship-card.is-selected .el-mship-cta-btn:hover {
    box-shadow:
        0 0 40px rgba(125, 211, 252, 0.65),
        0 12px 32px rgba(188, 255, 0, 0.32);
}
.el-mship-card.is-selected {
    box-shadow:
        0 0 0 2px var(--el-accent),
        0 0 18px rgba(125, 211, 252, 0.55),
        0 0 36px rgba(125, 211, 252, 0.32);
}

/* The mship cards replace the default preview-card DOM, but they still
   live inside the same .el-preview-cards grid — no grid override
   needed. On very narrow screens (< 520px) the button label should
   shrink slightly so "Learn More →" fits without wrapping. */
@media (max-width: 520px) {
    .el-mship-card { padding: 24px 20px 20px; }
    .el-mship-card--popular { padding-top: 50px; }
    .el-mship-price-big { font-size: 2.2rem; }
}

/* ── Events timeline strip ─────────────────────────────────────────
   Horizontal axis from (today - 60 days) to (today + 60 days) with
   a dot per event. Dots can stack into vertical "lanes" when two
   events sit close together in time, so overlap doesn't hide one.
   A dashed TODAY line + label cuts the axis at the current moment. */
.el-preview-timeline-host {
    margin-top: 36px;
}
/* Timeline container — treated as a card so it sits alongside the
   news / event cards with the same interior bg + sky-blue glow. */
.el-preview-timeline {
    position: relative;
    /* Top padding trimmed from 18px → 4px because the inner
       scroll container now reserves 64px padding-top for tooltip
       clearance (see .el-preview-timeline-scroll). Together the
       stack still reads with a comfortable gap above the axis
       labels, and tooltips no longer clip. */
    padding: 4px 18px 14px;
    background: #ffffff;
    border: none;
    border-radius: var(--el-radius-lg);
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft);
}
.el-preview-timeline:hover {
    box-shadow: var(--el-glow-hover);
}
.el-preview-strip--dark .el-preview-timeline {
    background: rgba(255, 255, 255, 0.04);
}
html.night-mode .el-preview-timeline {
    background: #12141b;
}

.el-preview-timeline-axis {
    position: relative;
    display: flex;
    justify-content: space-between;
    font-size: 0.72rem;
    color: var(--el-text-muted);
    margin-bottom: 10px;
    letter-spacing: 0.02em;
}
.el-preview-strip--dark .el-preview-timeline-axis { color: var(--el-text-inv-muted); }
.el-preview-timeline-label--start { text-align: left; }
.el-preview-timeline-label--end { text-align: right; }
.el-preview-timeline-today {
    position: absolute;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: 0.68rem;
    color: var(--club-accent);
    white-space: nowrap;
}
.el-preview-strip--dark .el-preview-timeline-today { color: var(--el-green); }
html.night-mode .el-preview-timeline-today { color: var(--el-accent); }
.el-preview-timeline-today-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
}

/* Scroll container — inner track is wider (300%) than this so it
   overflows horizontally; user pans by click-and-drag or touch swipe.
   Native scrollbar hidden — the interaction is drag-based, not
   scrollbar-based; the operator wanted a tactile timeline. */
.el-preview-timeline-scroll {
    position: relative;
    overflow-x: auto;
    /* CSS rule: when overflow-x is not 'visible', overflow-y is coerced
       to 'auto' regardless of what we set — a container can't clip one
       axis and let the other overflow. Consequence: tooltips positioned
       above dots get clipped at the top of this container.
       Fix: reserve ~64px of padding-top INSIDE the clip bounds so
       tooltip (~60px tall) has room to float above the top-lane dots
       without hitting the ceiling. Bottom padding smaller — no tooltip
       below. */
    overflow-y: visible;
    padding-top: 64px;
    padding-bottom: 8px;
    scrollbar-width: none;
    -ms-overflow-style: none;
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
}
.el-preview-timeline-scroll::-webkit-scrollbar { display: none; }
.el-preview-timeline-scroll.is-panning { cursor: grabbing; }
.el-preview-timeline-inner {
    position: relative;
    /* Width set inline (DT_INNER_WIDTH_PCT %); positional children use
       % coords so widening the inner spreads dots along its length. */
}

.el-preview-timeline-track {
    position: relative;
    /* Grow track height to match the new 22px lane offset —
       leaves room for stacked-lane dots without them poking
       into the axis label row above. */
    height: calc(22px + (var(--lane-count, 1) * 24px));
    min-height: 48px;
}
.el-preview-timeline-line {
    position: absolute;
    top: 50%;
    left: 0; right: 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, rgba(2, 12, 146, 0.3), transparent);
    transform: translateY(-50%);
}
.el-preview-strip--dark .el-preview-timeline-line,
html.night-mode .el-preview-timeline-line {
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
}
.el-preview-timeline-today-line {
    position: absolute;
    top: 0; bottom: 0;
    width: 1.5px;
    background: repeating-linear-gradient(
        to bottom,
        var(--club-accent) 0,
        var(--club-accent) 4px,
        transparent 4px,
        transparent 8px
    );
    transform: translateX(-50%);
    opacity: 0.6;
    pointer-events: none;
}
.el-preview-strip--dark .el-preview-timeline-today-line,
html.night-mode .el-preview-timeline-today-line {
    background: repeating-linear-gradient(
        to bottom,
        var(--el-green) 0,
        var(--el-green) 4px,
        transparent 4px,
        transparent 8px
    );
}

/* Dots — positioned by left % + --lane index; use max(--lane) to
   nudge higher-lane dots upward so they don't overlap. */
.el-preview-timeline-dot {
    position: absolute;
    top: 50%;
    left: 0;
    /* Bumped 12 → 14 so the dot renders as a clear filled circle at
       every zoom level. The old 12px + 2px border + double box-shadow
       stack composited into a chunky/segmented look on some browsers,
       especially when multiple dots were stacked in adjacent lanes. */
    width: 14px; height: 14px;
    border-radius: 50%;
    /* Bumped 14 → 22 vertical spread so stacked-lane dots on the same
       date have real breathing room. Prevents the "cluster reads as
       one star-shape" artefact operator flagged. */
    transform: translate(-50%, calc(-50% - (var(--lane, 0) * 22px)));
    background: var(--club-accent);
    cursor: pointer;
    border: 2px solid #ffffff;
    /* Simpler shadow — drop the inset 1px ring that composited weirdly
       on small circles. Just a soft drop shadow for depth. */
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.20);
    transition: transform 0.18s var(--el-ease-soft), box-shadow 0.18s;
    text-decoration: none;
    z-index: 1;
}
.el-preview-strip--dark .el-preview-timeline-dot,
html.night-mode .el-preview-timeline-dot {
    border-color: rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 2px 6px rgba(0, 0, 0, 0.35);
}
.el-preview-timeline-dot:hover,
.el-preview-timeline-dot:focus-visible {
    transform: translate(-50%, calc(-50% - (var(--lane, 0) * 22px))) scale(1.35);
    box-shadow: 0 0 0 3px rgba(2, 12, 146, 0.2), 0 4px 12px rgba(0, 0, 0, 0.2);
    z-index: 3;
}
.el-preview-strip--dark .el-preview-timeline-dot:hover,
.el-preview-strip--dark .el-preview-timeline-dot:focus-visible {
    box-shadow: 0 0 0 3px rgba(188, 255, 0, 0.35), 0 4px 12px rgba(0, 0, 0, 0.4);
}
/* Past dots — dim via filter (NOT opacity) so the populate-stagger
   opacity transition can still drive 0 → 1 cleanly. Using opacity
   here clashed with .is-populated [opacity:1] at equal specificity
   and made the timeline look "half-rendered". */
.el-preview-timeline-dot.is-past { filter: saturate(0.55) brightness(0.85); }
.el-preview-timeline-dot.is-past:hover { filter: none; }

/* Category hues for dots — same palette as category pills */
.el-preview-timeline-dot--social      { background: #16a34a; }
.el-preview-timeline-dot--junior      { background: #f59e0b; }
.el-preview-timeline-dot--competition { background: #dc2626; }
.el-preview-timeline-dot--coaching    { background: #3b82f6; }
.el-preview-timeline-dot--community   { background: #10b981; }
.el-preview-timeline-dot--maintenance { background: #64748b; }
.el-preview-timeline-dot--sponsor     { background: #a855f7; }
.el-preview-timeline-dot--other       { background: var(--club-accent); }

/* Placeholder dots — recurring pattern projections, not real events.
   Slightly transparent + a dashed outer ring so they read as
   "provisional" while still keeping the category hue. A real event
   on the same day always suppresses the placeholder (see
   projectPlaceholders in events.js), so placeholders only appear on
   days that would otherwise be blank. */
/* FUTURE recurring-pattern placeholders — visually distinct from
   real events without looking broken. Operator complaint (2026-07-20):
   the old dashed-border on a 12px circle rendered as segmented
   arcs that read as a triangle/star from a distance. Fix: hollow
   ring instead — solid category-tinted stroke (same category hue),
   transparent fill, slightly smaller than a real dot. Reads as
   "projected, less definite" cleanly, no fake-triangle effect.
   Category hue on the border comes from the .el-preview-timeline-dot--<cat>
   rules further down setting background — we invert that here so the
   background acts as our border colour via currentColor + inset.
   Simplest: set background transparent + keep the 2px white border but
   add an inner ring in the category colour. */
.el-preview-timeline-dot.is-placeholder {
    /* Slightly smaller than a real event dot (14 → 12) so the eye
       reads it as "less definite" via subtle size difference rather
       than a distinct shape. */
    width: 12px; height: 12px;
    opacity: 0.85;
    /* Hollow ring: transparent fill + inset category-tint ring +
       soft drop shadow. Same shape as a real dot (circle), just
       ringed instead of filled — no dashed-border weirdness. */
    background: transparent;
    box-shadow:
        inset 0 0 0 3px currentColor,
        0 2px 6px rgba(0, 0, 0, 0.10);
    color: var(--club-accent);
}
/* Category-hue overrides for placeholder rings — mirror the real-
   event colour scale so category identity stays legible even when
   the fill is transparent. */
.el-preview-timeline-dot--social.is-placeholder      { color: #16a34a; }
.el-preview-timeline-dot--junior.is-placeholder      { color: #f59e0b; }
.el-preview-timeline-dot--competition.is-placeholder { color: #dc2626; }
.el-preview-timeline-dot--coaching.is-placeholder    { color: #3b82f6; }
.el-preview-timeline-dot--community.is-placeholder   { color: #10b981; }

.el-preview-timeline-dot.is-placeholder:hover {
    opacity: 1;
    /* On hover — fill the ring solid so it matches a real event's
       weight. Reinforces the "recurring pattern" semantics
       without needing dashed borders. */
    background: currentColor;
    box-shadow:
        0 0 0 3px rgba(2, 12, 146, 0.14),
        0 4px 12px rgba(0, 0, 0, 0.16);
}
.el-preview-timeline-tooltip-ph {
    display: inline-block;
    margin-top: 2px;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: rgba(255, 255, 255, 0.55);
    font-style: italic;
}
/* Legend chip for the placeholder swatch — mirrors the new
   hollow-ring style used by future placeholder dots so the
   legend explains what the operator sees. */
.el-preview-type-dot--placeholder {
    background: transparent;
    box-shadow: inset 0 0 0 3px var(--club-accent);
}
.el-preview-strip--dark .el-preview-type-dot--placeholder,
html.night-mode .el-preview-type-dot--placeholder {
    border-color: rgba(255, 255, 255, 0.55);
}
.el-preview-timeline-legend-item--ph { opacity: 0.75; }

/* Placeholder in the day-grid view — dashed border + subtle
   "recurring" badge inside the title. Same colour hue as the real
   event category so at-a-glance the pattern reads correctly. */
.el-ev-day-block--placeholder {
    opacity: 0.7;
    border: 1.5px dashed rgba(255, 255, 255, 0.6);
    box-shadow: none;
}
.el-ev-day-block--placeholder:hover { opacity: 1; }
.el-ev-day-block-ph {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 0.7rem;
    font-weight: 500;
    opacity: 0.85;
    margin-left: 6px;
    padding: 1px 5px;
    background: rgba(0, 0, 0, 0.18);
    border-radius: 4px;
    vertical-align: middle;
}
.el-ev-day-block-ph .mdi { font-size: 0.85rem; }

/* Placeholder in the day-popup (calendar cell click) — non-clickable
   with a hint chip. */
.el-ev-cal-popup-item--placeholder {
    opacity: 0.72;
    cursor: default;
    border: 1px dashed rgba(0, 0, 0, 0.18);
}
.el-ev-cal-popup-item--placeholder:hover {
    background: inherit;
    transform: none;
}
html.night-mode .el-ev-cal-popup-item--placeholder,
.el-preview-strip--dark .el-ev-cal-popup-item--placeholder {
    border-color: rgba(255, 255, 255, 0.2);
}
.el-ev-cal-popup-ph-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 6px;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--el-text-muted);
    font-style: italic;
}
.el-ev-cal-popup-ph-chip .mdi { font-size: 0.85rem; }

/* Tooltip */
.el-preview-timeline-tooltip {
    position: absolute;
    bottom: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%) scale(0.92);
    transform-origin: bottom center;
    background: #0b1220;
    color: #ffffff;
    padding: 8px 12px;
    border-radius: 8px;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    line-height: 1.4;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.18s var(--el-ease-soft);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
    z-index: 4;
}
.el-preview-timeline-tooltip::after {
    content: '';
    position: absolute;
    top: 100%; left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: #0b1220;
}
.el-preview-timeline-tooltip-type {
    display: inline-block;
    margin-top: 2px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
}
.el-preview-timeline-dot:hover .el-preview-timeline-tooltip,
.el-preview-timeline-dot:focus-visible .el-preview-timeline-tooltip {
    opacity: 1;
    transform: translateX(-50%) scale(1);
    pointer-events: auto;
}

/* Legend under the track */
.el-preview-timeline-legend {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 10px 18px;
    margin-top: 14px;
    font-size: 0.72rem;
    color: var(--el-text-muted);
}
.el-preview-strip--dark .el-preview-timeline-legend { color: var(--el-text-inv-muted); }
.el-preview-timeline-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

@media (max-width: 600px) {
    .el-preview-timeline-axis { font-size: 0.65rem; }
    .el-preview-timeline-today { font-size: 0.6rem; }
    .el-preview-timeline-legend { font-size: 0.66rem; gap: 8px 12px; }
    .el-preview-timeline-dot { width: 10px; height: 10px; }
    .el-preview-timeline-tooltip { font-size: 0.72rem; padding: 6px 10px; }
}

/* Footer CTA (below the 3-card grid) */
.el-preview-cta {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 36px;
}

/* ── Weather strip ──────────────────────────────────────────────────
   Dark navy block showing live Court Conditions (current temp +
   wind + description) on the left and a 4-band Today's Play Forecast
   on the right (Morning / Afternoon / Evening / Night). Playability
   dots: green (good), amber (caution), red (bad). */
/* Weather strip — sits on a light-blue tinted surface (distinct from
   the other light-cream strips) to feel like a sky panel. The bg
   comes from the shared `.el-preview-strip--sky` class so it stays
   in lockstep with the Latest Stories strip above it. */
.el-weather-strip { padding: clamp(32px, 4vw, 56px) 0; }
.el-weather-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: clamp(24px, 4vw, 56px);
    align-items: center;
}
@media (max-width: 820px) {
    .el-weather-grid { grid-template-columns: 1fr; }
}
.el-weather-label {
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--club-accent);
    opacity: 0.9;
    margin-bottom: 8px;
}
html.night-mode .el-weather-label { color: var(--el-accent); }
.el-weather-now-row {
    display: flex;
    align-items: center;
    gap: 18px;
}
.el-weather-now-icon {
    font-size: 3.6rem;
    color: var(--club-accent);
    filter: drop-shadow(0 2px 10px rgba(2, 12, 146, 0.18));
}
html.night-mode .el-weather-now-icon {
    color: var(--el-accent);
    filter: drop-shadow(0 2px 10px rgba(125, 211, 252, 0.25));
}
.el-weather-now-temp {
    font-size: clamp(2.4rem, 4vw, 3rem);
    font-weight: 800;
    color: var(--el-text);
    letter-spacing: -0.02em;
    line-height: 1;
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}
html.night-mode .el-weather-now-temp { color: var(--el-text-inv); }
.el-weather-now-desc {
    font-size: 0.98rem;
    font-weight: 500;
    color: var(--el-text-muted);
    letter-spacing: 0;
}
html.night-mode .el-weather-now-desc { color: var(--el-text-inv-muted); }
.el-weather-now-wind {
    margin-top: 4px;
    font-size: 0.86rem;
    color: var(--el-text-muted);
}
html.night-mode .el-weather-now-wind { color: var(--el-text-inv-muted); }

.el-weather-forecast-title {
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--el-text);
    margin-bottom: 14px;
    text-align: center;
}
html.night-mode .el-weather-forecast-title { color: var(--el-text-inv); }
.el-weather-bands {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}
@media (max-width: 560px) {
    .el-weather-bands { grid-template-columns: repeat(2, 1fr); gap: 10px; }
}
.el-weather-band {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 12px 8px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.6);
    border: 1px solid rgba(2, 12, 146, 0.1);
    transition: background 0.2s, border-color 0.2s, transform 0.2s;
}
.el-weather-band:hover {
    background: rgba(255, 255, 255, 0.85);
    border-color: rgba(2, 12, 146, 0.22);
    transform: translateY(-1px);
}
html.night-mode .el-weather-band {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.08);
}
html.night-mode .el-weather-band:hover {
    background: rgba(255, 255, 255, 0.07);
    border-color: rgba(125, 211, 252, 0.28);
}
.el-weather-band-name {
    font-size: 0.78rem;
    color: var(--club-accent);
    letter-spacing: 0.02em;
    font-weight: 700;
}
html.night-mode .el-weather-band-name { color: var(--el-accent); }
.el-weather-band-icon {
    font-size: 1.6rem;
    color: var(--club-accent);
    opacity: 0.9;
    margin-bottom: 2px;
}
html.night-mode .el-weather-band-icon { color: var(--el-accent); }
.el-weather-band-temp {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--el-text);
    letter-spacing: -0.01em;
}
html.night-mode .el-weather-band-temp { color: var(--el-text-inv); }
.el-weather-band-play {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--el-text-muted);
}
html.night-mode .el-weather-band-play { color: var(--el-text-inv-muted); }
.el-weather-band-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: #94a3b8;
}
.el-weather-band-play--good    .el-weather-band-dot { background: #22c55e; box-shadow: 0 0 8px rgba(34, 197, 94, 0.45); }
.el-weather-band-play--caution .el-weather-band-dot { background: #f59e0b; box-shadow: 0 0 8px rgba(245, 158, 11, 0.45); }
.el-weather-band-play--bad     .el-weather-band-dot { background: #ef4444; box-shadow: 0 0 8px rgba(239, 68, 68, 0.45); }
.el-weather-band-play--good    { color: #16a34a; }
.el-weather-band-play--caution { color: #d97706; }
.el-weather-band-play--bad     { color: #dc2626; }
html.night-mode .el-weather-band-play--good    { color: #86efac; }
html.night-mode .el-weather-band-play--caution { color: #fcd34d; }
html.night-mode .el-weather-band-play--bad     { color: #fca5a5; }

.el-weather-disclaimer {
    margin: 22px 0 0;
    text-align: center;
    font-size: 0.76rem;
    color: var(--el-text-muted);
    opacity: 0.8;
}
html.night-mode .el-weather-disclaimer { color: var(--el-text-inv-muted); }
.el-preview-strip--dark .el-preview-cta .el-btn--outline {
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.5);
}
.el-preview-strip--dark .el-preview-cta .el-btn--outline:hover {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-green);
}

/* ── WhatsApp + social FAB polish (reuses .cs- classes from club-site.css) ──
   Keep them ABOVE the sticky nav (z-index: 40) so they're never
   clipped by header stacking contexts on mobile. They were
   previously at z-index 30 which sat BELOW .el-nav and was
   getting hidden on Android viewports. */
.cs-wa-fab,
.cs-social-fabs {
    z-index: 70;
    /* Defensive — any ancestor's transform/filter/will-change wraps
       fixed-positioned descendants into a new containing block.
       The `inset` reaffirmation keeps the FABs anchored to the
       viewport edge regardless of parent stacking-context tricks. */
    position: fixed !important;
}
.cs-wa-fab     { right: 24px !important; bottom: 24px !important; left: auto !important; top: auto !important; }
.cs-social-fabs { left: 24px !important; bottom: 24px !important; right: auto !important; top: auto !important; }

/* Pop-in / pop-out transitions on every FAB. Default state (visible)
   uses a back-out easing that overshoots ~10 % past scale 1 then
   settles — reads as a confident "pop in". Hidden state uses a
   snappier ease-in — reads as a quick "pop out". */
.cs-wa-fab,
.cs-social-fabs,
.el-ace-fab {
    transition:
        opacity 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
        transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1),
        box-shadow 0.25s;
}
/* Hidden state — driven by the JS-toggled body.is-fab-hidden class.
   Page loads at top → hidden; scroll past 80 px → revealed (pop in);
   near bottom (within 200 px of the footer) → hidden again (pop out).
   Smaller scale (0.4) for more pop punch on both directions. */
body.is-fab-hidden .cs-wa-fab,
body.is-fab-hidden .cs-social-fabs,
body.is-fab-hidden .el-ace-fab {
    opacity: 0;
    transform: translateY(20px) scale(0.4);
    pointer-events: none;
    transition:
        opacity 0.22s cubic-bezier(0.55, 0, 0.85, 0.35),
        transform 0.28s cubic-bezier(0.55, 0, 0.85, 0.35);
}
/* Mobile drawer open — hide every floating chrome surface so nothing
   stacks on top of the drawer. Same pop-out feel as .is-fab-hidden,
   plus the edit-mode overlay (only present when a committee admin is
   editing). Body class set by the drawer open/close handler in
   eldoraigne.js. */
body.el-nav-drawer-open .cs-wa-fab,
body.el-nav-drawer-open .cs-social-fabs,
body.el-nav-drawer-open .el-ace-fab,
body.el-nav-drawer-open .el-edit-overlay {
    opacity: 0;
    transform: translateY(20px) scale(0.4);
    pointer-events: none;
    transition:
        opacity 0.22s cubic-bezier(0.55, 0, 0.85, 0.35),
        transform 0.28s cubic-bezier(0.55, 0, 0.85, 0.35);
}
/* Admin-FAB container is horizontally centered (translateX(-50%)) — the
   pop-out transform has to preserve that translate or the pill pair
   jumps to the LEFT edge as it fades. Both the mobile nav drawer AND
   the FAQ editor drawer hide the admin pills — they'd otherwise cover
   the drawer's own footer/save bar. */
body.el-nav-drawer-open #el-admin-fabs,
body.fq-editor-open #el-admin-fabs {
    opacity: 0;
    transform: translateX(-50%) translateY(20px) scale(0.4);
    pointer-events: none;
    transition:
        opacity 0.22s cubic-bezier(0.55, 0, 0.85, 0.35),
        transform 0.28s cubic-bezier(0.55, 0, 0.85, 0.35);
}

/* ── Responsive ─────────────────────────────────────────────────────── */
/* Tablet — 6 columns crush at ≤1180 (matches the nav → hamburger threshold).
   Collapse to a clean 3-col grid so Brand/Explore/More/Club Info/Hours/Legal
   wrap into two neat rows of three instead of squeezing across a full row. */
@media (max-width: 1180px) {
    .el-footer-grid { grid-template-columns: 1fr 1fr 1fr; }
}
@media (max-width: 960px) {
    .el-footer-grid { grid-template-columns: 1fr 1fr; }
}
/* Nav → hamburger threshold. Raised from ≤720px to ≤1180px on
   2026-07-16 per operator review — 12 top-level links couldn't fit
   on a single row between 721-1180px, and the previous intermediate
   "shrink font + wrap onto 2 rows" band produced a broken-looking
   halfway state. Better to snap straight to the hamburger drawer
   at any width where the full nav can't cleanly display.

   The hero-logo width tweak for the tablet-portrait band stays
   separate below since it's a hero-layout concern, not nav. */
@media (max-width: 1180px) {
    .el-nav-links { display: none; }
    .el-nav-hamburger { display: inline-flex; }
    /* Back to flex on collapsed nav so actions + hamburger sit
       side-by-side on the right without stacking in the same grid
       cell. */
    .el-nav-inner {
        display: flex;
        justify-content: flex-end;
        gap: 6px;
    }
    .el-nav-actions { gap: 6px; grid-column: auto; justify-self: auto; }
    .el-nav-hamburger { grid-column: auto; justify-self: auto; }
}

/* Tablet-portrait hero-logo band. Base clamp bottoms out around
   180px in this width range which is too small for the empty hero
   canvas above the headline. Bump the viewport share to keep the
   club mark as the visual anchor. Nav is already collapsed at this
   width by the ≤1180px block above — nothing to do for it here. */
@media (min-width: 721px) and (max-width: 1180px) {
    .el-hero-logo {
        width: calc(clamp(260px, 45vw, 340px) * (var(--img-size-pct, 100) / 100));
    }
}

/* Mobile-only refinements — hero title shrink, hide login/user text,
   book button tighter, footer collapses to single column. Nav has
   already collapsed to hamburger at ≤1180px above; these are the
   phone-specific squeezes. */
@media (max-width: 720px) {
    #cs-member-login-btn span,
    #cs-nav-user span { display: none; }
    .el-btn-book { padding: 8px 12px; font-size: 0.72rem; }
    .el-hero--home .el-hero-title--home { font-size: clamp(2.6rem, 11vw, 4.4rem); }
    .el-footer-grid { grid-template-columns: 1fr; }
    .el-preview-header { flex-direction: column; align-items: flex-start; }
}

/* Mobile nav drawer (rendered by eldoraigne.js when hamburger tapped) */
/* Right-side slide-out. Compact (320px on wide phones, 88vw on narrow),
   scrolls internally when the item list overflows the viewport,
   dimmed backdrop behind it. Slides in via transform so we can animate
   both open and close smoothly (opacity toggle alone doesn't give the
   sliding-in-from-edge feel operators expect from a modern drawer). */
.el-nav-drawer {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    height: 100dvh; /* dynamic — accounts for mobile URL bar chrome */
    width: min(320px, 88vw);
    background: var(--el-hero);
    color: var(--el-text-inv);
    z-index: 51;
    padding: 64px 0 24px;
    display: flex;
    flex-direction: column;
    gap: 0;
    transform: translateX(100%);
    transition: transform 0.28s cubic-bezier(0.32, 0.72, 0.32, 1);
    box-shadow: -8px 0 32px rgba(0, 0, 0, 0.32);
    overflow-y: auto;
    overscroll-behavior: contain; /* prevent scroll chain to page under */
    -webkit-overflow-scrolling: touch;
}
.el-nav-drawer.is-open { transform: translateX(0); }

/* Dimmed backdrop — real DOM element injected by eldoraigne.js on open
   so it can carry a click-to-close handler. Sits below the drawer,
   above everything else. */
.el-nav-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 50;
    opacity: 0;
    transition: opacity 0.22s;
    cursor: pointer;
}
.el-nav-drawer-backdrop.is-open { opacity: 1; }

.el-nav-drawer a {
    padding: 12px 20px;
    font-size: 0.9rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    color: var(--el-text-inv);
    text-decoration: none;
    flex: 0 0 auto; /* don't let flex-column stretch each row when there's extra height */
}
.el-nav-drawer a:hover { background: rgba(255, 255, 255, 0.05); }
.el-nav-drawer a.is-active { color: var(--el-accent); }
.el-nav-drawer-close {
    position: absolute;
    top: 14px; right: 14px;
    width: 40px; height: 40px;
    display: inline-grid;
    place-items: center;
    background: none;
    border: 0;
    color: var(--el-text-inv);
    font-size: 1.5rem;
    cursor: pointer;
    border-radius: 50%;
    z-index: 1;
    transition: background 0.15s;
}
.el-nav-drawer-close:hover { background: rgba(255, 255, 255, 0.08); }

/* ═══════════════════════════════════════════════════════════════════════
   NIGHT-MODE overrides for the nav + footer + icon buttons + CTAs.
   --el-hero is left alone globally so brand-navy elsewhere stays navy;
   these rules target the specific surfaces the user wants flipped.
   ═══════════════════════════════════════════════════════════════════ */

/* Nav + footer go true-black in night mode so the header bar reads as
   part of the black page instead of a navy strip on top of it. */
html.night-mode .el-nav    { background: #000000; border-bottom-color: rgba(255, 255, 255, 0.08); }
html.night-mode .el-footer { background: #000000; }
html.night-mode .el-nav-drawer { background: #000000; }

/* Icon buttons (night toggle, cart, login, user pill) — soft lifted
   shadow + sky-blue glow on hover so they pop off the black chrome
   without a visible ring. */
html.night-mode #cs-night-toggle,
html.night-mode #cs-cart-btn,
html.night-mode #cs-member-login-btn,
html.night-mode #cs-nav-user {
    background: rgba(255, 255, 255, 0.05);
    border: 0;
    box-shadow:
        0 4px 14px rgba(0, 0, 0, 0.6),
        inset 0 1px 0 rgba(255, 255, 255, 0.15);
}
html.night-mode #cs-night-toggle:hover,
html.night-mode #cs-cart-btn:hover,
html.night-mode #cs-member-login-btn:hover,
html.night-mode #cs-nav-user:hover {
    background: rgba(255, 255, 255, 0.12);
    box-shadow:
        0 10px 28px rgba(0, 0, 0, 0.7),
        0 0 18px rgba(125, 211, 252, 0.45),
        0 0 36px rgba(125, 211, 252, 0.22),
        inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

/* Hero CTA buttons — matching white glow treatment in night mode so
   "BOOK A COURT" + "EXPLORE MEMBERSHIPS" pop off the dark. */
html.night-mode .el-hero .el-btn--inverse {
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.4),
        0 0 24px rgba(255, 255, 255, 0.25),
        0 0 48px rgba(255, 255, 255, 0.15);
}
html.night-mode .el-hero .el-btn--inverse:hover {
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.7),
        0 0 32px rgba(255, 255, 255, 0.45),
        0 0 80px rgba(255, 255, 255, 0.25);
}
html.night-mode .el-hero .el-btn--outline {
    border-color: rgba(255, 255, 255, 0.7);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.15),
        0 0 18px rgba(255, 255, 255, 0.15);
}
html.night-mode .el-hero .el-btn--outline:hover {
    border-color: #ffffff;
    background: rgba(255, 255, 255, 0.08);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.4),
        0 0 28px rgba(255, 255, 255, 0.35);
}

/* ═══════════════════════════════════════════════════════════════════════
   COMMITTEE EDIT MODE — only rendered by edit-mode.js for logged-in
   committee users. FAB bottom-right; overlays appear over every
   [data-img-slot] element when body.el-edit-mode is active.
   ═══════════════════════════════════════════════════════════════════ */

/* Shared admin-FAB container — hosts Design + Edit side-by-side. Mounted
   lazily by edit-mode.js + design-mode.js (either script creates it
   whichever fires first). Solo FAB naturally auto-centers because it's
   the only flex child. Two FABs sit next to each other with a gap. */
#el-admin-fabs {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 99999;
    display: flex;
    align-items: center;
    gap: 8px;
    pointer-events: none; /* children opt back in below */
}
#el-admin-fabs > * { pointer-events: auto; }
/* Order enforced by CSS regardless of DOM insertion order so Design
   always sits left of Edit. */
#el-admin-fabs > #el-design-fab { order: 1; }
#el-admin-fabs > #el-edit-fab   { order: 2; }

.el-edit-fab {
    /* Sits inside #el-admin-fabs (flex row) — no fixed positioning of
       its own. Hover translateY still works. Admin-only affordance —
       dashed border + 50% fill/text opacity so it reads as "operator
       tool, not a public CTA". Uses club green so the pill stays
       legible on any background (navy-on-navy the border vanished).
       Full opacity on hover; brighter green + heavy glow when active
       (edit-mode toggled ON). */
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px; /* -2 to absorb the 2px border */
    border-radius: 999px;
    background: color-mix(in srgb, var(--el-green) 50%, transparent);
    color: color-mix(in srgb, var(--el-green-text) 50%, transparent);
    border: 2px dashed var(--el-green);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    box-shadow: 0 12px 32px rgba(188, 255, 0, 0.18);
    cursor: pointer;
    transition: transform 0.2s var(--el-ease-soft), background 0.2s, color 0.2s, filter 0.2s, box-shadow 0.2s;
}
.el-edit-fab:hover {
    transform: translateY(-2px);
    filter: brightness(1.05);
    background: var(--el-green);
    color: var(--el-green-text);
    box-shadow: 0 12px 32px rgba(188, 255, 0, 0.35);
}
.el-edit-fab.is-active {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-green);
    box-shadow: 0 12px 32px rgba(188, 255, 0, 0.55);
}
.el-edit-fab .mdi { font-size: 1.1rem; }

/* Wrap we add around <img> elements so we can overlay a pencil. */
.el-img-wrap {
    position: relative;
    display: block;
    line-height: 0;           /* kill inline-image gap */
    width: 100%;
    height: 100%;
}
.el-img-wrap > img { width: 100%; height: 100%; display: block; }

/* The pencil overlay itself — hidden by default; visible when
   body.el-edit-mode is set. */
.el-edit-overlay {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    background: rgba(2, 12, 146, 0.55);
    backdrop-filter: blur(4px);
    color: var(--el-text-inv);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s var(--el-ease-soft);
    /* Inherit rounded corners from the parent so we don't bleed past
       rounded images like the about clubhouse. */
    border-radius: inherit;
}
body.el-edit-mode .el-edit-overlay {
    opacity: 1;
    pointer-events: auto;
}
.el-edit-pick {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 20px;
    border-radius: 999px;
    background: var(--el-green);
    color: var(--el-green-text);
    border: 0;
    font-size: 0.82rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
    transition: transform 0.18s var(--el-ease-soft), filter 0.18s;
}
.el-edit-pick:hover { transform: translateY(-1px); filter: brightness(1.08); }
.el-edit-pick .mdi { font-size: 1rem; }
.el-edit-slot-label {
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    opacity: 0.85;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.25);
}
/* Size slider — added when an editable element carries
   `data-img-resizable`. Lives in the same overlay row as the
   "Change image" pill. Slider value persists per-slot in
   localStorage; the element is scaled via --img-size-pct. */
.el-edit-size {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.45);
    color: #ffffff;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    cursor: ew-resize;
    pointer-events: auto;
}
.el-edit-size .mdi { font-size: 1rem; opacity: 0.85; }
.el-edit-size-input {
    -webkit-appearance: none;
    appearance: none;
    width: 140px;
    height: 4px;
    background: rgba(255, 255, 255, 0.3);
    border-radius: 999px;
    outline: none;
    cursor: ew-resize;
}
.el-edit-size-input::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px; height: 14px;
    border-radius: 50%;
    background: var(--el-accent);
    border: 2px solid #ffffff;
    cursor: ew-resize;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.el-edit-size-input::-moz-range-thumb {
    width: 14px; height: 14px;
    border-radius: 50%;
    background: var(--el-accent);
    border: 2px solid #ffffff;
    cursor: ew-resize;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.el-edit-size-val {
    min-width: 40px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Hero backgrounds are normally decorative — in edit mode force them
   visible AND lift them above .el-container (which has z-index: 1) so
   the overlay pencil button is actually clickable. */
body.el-edit-mode .el-hero-bg--day,
body.el-edit-mode .el-hero-bg--night {
    opacity: 0.75 !important;
    mix-blend-mode: normal;
    z-index: 10;
}
body.el-edit-mode .el-hero-bg {
    outline: 2px dashed rgba(255, 255, 255, 0.35);
    outline-offset: -4px;
}

/* For hero-bg overlays specifically, switch from full-cover to a
   corner pill — day top-left, night top-right — so the two don't
   overlap and the hero copy stays readable underneath. */
.el-hero-bg > .el-edit-overlay {
    inset: auto;
    top: 20px;
    background: transparent;
    backdrop-filter: none;
    align-items: flex-start;
    justify-content: flex-start;
    width: auto;
    height: auto;
    flex-direction: row;
    gap: 8px;
    padding: 0;
    pointer-events: none;   /* re-enabled per child */
}
.el-hero-bg--day   > .el-edit-overlay { left: 20px; }
.el-hero-bg--night > .el-edit-overlay { right: 20px; }
.el-hero-bg > .el-edit-overlay > .el-edit-pick,
.el-hero-bg > .el-edit-overlay > .el-edit-slot-label {
    pointer-events: auto;
}
.el-hero-bg > .el-edit-overlay .el-edit-slot-label {
    background: rgba(2, 12, 146, 0.75);
    color: var(--el-text-inv);
}

/* ═══════════════════════════════════════════════════════════════════════
   ABOUT THE CLUB — embedded section below the home hero
   ═══════════════════════════════════════════════════════════════════ */

.el-about {
    background: var(--el-surface);
}
.el-about-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(32px, 5vw, 72px);
    align-items: center;
}
.el-about-copy .el-section-title {
    font-size: clamp(2rem, 4vw, 3rem);
    line-height: 1.08;
    margin-bottom: 24px;
}
.el-about-body {
    font-size: 1.02rem;
    line-height: 1.7;
    color: var(--el-text);
    opacity: 0.88;
    margin: 0;
    max-width: 560px;
}
.el-about-image {
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    aspect-ratio: 4 / 3;
    background: var(--el-surface-alt);
    /* Shared sky-blue glow — see --el-glow-idle / --el-glow-hover at
       :root and html.night-mode for the source-of-truth values. */
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft), transform 0.35s var(--el-ease-soft);
}
.el-about-image:hover {
    transform: translateY(-3px);
    box-shadow: var(--el-glow-hover);
}
.el-about-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.el-about-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(24px, 4vw, 56px);
    margin-top: clamp(48px, 7vw, 88px);
    padding-top: clamp(32px, 5vw, 56px);
    border-top: 1px solid var(--el-border);
}

/* Scroll-triggered slide-in — start vector depends on scroll direction:
     .is-from-left  (scrolling DOWN to stats)  -> slide in from the left
     .is-from-top   (scrolling UP   to stats)  -> drop in from above
   Staggered so the three tiles enter one after the other. */
.el-about-stat {
    opacity: 0;
    transition:
        opacity 0.7s var(--el-ease-soft),
        transform 0.7s var(--el-ease-soft);
    cursor: default;
}
.el-about-stats.is-from-left .el-about-stat { transform: translateX(-50px); }
.el-about-stats.is-from-top  .el-about-stat { transform: translateY(-50px); }
/* Default start (before any direction class) — from left */
.el-about-stats:not(.is-from-left):not(.is-from-top) .el-about-stat {
    transform: translateX(-50px);
}

.el-about-stats.is-visible .el-about-stat:nth-child(1) {
    opacity: 1;
    transform: translate(0, 0);
    transition-delay: 0s;
}
.el-about-stats.is-visible .el-about-stat:nth-child(2) {
    opacity: 1;
    transform: translate(0, 0);
    transition-delay: 0.12s;
}
.el-about-stats.is-visible .el-about-stat:nth-child(3) {
    opacity: 1;
    transform: translate(0, 0);
    transition-delay: 0.24s;
}

/* Hover: slight grow + glowing number. Only when already visible —
   otherwise hover on a hidden (translateX -50) stat would short-circuit
   the slide-in animation. */
.el-about-stats.is-visible .el-about-stat {
    transition:
        opacity 0.7s var(--el-ease-soft),
        transform 0.35s var(--el-ease-soft);
}
.el-about-stats.is-visible .el-about-stat:hover {
    transform: translate(0, 0) scale(1.1);
}
.el-about-stat-num {
    font-family: 'Inter', sans-serif;
    font-weight: 900;
    font-size: clamp(2.4rem, 5.5vw, 4rem);
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--el-text);
    margin-bottom: 10px;
    font-variant-numeric: tabular-nums;  /* stable width as numbers tick */
    transition: text-shadow 0.35s var(--el-ease-soft), color 0.35s var(--el-ease-soft);
}
/* Hover = tennis-ball green GLOW only. Number colour stays navy (day)
   or white (night) — only the bloom around it goes green. Gives the
   "tennis-ball lights up behind the number" effect without changing
   the readable colour. */
.el-about-stats.is-visible .el-about-stat:hover .el-about-stat-num {
    text-shadow:
        0 0 14px rgba(188, 255, 0, 0.85),
        0 0 32px rgba(188, 255, 0, 0.6),
        0 0 60px rgba(188, 255, 0, 0.4),
        0 0 100px rgba(188, 255, 0, 0.22);
}
.el-about-stat-label {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--el-text);
    margin-bottom: 4px;
}
.el-about-stat-sub {
    font-size: 0.86rem;
    color: var(--el-text-muted);
    line-height: 1.45;
    max-width: 220px;
}

@media (max-width: 860px) {
    .el-about-grid { grid-template-columns: 1fr; gap: 32px; }
    .el-about-image { aspect-ratio: 16 / 10; }
    .el-about-stats { grid-template-columns: 1fr; gap: 28px; }
    .el-about-stats { text-align: left; }
}

/* ═══════════════════════════════════════════════════════════════════════
   FACILITIES / BOOK YOUR COURT — page-specific styles
   ═══════════════════════════════════════════════════════════════════ */

/* Hero — royal navy angled gradient matching --club-accent. Lighter top-left
   → deep navy bottom-right, with a subtle sky-blue highlight in the upper
   quadrant for warmth. Night mode flips to a near-black gradient so the
   hero conforms to the rest of the dark page instead of standing out as
   the only navy region. */
.el-hero--facilities {
    background:
        radial-gradient(ellipse at 20% 0%, rgba(125, 211, 252, 0.18) 0%, transparent 55%),
        linear-gradient(155deg, #1a26b0 0%, #0d16a0 28%, #020c92 55%, #000659 100%);
    padding: 88px 0 104px;
}
/* All non-home heroes keep the default brand-navy fill (var(--el-hero))
   in night mode too. We previously forced them to plain #000000 to
   match the body, but that left the heroes reading as flat dead-zones
   while the rest of the page kept its starfield + tints — the bright
   navy is what every other page shows and what the user expects, so
   we let it stand. .el-hero--home stays special (photo bg flip). */
.el-hero--facilities::after {
    /* override the generic .el-hero::after — already-gradient bg doesn't need the radial */
    background: radial-gradient(ellipse at 80% 100%, rgba(188, 255, 0, 0.06) 0%, transparent 55%);
}
.el-hero--facilities .el-hero-title { max-width: none; }

/* ── Court cards — shown on the home page Facilities strip AND on the
   Facilities / Book-your-court page. Each card has an uploadable photo
   (slot: facility-court-a..e), a title + status dot, a badge, and a
   surface label. Idle + hover navy glow mirrors the About image so the
   visual language is consistent across the site. */
.el-court-cards {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 18px;
    margin-top: 40px;
    justify-content: center;
}
@media (max-width: 1100px) { .el-court-cards { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 680px)  { .el-court-cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px)  { .el-court-cards { grid-template-columns: 1fr; } }

/* ── Amenities grid (Tier 3 · 3.1, 2026-07-17) ──────────────────────
   Icon + title + short description card, rendered on /facilities in
   place of the moved Reservations grid. auto-fit + minmax lets the
   grid collapse gracefully: 3-col desktop → 2-col tablet → 1-col
   phone without a media query per breakpoint. */
.el-amenities-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 20px;
    margin-top: 40px;
}
.el-amenity-card {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    padding: 26px 24px;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft), transform 0.35s var(--el-ease-soft);
    text-align: left;
}
.el-amenity-card:hover {
    box-shadow: var(--el-glow-hover);
    transform: translateY(-3px);
}
html.night-mode .el-amenity-card {
    background: #12141b;
}
.el-amenity-icon {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--club-accent) 12%, transparent);
    color: var(--club-accent);
    font-size: 1.5rem;
    margin-bottom: 14px;
}
.el-amenity-icon i { line-height: 1; }
html.night-mode .el-amenity-icon {
    background: color-mix(in srgb, var(--club-accent) 22%, transparent);
}
.el-amenity-title {
    margin: 0 0 8px;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--el-text);
    line-height: 1.3;
}
.el-amenity-body {
    margin: 0;
    color: var(--el-text-muted);
    line-height: 1.55;
    font-size: 0.95rem;
}
/* Narrow screens — collapse the card photo. The full-width 16:10
   image was eating most of the viewport per card, so on phones the
   cards become compact text-only tiles (court name + status dot +
   floodlight badge + surface). The photo is still in the DOM (we
   don't display:none it) so a tap can still open the lightbox if
   that's wired in future. Hides at ≤520px which catches the
   2-col → 1-col transition + small phones in 2-col.

   EXCEPTION — if the photo container holds a maintenance ribbon
   (e.g. "LIGHTING UNDER MAINTENANCE"), keep the photo visible as a
   compact ribbon-only strip so the warning still surfaces on mobile.
   The ribbon is reflowed inline (position: static, no offsets) so it
   sits as a normal banner above the card body instead of being clipped
   by the empty/zero-height photo container. */
@media (max-width: 520px) {
    .el-court-card-photo { display: none; }
    .el-court-card-body  { padding: 14px 16px 16px; }

    /* Photo container with a ribbon — show as a slim banner */
    .el-court-card-photo:has(.el-court-card-ribbon) {
        display: block;
        aspect-ratio: auto;
        background: transparent;
        padding: 0;
        overflow: visible;
    }
    /* Hide the actual image / placeholder regardless — only the
       ribbon comes through. */
    .el-court-card-photo img,
    .el-court-card-photo .el-court-card-media-fallback {
        display: none;
    }
    /* Ribbon goes inline (static flow) instead of absolute over the
       photo. Slight horizontal bleed kept so it visually anchors to
       the card edge. */
    .el-court-card-photo .el-court-card-ribbon {
        position: static;
        top: auto; left: auto; right: auto;
        margin: 0;
        padding: 7px 14px;
        border-radius: var(--el-radius) var(--el-radius) 0 0;
        box-shadow: none;
    }
    /* Drop the little flag-tail triangles when the ribbon is inline
       — they only make sense when the ribbon hangs off a photo. */
    .el-court-card-photo .el-court-card-ribbon::before,
    .el-court-card-photo .el-court-card-ribbon::after { display: none; }
}

.el-court-card {
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border-radius: var(--el-radius);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition:
        box-shadow 0.35s var(--el-ease-soft),
        transform 0.35s var(--el-ease-soft);
}
.el-court-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--el-glow-hover);
}
html.night-mode .el-court-card {
    background: rgba(255, 255, 255, 0.04);
}
/* Photo container is a FIXED-aspect frame — image fills it via
   object-fit: cover (zooms to fit without distortion, crops excess).
   Image is absolutely positioned so its natural dimensions NEVER
   drive the container's height — every card stays the same shape
   regardless of whether the slot has a real photo, the square logo
   placeholder, or nothing at all. */
.el-court-card-photo {
    aspect-ratio: 16 / 10;
    background: var(--el-surface-alt);
    position: relative;
    overflow: hidden;
}
.el-court-card-photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.el-court-card-body {
    padding: 16px 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.el-court-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.el-court-card-name {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--el-text);
}
.el-court-card-dot {
    width: 10px; height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}
.el-court-card-dot--on      { background: #4ade80; box-shadow: 0 0 8px rgba(74, 222, 128, 0.8); }
.el-court-card-dot--limited { background: #fb923c; box-shadow: 0 0 8px rgba(251, 146, 60, 0.8); }
.el-court-card-dot--off     { background: #ef4444; box-shadow: 0 0 8px rgba(239, 68, 68, 0.8); }
.el-court-card-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(2, 12, 146, 0.08);
    color: var(--el-text);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    align-self: flex-start;
    border: 1px solid rgba(2, 12, 146, 0.15);
}
html.night-mode .el-court-card-badge {
    background: rgba(255, 255, 255, 0.08);
    color: var(--el-text);
    border-color: rgba(255, 255, 255, 0.15);
}
.el-court-card--daylight .el-court-card-badge {
    background: rgba(251, 146, 60, 0.14);
    border-color: rgba(251, 146, 60, 0.4);
    color: #9a3412;
}
html.night-mode .el-court-card--daylight .el-court-card-badge {
    color: #fb923c;
}
/* Maintenance ribbon — red stripe across the top of the card photo.
   The badge below keeps stating the real capability (Daylight Only)
   since the court itself is still playable during daylight. */
.el-court-card-ribbon {
    position: absolute;
    top: 10px;
    left: -8px;
    right: -8px;
    z-index: 3;
    padding: 6px 14px;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: center;
    color: #ffffff;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
}
.el-court-card-ribbon::before,
.el-court-card-ribbon::after {
    content: '';
    position: absolute;
    top: 100%;
    width: 8px; height: 8px;
    background: currentColor;
    opacity: 0.65;
    clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.el-court-card-ribbon::before { left: 0;  transform: scaleX(-1); }
.el-court-card-ribbon::after  { right: 0; }
.el-court-card-ribbon--maintenance {
    background: linear-gradient(90deg, #ef4444, #dc2626);
}

/* Live-status pill — what's happening on this court RIGHT NOW. */
.el-court-card-live {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    align-self: flex-start;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin-top: 2px;
}
.el-court-card-live-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
    animation: el-live-pulse 1.6s ease-in-out infinite;
}
@keyframes el-live-pulse {
    0%, 100% { opacity: 1;   transform: scale(1); }
    50%      { opacity: 0.4; transform: scale(0.85); }
}
.el-court-card-live--coaching {
    background: rgba(251, 146, 60, 0.14);
    color: #9a3412;
    border: 1px solid rgba(251, 146, 60, 0.4);
}
.el-court-card-live--league {
    background: rgba(239, 68, 68, 0.14);
    color: #991b1b;
    border: 1px solid rgba(239, 68, 68, 0.4);
}
.el-court-card-live--social {
    background: rgba(125, 211, 252, 0.18);
    color: #075985;
    border: 1px solid rgba(125, 211, 252, 0.55);
}
.el-court-card-live--booked {
    background: rgba(2, 12, 146, 0.1);
    color: var(--el-text);
    border: 1px solid rgba(2, 12, 146, 0.3);
}
.el-court-card-live--maintenance {
    background: rgba(107, 114, 128, 0.18);
    color: #374151;
    border: 1px solid rgba(107, 114, 128, 0.45);
}
html.night-mode .el-court-card-live--coaching    { color: #fdba74; border-color: rgba(251, 146, 60, 0.4); }
html.night-mode .el-court-card-live--league      { color: #fca5a5; border-color: rgba(239, 68, 68, 0.4); }
html.night-mode .el-court-card-live--social      { color: #7dd3fc; }
html.night-mode .el-court-card-live--booked      { color: #e5e7eb; border-color: rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.06); }
html.night-mode .el-court-card-live--maintenance { color: #d1d5db; }
.el-court-card-surface {
    font-size: 0.8rem;
    color: var(--el-text-muted);
    margin-top: 2px;
}

/* ── Day rail (Today + 7-day strip + week nav) ─────────────────────── */
/* nowrap keeps the TODAY/THIS MONTH button + chevrons + chip strip on
   a single line at any viewport width. Overflow inside the chip strip
   is absorbed by `.el-res-days` own `overflow-x: auto`. */
.el-res-rail {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 38px 0 18px;
    flex-wrap: nowrap;
}
/* TODAY / THIS MONTH anchor — FIXED width so both variants render at
   exactly the same size regardless of which rail (day chips or month
   chips) sits next to them. Without a fixed width the button grew
   to match neighbour chip widths, making TODAY (in the day rail)
   visibly wider than THIS MONTH (in the month rail). 92px sits
   between the two natural chip widths and gives the 2-line "THIS
   MONTH" label room without wrapping awkwardly. */
.el-res-today {
    flex: 0 0 92px;
    width: 92px;
    min-width: 92px;
    max-width: 92px;
    /* Locked to the same height as .el-res-day chips so the rail
       reads as a single uniform strip — month-rail's chips were
       rendering ~2px taller than day-rail's because day chips have
       short labels (MON/13/APR) while the filter buttons + month
       chips have a different intrinsic content stack. */
    min-height: 78px;
    box-sizing: border-box;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 12px 10px 10px;
    border-radius: 10px;
    background: var(--el-hero);
    color: var(--el-text-inv);
    border: 0;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    line-height: 1.1;
    text-align: center;
    transition: filter 0.2s, transform 0.2s, box-shadow 0.2s;
}
.el-res-today .mdi {
    font-size: 0.95rem;   /* match .el-res-day-dow size */
    opacity: 0.85;
    margin-bottom: 2px;
}
.el-res-today-line {
    display: block;
    font-size: 0.78rem;   /* match .el-res-day-dow tone */
    line-height: 1.1;
}
.el-res-today-line--spacer {
    font-size: 0.68rem;    /* match .el-res-day-mo height */
    visibility: hidden;
}
.el-res-today:hover {
    filter: brightness(1.12);
    transform: translateY(-1px);
    box-shadow: 0 6px 20px rgba(2, 12, 146, 0.25);
}
.el-res-nav {
    flex: 0 0 38px;          /* never grow OR shrink — chevron was rendering oblique on the Month rail when the row got tight */
    width: 38px; height: 38px;
    border-radius: 50%;
    border: 1px solid var(--el-border);
    background: transparent;
    color: var(--el-text);
    display: grid; place-items: center;
    font-size: 1.1rem;
    transition: background 0.2s, color 0.2s;
}
.el-res-nav:hover { background: var(--el-hero); color: var(--el-text-inv); }
.el-res-days {
    display: flex;
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;          /* allow shrink below content width so overflow-x kicks in instead of pushing the rail */
    overflow-x: auto;
    scrollbar-width: none;
    padding: 2px 2px 4px;  /* breathing room for focus ring */
}
.el-res-days::-webkit-scrollbar { display: none; }
.el-res-day {
    /* Fixed width — neither grow NOR shrink. Letting the chips flex
       made the Month rail look bigger than the Day rail whenever its
       12 chips happened to fit in the available width (they'd fill
       the row instead of overflowing). With both rails now always
       wider than the visible track, chip size stays consistent and
       the rail just scrolls horizontally. */
    flex: 0 0 80px;
    width: 80px;
    /* Match .el-res-today min-height so day chips, month chips, and
       the filter buttons all line up to the same row height. */
    min-height: 78px;
    box-sizing: border-box;
    padding: 12px 14px 10px;
    border-radius: 10px;
    border: 1px solid var(--el-border);
    background: transparent;
    color: var(--el-text);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s, color 0.2s, transform 0.2s;
}
.el-res-day-dow {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}
.el-res-day-num {
    font-size: 1.4rem;
    font-weight: 800;
    line-height: 1.1;
}
.el-res-day-mo {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    margin-top: 1px;
}
.el-res-day.is-active .el-res-day-mo { color: var(--el-accent); }
.el-res-day:hover { border-color: var(--el-hero); }
.el-res-day.is-active {
    background: var(--el-hero);
    color: var(--el-text-inv);
    border-color: var(--el-hero);
    transform: translateY(-2px);
    box-shadow: var(--el-shadow);
}
.el-res-day.is-active .el-res-day-dow { color: var(--el-accent); }
/* No "is-today" dot indicator on the chip — the active chip already
   reads as "current period" via the filled navy background colour, the
   extra dot was redundant and looked like a typo on the active state. */

/* ── The time × court grid ─────────────────────────────────────────── */
.el-res-grid-wrap {
    background: var(--el-surface);
    border: 1px solid var(--el-border);
    border-radius: var(--el-radius-lg);
    padding: 10px;
    box-shadow: var(--el-shadow-sm);
    overflow: hidden;
}
html.night-mode .el-res-grid-wrap {
    background: var(--el-surface-alt);
}
.el-res-grid {
    display: grid;
    /* First col: time axis. Remaining cols: one per court (set inline by JS). */
    grid-auto-rows: minmax(54px, auto);
    gap: 6px;
    font-size: 0.98rem;
}
.el-res-grid.is-loading { opacity: 0.45; pointer-events: none; }

/* Scroll-cascade in/out — every cell carries a --row-i CSS var (set
   by facilities.js stampRowIndices). Cells start faded + slid down,
   reveal staggered by row when an IntersectionObserver toggles
   .is-populated on the grid. Leaving the viewport reverses, so
   re-entering replays the cascade. */
.el-res-grid > * {
    opacity: 0;
    transform: translateY(8px);
    transition:
        opacity 0.5s var(--el-ease-soft, cubic-bezier(0.22, 1, 0.36, 1)),
        transform 0.5s var(--el-ease-soft, cubic-bezier(0.22, 1, 0.36, 1)),
        background 0.18s ease,
        border-color 0.18s ease,
        box-shadow 0.18s ease,
        color 0.18s ease;
    transition-delay:
        calc(var(--row-i, 0) * 30ms),
        calc(var(--row-i, 0) * 30ms),
        0s, 0s, 0s, 0s;
}
.el-res-grid.is-populated > * {
    opacity: 1;
    transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
    .el-res-grid > * {
        opacity: 1;
        transform: none;
        transition: background 0.18s ease, border-color 0.18s ease;
    }
}

/* Header row: empty corner + 1 cell per court */
.el-res-header-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 14px 8px;
    font-size: 0.88rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    border-bottom: 1px solid var(--el-border);
}
.el-res-header-cell--court {
    background: rgba(2, 12, 146, 0.05);
    border-radius: 8px 8px 0 0;
    color: var(--el-hero);
    font-weight: 900;
}
html.night-mode .el-res-header-cell--court {
    background: rgba(255, 255, 255, 0.04);
    color: var(--el-text);
}
/* On narrow screens, drop the "Court " prefix so the header reads
   just "A ⚡" instead of "COURT A ⚡" — gave the icon room to breathe
   and stopped the header text from wrapping next to the lightning
   bolt. The prefix is preserved on desktop. */
@media (max-width: 600px) {
    .el-res-header-cell-prefix { display: none; }
}

/* Time label column */
.el-res-time {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 0 12px;
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--el-text-muted);
    font-variant-numeric: tabular-nums;
    /* light tick between half-hour labels */
    border-right: 1px dashed var(--el-border);
}
.el-res-time.is-hour {
    color: var(--el-text);
    font-weight: 800;
}

/* A slot cell */
.el-res-slot {
    position: relative;
    border-radius: 8px;
    padding: 8px 10px;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 0.12s var(--el-ease-soft), box-shadow 0.15s, background 0.15s;
    user-select: none;
    border: 1px solid transparent;
}
/* Open: subtle green wash with accent text */
.el-res-slot--open {
    background: rgba(188, 255, 0, 0.16);
    color: #2b6a00;
    border-color: rgba(188, 255, 0, 0.35);
}
.el-res-slot--open:hover {
    background: rgba(188, 255, 0, 0.28);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(2, 12, 146, 0.1);
}
html.night-mode .el-res-slot--open {
    color: #bcff00;
    background: rgba(188, 255, 0, 0.08);
    border-color: rgba(188, 255, 0, 0.25);
}

/* Booked: greyed out diagonal-hatched bg */
.el-res-slot--busy {
    background: repeating-linear-gradient(
        -45deg,
        rgba(2, 12, 146, 0.12) 0 5px,
        rgba(2, 12, 146, 0.06) 5px 10px
    );
    color: var(--el-text-muted);
    cursor: not-allowed;
}
html.night-mode .el-res-slot--busy {
    background: repeating-linear-gradient(
        -45deg,
        rgba(255, 255, 255, 0.08) 0 5px,
        rgba(255, 255, 255, 0.03) 5px 10px
    );
    color: rgba(255, 255, 255, 0.4);
}
.el-res-slot--busy:hover { transform: none; }

/* Selected: 50%-transparent tennis-ball green — softer than a solid fill
   so the grid doesn't scream when several slots are chosen. */
.el-res-slot--selected {
    background: rgba(188, 255, 0, 0.5);
    color: var(--el-green-text);
    border-color: rgba(188, 255, 0, 0.85);
    box-shadow: 0 4px 14px rgba(188, 255, 0, 0.22);
    font-weight: 800;
}
html.night-mode .el-res-slot--selected {
    background: rgba(188, 255, 0, 0.38);
    color: #0b1420;
    border-color: rgba(188, 255, 0, 0.7);
}
.el-res-slot--selected:hover {
    background: rgba(188, 255, 0, 0.62);
    filter: brightness(1.06);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(188, 255, 0, 0.32);
}

.el-res-slot-label { pointer-events: none; }

/* Past slots (today, already-elapsed time) — faded, inert, striped bg */
.el-res-slot--past {
    background: rgba(2, 12, 146, 0.04);
    color: rgba(2, 12, 146, 0.3);
    border: 1px dashed rgba(2, 12, 146, 0.15);
    cursor: default;
    opacity: 0.55;
}
html.night-mode .el-res-slot--past {
    background: rgba(255, 255, 255, 0.02);
    color: rgba(255, 255, 255, 0.25);
    border-color: rgba(255, 255, 255, 0.1);
}
.el-res-time.is-past {
    color: var(--el-text-muted);
    opacity: 0.55;
}

/* Collapsed "past today" banner (one row spanning all cols).
   Left padding places the clock icon in the time-column gutter so it
   lines up vertically with the time labels below (06:00 / 20:00 etc.)
   AND with the maintenance banner's alert icon above. */
.el-res-past-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    background: rgba(2, 12, 146, 0.05);
    border: 1px dashed rgba(2, 12, 146, 0.2);
    border-radius: 10px;
    color: var(--el-text-muted);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s;
    width: 100%;
}
.el-res-past-toggle:hover {
    background: rgba(2, 12, 146, 0.1);
    border-color: rgba(2, 12, 146, 0.35);
    color: var(--el-text);
}
html.night-mode .el-res-past-toggle {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.12);
}
html.night-mode .el-res-past-toggle:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.3);
}
.el-res-past-toggle .mdi:first-child { font-size: 1.05rem; color: var(--el-hero); }
html.night-mode .el-res-past-toggle .mdi:first-child { color: var(--el-accent); }
.el-res-past-count {
    margin-left: auto;
    font-size: 0.72rem;
    padding: 2px 10px;
    border-radius: 999px;
    background: rgba(2, 12, 146, 0.1);
    color: var(--el-text);
}
html.night-mode .el-res-past-count {
    background: rgba(255, 255, 255, 0.08);
    color: var(--el-text);
}
.el-res-past-caret { transition: transform 0.2s; }
.el-res-past-toggle.is-open .el-res-past-caret { transform: rotate(180deg); }

/* Legend row */
.el-res-legend {
    display: flex;
    gap: 22px;
    flex-wrap: wrap;
    justify-content: center;
    margin: 18px 0 0;
    font-size: 0.8rem;
    color: var(--el-text-muted);
}
.el-res-legend-item { display: inline-flex; align-items: center; gap: 8px; }
.el-res-sw { width: 16px; height: 16px; border-radius: 4px; display: inline-block; }
.el-res-sw--open { background: rgba(188, 255, 0, 0.28); border: 1px solid rgba(188, 255, 0, 0.5); }
.el-res-sw--busy { background: repeating-linear-gradient(-45deg, rgba(2, 12, 146, 0.25) 0 4px, rgba(2, 12, 146, 0.12) 4px 8px); }
.el-res-sw--selected { background: var(--el-green); border: 1px solid rgba(2, 12, 146, 0.2); }
.el-res-sw--daylight { background: rgba(251, 146, 60, 0.25); border: 1px solid rgba(251, 146, 60, 0.5); }
.el-res-sw--disabled { background: rgba(239, 68, 68, 0.2); border: 1px solid rgba(239, 68, 68, 0.55); }

/* Daylight-only slot (evening on a non-floodlit court) — orange warning,
   but STILL BOOKABLE (players often book dark courts anyway — neighbouring
   lights help, or it's a social match). Hover deepens the tint. */
.el-res-slot--daylight {
    background: rgba(251, 146, 60, 0.1);
    color: rgba(154, 52, 18, 0.85);
    border: 1px dashed rgba(251, 146, 60, 0.45);
    cursor: pointer;
}
.el-res-slot--daylight:hover {
    background: rgba(251, 146, 60, 0.22);
    border-color: rgba(251, 146, 60, 0.7);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(251, 146, 60, 0.25);
}
html.night-mode .el-res-slot--daylight {
    background: rgba(251, 146, 60, 0.08);
    color: rgba(251, 146, 60, 0.85);
    border-color: rgba(251, 146, 60, 0.35);
}
html.night-mode .el-res-slot--daylight:hover {
    background: rgba(251, 146, 60, 0.18);
    border-color: rgba(251, 146, 60, 0.55);
}

/* Maintenance slot — red warning, also still bookable (same reasoning
   as daylight slots). Hover deepens the tint. */
.el-res-slot--disabled {
    background: rgba(239, 68, 68, 0.08);
    color: rgba(153, 27, 27, 0.85);
    border: 1px dashed rgba(239, 68, 68, 0.5);
    cursor: pointer;
}
.el-res-slot--disabled:hover {
    background: rgba(239, 68, 68, 0.18);
    border-color: rgba(239, 68, 68, 0.7);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(239, 68, 68, 0.25);
}
html.night-mode .el-res-slot--disabled {
    background: rgba(239, 68, 68, 0.08);
    color: rgba(239, 68, 68, 0.85);
    border-color: rgba(239, 68, 68, 0.35);
}
html.night-mode .el-res-slot--disabled:hover {
    background: rgba(239, 68, 68, 0.18);
    border-color: rgba(239, 68, 68, 0.55);
}

/* When a daylight/disabled slot gets selected, keep the green selected
   fill BUT add a small warning ring so the user remembers their slot
   needs lights. */
.el-res-slot--warn-daylight {
    box-shadow:
        0 0 0 1.5px rgba(251, 146, 60, 0.7),
        0 4px 14px rgba(188, 255, 0, 0.35) !important;
}
.el-res-slot--warn-disabled {
    box-shadow:
        0 0 0 1.5px rgba(239, 68, 68, 0.7),
        0 4px 14px rgba(188, 255, 0, 0.35) !important;
}

/* Header cell variants matching court status */
.el-res-header-cell--daylight .mdi { color: #fb923c; }
.el-res-header-cell--disabled .mdi { color: #ef4444; }
.el-res-header-cell--disabled {
    background: rgba(239, 68, 68, 0.08) !important;
    color: #991b1b !important;
}
html.night-mode .el-res-header-cell--disabled {
    color: #fca5a5 !important;
    background: rgba(239, 68, 68, 0.15) !important;
}

/* Maintenance banner — red-tinted alert strip above the grid.
   Left padding matches the 'Earlier today' banner so both alert icons
   + the time-column labels all line up on the same vertical axis. */
.el-res-maintenance {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 18px;
    margin: 0 0 10px;
    background: rgba(239, 68, 68, 0.08);
    border: 1px solid rgba(239, 68, 68, 0.35);
    border-radius: 10px;
    color: #991b1b;
}
html.night-mode .el-res-maintenance {
    background: rgba(239, 68, 68, 0.12);
    border-color: rgba(239, 68, 68, 0.4);
    color: #fca5a5;
}
.el-res-maintenance > .mdi {
    font-size: 1.3rem;
    color: #ef4444;
    flex-shrink: 0;
    margin-top: 2px;
}
.el-res-maintenance-title {
    font-weight: 800;
    font-size: 0.92rem;
    margin-bottom: 2px;
}
.el-res-maintenance-sub {
    font-size: 0.86rem;
    line-height: 1.45;
    color: inherit;
    opacity: 0.9;
}

.el-res-loading,
.el-res-error {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 60px 24px;
    font-size: 0.92rem;
    color: var(--el-text-muted);
}
.el-res-loading .mdi { font-size: 1.4rem; color: var(--el-green); animation: el-spin 1.2s linear infinite; }
@keyframes el-spin { to { transform: rotate(360deg); } }
.el-res-error .mdi { color: #e33e41; }

/* Sticky action bar (appears when slots selected) */
.el-res-action-bar {
    position: sticky;
    bottom: 16px;
    margin-top: 22px;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(14px);
    border: 1px solid var(--el-border);
    border-radius: 999px;
    padding: 10px 12px 10px 22px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    box-shadow: 0 12px 40px rgba(2, 12, 146, 0.18);
    z-index: 20;
    animation: el-res-bar-in 0.3s var(--el-ease-soft);
}
/* `hidden` attribute normally resolves to display:none, but the .el-res-action-bar
   class's `display: flex` overrides it at class-level specificity. Force hide
   explicitly. */
.el-res-action-bar[hidden] { display: none !important; }
html.night-mode .el-res-action-bar {
    background: rgba(15, 30, 45, 0.92);
    border-color: rgba(255, 255, 255, 0.1);
}
@keyframes el-res-bar-in {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: translateY(0); }
}
.el-res-action-info {
    display: flex; align-items: center; gap: 10px;
    font-weight: 700;
    color: var(--el-hero);
}
html.night-mode .el-res-action-info { color: var(--el-text); }
.el-res-action-info .mdi { color: var(--el-green); font-size: 1.2rem; }
.el-res-action-btns { display: flex; gap: 8px; }
.el-res-action-btns .el-btn { padding: 12px 20px; font-size: 0.8rem; }
/* Scoped green override for the action-bar CTA — keeps it visually tied to the
   green Selected cells above. Other .el-btn--cta usages stay navy. */
.el-res-action-bar .el-btn--cta {
    background: var(--el-green);
    color: var(--el-green-text);
    box-shadow: 0 8px 22px rgba(188, 255, 0, 0.3);
}
.el-res-action-bar .el-btn--cta:hover {
    filter: brightness(1.06);
    box-shadow: 0 12px 30px rgba(188, 255, 0, 0.45);
}

/* ── Accordion ─────────────────────────────────────────────────────── */
.el-accordion {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 28px;
}
.el-accordion-item {
    border: none;
    border-radius: var(--el-radius);
    background: var(--el-surface);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.25s var(--el-ease-soft);
}
.el-accordion-item:hover,
.el-accordion-item[open] {
    box-shadow: var(--el-glow-hover);
}
.el-accordion-item summary {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 18px 22px;
    font-weight: 700;
    font-size: 1rem;
    cursor: pointer;
    list-style: none;
}
.el-accordion-item summary::-webkit-details-marker { display: none; }
.el-accordion-item summary > .mdi:first-child {
    font-size: 1.3rem;
    color: var(--el-hero);
    flex-shrink: 0;
}
html.night-mode .el-accordion-item summary > .mdi:first-child { color: var(--el-accent); }
.el-accordion-item summary > span {
    flex: 1;
    color: var(--el-text);
}
.el-accordion-caret {
    font-size: 1.3rem;
    transition: transform 0.25s var(--el-ease-soft);
    color: var(--el-text-muted);
}
.el-accordion-item[open] .el-accordion-caret {
    transform: rotate(180deg);
    color: var(--el-hero);
}
html.night-mode .el-accordion-item[open] .el-accordion-caret { color: var(--el-accent); }
.el-accordion-body {
    padding: 0 22px 22px;
    color: var(--el-text);
    line-height: 1.65;
    font-size: 0.94rem;
}
.el-accordion-body p { margin: 0 0 12px; }
.el-accordion-body p:last-child { margin-bottom: 0; }
.el-accordion-body ul {
    margin: 0;
    padding-left: 22px;
}
.el-accordion-body li { margin-bottom: 6px; }

/* Fixed body height so the left column doesn't shuffle around as the
   user clicks through panels — each body gets the same min-height and
   overflow just scrolls if a section happens to be longer. Using
   <details name="fineprint"> already restricts to one-open-at-a-time
   natively (Chrome 120+, Firefox 133+, Safari 17.2+). */
.el-accordion-body {
    min-height: 160px;
}

/* Sunrise / sunset inline block inside the Floodlight Hours body */
.el-suntimes {
    display: flex;
    gap: 20px;
    margin-top: 16px;
    padding: 14px 16px;
    background: rgba(2, 12, 146, 0.06);
    border: 1px solid rgba(2, 12, 146, 0.15);
    border-radius: 10px;
    flex-wrap: wrap;
}
html.night-mode .el-suntimes {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.1);
}
.el-suntimes-item {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1 1 auto;
    min-width: 130px;
}
.el-suntimes-item > .mdi {
    font-size: 1.8rem;
    color: #fb923c;
    flex-shrink: 0;
}
.el-suntimes-item:nth-child(2) > .mdi { color: #7e22ce; }
.el-suntimes-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    line-height: 1;
    margin-bottom: 4px;
}
.el-suntimes-time {
    font-variant-numeric: tabular-nums;
    font-weight: 800;
    font-size: 1.15rem;
    color: var(--el-text);
    line-height: 1;
}

/* Compact sunrise / sunset pill — inline, single row, used above the
   court cards grid on home + facilities. Same tokens as .el-suntimes
   so the two layouts feel related. */
.el-sun-pill {
    display: inline-flex;
    align-items: center;
    gap: 18px;
    padding: 10px 20px;
    background: rgba(2, 12, 146, 0.06);
    border: 1px solid rgba(2, 12, 146, 0.18);
    border-radius: 999px;
    margin: 10px 0 28px;
    font-variant-numeric: tabular-nums;
}
html.night-mode .el-sun-pill {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.12);
}
.el-sun-pill-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.el-sun-pill-item > .mdi { font-size: 1.25rem; color: #fb923c; }
.el-sun-pill-item:nth-of-type(2) > .mdi { color: #7e22ce; }
.el-sun-pill-label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    margin-right: 2px;
}
.el-sun-pill-time {
    font-size: 0.92rem;
    font-weight: 800;
    color: var(--el-text);
}
.el-sun-pill-sep {
    color: var(--el-text-muted);
    opacity: 0.5;
}

/* ── Fine-print 2-column: accordion (left) + floodlit photo (right) ── */
.el-fineprint-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(32px, 5vw, 64px);
    align-items: stretch;
    margin-top: clamp(24px, 4vw, 48px);
}
.el-fineprint-cta {
    margin-top: 18px;
}
.el-fineprint-cta .el-btn {
    padding: 12px 20px;
    font-size: 0.78rem;
}
/* Same 4-layer idle glow + 5-layer hover bloom as the About clubhouse
   image so the visual language stays consistent across the site. */
.el-fineprint-photo {
    position: relative;
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    margin: 0;
    min-height: 440px;
    background: var(--el-surface-alt);
    box-shadow:
        0 0 0 1.5px rgba(2, 12, 146, 0.45),
        0 0 16px rgba(2, 12, 146, 0.35),
        0 0 36px rgba(2, 12, 146, 0.25),
        0 0 72px rgba(2, 12, 146, 0.15);
    transition: transform 0.35s var(--el-ease-soft), box-shadow 0.35s var(--el-ease-soft);
}
.el-fineprint-photo:hover {
    transform: translateY(-3px);
    box-shadow:
        0 0 0 2px rgba(2, 12, 146, 0.95),
        0 0 0 6px rgba(2, 12, 146, 0.45),
        0 0 24px rgba(2, 12, 146, 0.75),
        0 0 60px rgba(2, 12, 146, 0.5),
        0 0 120px rgba(2, 12, 146, 0.3);
}
.el-fineprint-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    position: absolute;
    inset: 0;
}
.el-fineprint-caption {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    padding: 22px 26px 26px;
    color: #ffffff;
    background: linear-gradient(180deg,
        transparent 0%,
        rgba(0, 6, 89, 0.0) 30%,
        rgba(0, 6, 89, 0.7) 75%,
        rgba(0, 6, 89, 0.92) 100%);
    pointer-events: none;
}
.el-fineprint-caption-top {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 800;
    font-size: 1rem;
    margin-bottom: 6px;
}
.el-fineprint-caption-top .mdi {
    color: var(--el-green);
    font-size: 1.1rem;
}
.el-fineprint-caption-sub {
    font-size: 0.88rem;
    opacity: 0.88;
    line-height: 1.45;
}

@media (max-width: 900px) {
    .el-fineprint-grid { grid-template-columns: 1fr; gap: 28px; }
    .el-fineprint-photo { min-height: 320px; aspect-ratio: 4 / 3; }
}

/* ── CTA card block ────────────────────────────────────────────────── */
.el-cta-block { padding-bottom: 80px; }
.el-cta-card {
    background:
        radial-gradient(ellipse at 90% 10%, rgba(188, 255, 0, 0.12) 0%, transparent 55%),
        linear-gradient(135deg, #020c92 0%, #000659 100%);
    color: var(--el-text-inv);
    padding: 56px 48px;
    border-radius: var(--el-radius-lg);
    text-align: center;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft), transform 0.35s var(--el-ease-soft);
    position: relative;
    overflow: hidden;
}
.el-cta-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--el-glow-hover);
}
.el-cta-card::before {
    /* Tennis-ball accent glow in upper-right */
    content: '';
    position: absolute;
    top: -80px; right: -80px;
    width: 260px; height: 260px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(188, 255, 0, 0.12) 0%, transparent 70%);
    pointer-events: none;
}
.el-cta-card-eyebrow {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--el-accent);
    text-shadow: 0 0 12px rgba(125, 211, 252, 0.45);
    margin-bottom: 12px;
}
.el-cta-card-title {
    font-family: 'Inter', sans-serif;
    font-weight: 900;
    font-size: clamp(1.6rem, 3.2vw, 2.4rem);
    line-height: 1.1;
    margin: 0 0 14px;
    letter-spacing: -0.02em;
}
.el-cta-card-sub {
    font-size: 1rem;
    color: var(--el-text-inv-muted);
    max-width: 560px;
    margin: 0 auto 28px;
}
.el-cta-card-actions {
    display: flex; gap: 14px;
    justify-content: center;
    flex-wrap: wrap;
}
.el-cta-card .el-btn--cta {
    background: var(--el-green);
    color: var(--el-green-text);
    box-shadow: 0 8px 24px rgba(188, 255, 0, 0.25);
}
.el-cta-card .el-btn--cta:hover {
    filter: brightness(1.05);
    box-shadow: 0 12px 32px rgba(188, 255, 0, 0.4);
}
.el-cta-card .el-btn--outline {
    color: var(--el-text-inv);
    border-color: rgba(255, 255, 255, 0.32);
}
.el-cta-card .el-btn--outline:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.5);
}

/* Smaller-screen tweaks */
@media (max-width: 720px) {
    .el-res-grid { font-size: 0.76rem; }
    .el-res-slot { padding: 4px 4px; font-size: 0.62rem; }
    .el-res-slot-label { display: none; }  /* cells too small for text — colour+hatch carry the meaning */
    .el-res-time { padding: 0 6px; font-size: 0.66rem; }
    /* Narrow viewport — shrink the fixed anchor button proportionally
       but still pin both TODAY / THIS MONTH variants to the same size. */
    .el-res-today {
        padding: 10px 8px 8px;
        flex: 0 0 76px;
        width: 76px;
        min-width: 76px;
        max-width: 76px;
    }
    .el-res-today-line { font-size: 0.66rem; }
    .el-res-nav { width: 34px; height: 34px; }
    .el-cta-card { padding: 40px 24px; }
    .el-res-action-bar {
        flex-direction: column;
        border-radius: 20px;
        padding: 14px;
    }
    .el-res-action-btns { width: 100%; }
    .el-res-action-btns .el-btn { flex: 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   EVENTS & TOURNAMENTS PAGE
   ═══════════════════════════════════════════════════════════════════ */

/* Hero features row (Weekly Socials · Annual Tournaments · Junior Programs) */
.el-hero-features {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    margin-top: 22px;
    color: var(--el-text-inv-muted);
    font-size: 0.88rem;
}
.el-hero-features > span {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.el-hero-features .mdi {
    color: var(--el-accent);
    font-size: 1.1rem;
}

/* Category pill + background — shared by weekly cards + list rows + calendar dots */
.el-ev-cat-pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    align-self: flex-start;
    border: 1px solid currentColor;
    background: transparent;
}
.el-ev-cat-pill--competition { color: #dc2626; }
.el-ev-cat-pill--social      { color: #0891b2; }
.el-ev-cat-pill--junior      { color: #ea580c; }
.el-ev-cat-pill--coaching    { color: #16a34a; }
.el-ev-cat-pill--other       { color: var(--el-text-muted); }
/* Category colour SOURCE OF TRUTH — these MUST match
   .el-preview-timeline-dot--* / .el-preview-type-dot--* below so the
   calendar blocks, day-grid blocks AND the legend dots all agree.
   Black text on the lighter junior shade only. */
.el-ev-cat-bg--competition { background: #dc2626; color: #fff; }
.el-ev-cat-bg--social      { background: #16a34a; color: #fff; }
.el-ev-cat-bg--junior      { background: #f59e0b; color: #1a1a1a; }
.el-ev-cat-bg--coaching    { background: #3b82f6; color: #fff; }
.el-ev-cat-bg--other       { background: var(--el-hero); color: #fff; }

.el-events-loading {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    padding: 60px 24px;
    color: var(--el-text-muted);
}
.el-events-loading .mdi { animation: el-spin 1.2s linear infinite; }
.el-ev-empty {
    text-align: center;
    padding: 48px 24px;
    color: var(--el-text-muted);
    font-size: 0.95rem;
}
.el-ev-empty .mdi { display: block; font-size: 2rem; margin-bottom: 10px; color: var(--el-hero); }

/* Weekly Schedule grid */
.el-weekly-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 22px;
    margin-top: 32px;
}
.el-weekly-card {
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border-radius: var(--el-radius);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s var(--el-ease-soft);
}
html.night-mode .el-weekly-card { background: rgba(255, 255, 255, 0.04); }
.el-weekly-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--el-glow-hover);
}
.el-weekly-day {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    background: #dc2626;
    color: #fff;
    font-weight: 800;
    letter-spacing: 0.1em;
}
.el-weekly-card.el-ev-card--social      .el-weekly-day { background: #0891b2; }
.el-weekly-card.el-ev-card--junior      .el-weekly-day { background: #ea580c; }
.el-weekly-card.el-ev-card--coaching    .el-weekly-day { background: #16a34a; }
.el-weekly-card.el-ev-card--competition .el-weekly-day { background: #dc2626; }
.el-weekly-card.el-ev-card--other       .el-weekly-day { background: var(--el-hero); }
.el-weekly-day-label { font-size: 1.05rem; }
.el-weekly-day-tag {
    font-size: 0.68rem;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.22);
    letter-spacing: 0.08em;
}
.el-weekly-photo {
    aspect-ratio: 16 / 9;
    background: var(--el-surface-alt);
    overflow: hidden;
}
.el-weekly-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.el-weekly-body {
    padding: 18px 20px 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.el-weekly-title {
    font-size: 1.2rem;
    font-weight: 800;
    margin: 4px 0 0;
    color: var(--el-text);
    line-height: 1.25;
}
.el-weekly-sub {
    font-size: 0.88rem;
    color: var(--el-text-muted);
    line-height: 1.45;
    margin: 0;
}
.el-weekly-meta {
    list-style: none;
    padding: 0;
    margin: 10px 0 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 0.85rem;
    color: var(--el-text-muted);
}
.el-weekly-meta .mdi { color: var(--el-text); opacity: 0.7; margin-right: 6px; }
.el-weekly-meta-note {
    font-weight: 600;
    color: var(--el-hero);
    margin-top: 2px;
}
html.night-mode .el-weekly-meta-note { color: var(--el-accent); }

/* Filter pills */
.el-ev-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 20px 0 28px;
}
.el-ev-filter {
    padding: 8px 16px;
    border-radius: 999px;
    border: 1px solid var(--el-border);
    background: transparent;
    color: var(--el-text);
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.el-ev-filter:hover { border-color: var(--el-hero); }
.el-ev-filter.is-active {
    background: #dc2626;
    color: #fff;
    border-color: #dc2626;
}

/* Calendar — shared sky-blue glow + matching margin to the timeline
   above so the two cards read as a single tight stack. */
.el-ev-cal {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    padding: 20px 22px;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft);
    margin-bottom: 28px;
}
.el-ev-cal:hover { box-shadow: var(--el-glow-hover); }
html.night-mode .el-ev-cal { background: #12141b; }
.el-ev-cal-head {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 18px;
}
.el-ev-cal-title {
    flex: 1;
    font-size: 1rem;
    font-weight: 800;
    color: var(--el-text);
}
/* Category legend — tells the user what each colour chip on a calendar
   cell means. Always visible so the legend is there even when the
   chip labels are cropped down to colour bars on narrow screens. */
.el-ev-cal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 4px 0 14px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.el-ev-cal-lg {
    position: relative;
    padding: 4px 10px 4px 22px;
    border-radius: 999px;
    background: transparent !important;   /* override .el-ev-cat-bg--* BG for the legend pill */
    color: var(--el-text) !important;
    border: 1px solid var(--el-border);
    display: inline-flex;
    align-items: center;
}
.el-ev-cal-lg-sw {
    position: absolute;
    left: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 10px; height: 10px;
    border-radius: 3px;
}
.el-ev-cal-lg.el-ev-cat-bg--competition .el-ev-cal-lg-sw { background: #dc2626; }
.el-ev-cal-lg.el-ev-cat-bg--social      .el-ev-cal-lg-sw { background: #16a34a; }
.el-ev-cal-lg.el-ev-cat-bg--junior      .el-ev-cal-lg-sw { background: #f59e0b; }
.el-ev-cal-lg.el-ev-cat-bg--coaching    .el-ev-cal-lg-sw { background: #3b82f6; }
.el-ev-cal-lg.el-ev-cat-bg--other       .el-ev-cal-lg-sw { background: var(--el-hero); }

/* Heat-map legend — sits on the same row as the category pills,
   separated by a subtle divider. Three swatches (Quiet / Medium /
   Packed) so a new visitor can decode the per-day badge. */
.el-ev-cal-heat-legend {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    padding-left: 12px;
    margin-left: auto;
    border-left: 1px solid var(--el-border);
}
.el-ev-cal-heat-legend > .mdi { color: var(--el-hero); font-size: 0.92rem; }
html.night-mode .el-ev-cal-heat-legend > .mdi { color: var(--el-accent); }
.el-ev-cal-heat-legend .el-ev-cal-heat {
    /* Overrides in legend context — show just a coloured chip, no count */
    padding: 1px 8px;
    font-size: 0.6rem;
    letter-spacing: 0.04em;
}
@media (max-width: 600px) {
    .el-ev-cal-heat-legend { margin-left: 0; border-left: 0; padding-left: 0; flex-basis: 100%; }
}

.el-ev-cal-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
    margin-bottom: 8px;
}
.el-ev-cal-weekdays span {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    text-align: center;
    padding: 6px 0;
}
.el-ev-cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
}
.el-ev-cal-cell {
    min-height: 84px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding: 10px 8px 8px;
    font-size: 1rem;
    font-weight: 800;
    color: var(--el-text);
    background: rgba(2, 12, 146, 0.05);
    border: 1px solid transparent;
    border-radius: 10px;
    transition: background 0.15s, border-color 0.15s;
}
html.night-mode .el-ev-cal-cell {
    background: rgba(255, 255, 255, 0.04);
    color: var(--el-text);
}
.el-ev-cal-cell--blank { visibility: hidden; background: transparent; }
.el-ev-cal-cell.is-past {
    /* filter, not opacity — keeps the populate wave 0 → 1 transition
       on this cell intact (opacity collisions on equal specificity
       were preventing the stagger from being visible). */
    filter: saturate(0.55) brightness(0.92);
    background: transparent;
}
.el-ev-cal-cell.is-today {
    background: var(--el-hero);
    color: var(--el-text-inv);
    border-color: var(--el-hero);
    box-shadow: 0 8px 24px rgba(2, 12, 146, 0.22);
}
.el-ev-cal-cell.has-event:not(.is-today) {
    background: rgba(2, 12, 146, 0.1);
    border-color: rgba(2, 12, 146, 0.2);
}
html.night-mode .el-ev-cal-cell.has-event:not(.is-today) {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.14);
}
/* Top row of a calendar cell — day number on the left, heat badge on
   the right. A grid rather than a flex so the num stays perfectly
   aligned across cells regardless of whether the heat badge is
   present. */
.el-ev-cal-cell-top {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 4px;
}
.el-ev-cal-num {
    display: block;
    font-size: 0.92rem;
    line-height: 1;
    text-align: left;
    font-variant-numeric: tabular-nums;
}
/* Booking-density heat badge — small count pill at the top-right.
   Colour intensifies with heat level; text stays readable. */
.el-ev-cal-heat {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 1px 6px 1px 4px;
    border-radius: 999px;
    font-size: 0.62rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    line-height: 1.3;
    color: #15803d;
    background: rgba(22, 163, 74, 0.12);
    border: 1px solid rgba(22, 163, 74, 0.3);
}
.el-ev-cal-heat .mdi { font-size: 0.72rem; opacity: 0.85; }
.el-ev-cal-heat--1 { color: #15803d; background: rgba(22, 163, 74, 0.1);  border-color: rgba(22, 163, 74, 0.3); }
.el-ev-cal-heat--2 { color: #a16207; background: rgba(234, 179, 8, 0.15); border-color: rgba(234, 179, 8, 0.4); }
.el-ev-cal-heat--3 { color: #c2410c; background: rgba(249, 115, 22, 0.15); border-color: rgba(249, 115, 22, 0.45); }
.el-ev-cal-heat--4 { color: #b91c1c; background: rgba(239, 68, 68, 0.18);  border-color: rgba(239, 68, 68, 0.55); }
.el-ev-cal-heat--5 { color: #ffffff; background: #dc2626;                   border-color: #991b1b; }
html.night-mode .el-ev-cal-heat--1 { color: #86efac; }
html.night-mode .el-ev-cal-heat--2 { color: #fde047; }
html.night-mode .el-ev-cal-heat--3 { color: #fdba74; }
html.night-mode .el-ev-cal-heat--4 { color: #fca5a5; }
html.night-mode .el-ev-cal-heat--5 { color: #ffffff; }

/* Cell BACKGROUND tint — adds subtle depth for busier days on top of
   the base has-event styling. No tint for level 0; progressively
   more saturated toward level 5. Keeps the brand-navy border
   priority for event-bearing cells. */
.el-ev-cal-cell.el-ev-cal-cell--heat-2:not(.is-today) { background: rgba(249, 115, 22, 0.05); }
.el-ev-cal-cell.el-ev-cal-cell--heat-3:not(.is-today) { background: rgba(249, 115, 22, 0.1); }
.el-ev-cal-cell.el-ev-cal-cell--heat-4:not(.is-today) { background: rgba(239, 68, 68, 0.1); }
.el-ev-cal-cell.el-ev-cal-cell--heat-5:not(.is-today) { background: rgba(239, 68, 68, 0.18); border-color: rgba(239, 68, 68, 0.35); }
html.night-mode .el-ev-cal-cell.el-ev-cal-cell--heat-2:not(.is-today) { background: rgba(249, 115, 22, 0.07); }
html.night-mode .el-ev-cal-cell.el-ev-cal-cell--heat-3:not(.is-today) { background: rgba(249, 115, 22, 0.12); }
html.night-mode .el-ev-cal-cell.el-ev-cal-cell--heat-4:not(.is-today) { background: rgba(239, 68, 68, 0.14); }
html.night-mode .el-ev-cal-cell.el-ev-cal-cell--heat-5:not(.is-today) { background: rgba(239, 68, 68, 0.22); }
.el-ev-cal-chips {
    display: flex;
    flex-direction: column;
    gap: 3px;
    align-items: stretch;
    margin-top: auto;
}
.el-ev-cal-chip {
    padding: 3px 6px;
    border-radius: 4px;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-align: center;
    color: #ffffff;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.el-ev-cal-chip--more {
    background: rgba(2, 12, 146, 0.18);
    color: var(--el-text);
}
html.night-mode .el-ev-cal-chip--more {
    background: rgba(255, 255, 255, 0.12);
    color: var(--el-text);
}

/* Placeholder chip — 2026-07-30. Applied when a day's category is
   represented ONLY by placeholder events (authoritative recurrence
   expansion or heuristic pattern) with no real community_post backing
   it yet. Reads as "we KNOW this Junior programme runs on last
   Fridays, but the operator hasn't published a specific event yet"
   rather than a solid confirmed day. Chip retains its category
   background so members still recognise the type at a glance, but
   the appearance is muted + dashed to signal "projected, not
   published". Once the operator publishes an event for the date,
   the real event wins the dedup and the chip flips back to solid. */
.el-ev-cal-chip--placeholder {
    opacity: 0.62;
    background: transparent;
    border: 1.5px dashed currentColor;
    /* currentColor picks up the .el-ev-cat-bg--<cat> tone below via
       a nested rule, so the border reads as a lighter dashed version
       of the same accent — no per-category CSS needed. */
    color: var(--el-text);
    font-weight: 700;
}
html.night-mode .el-ev-cal-chip--placeholder {
    color: var(--el-text-inv-muted);
    opacity: 0.68;
}
/* Per-category chip colours — normally solid backgrounds (see
   .el-ev-cat-bg--* at ~L5253). For placeholder chips we lift those
   same hex values to be the DASHED BORDER + TEXT colour instead,
   so the border reads as a lighter dashed version of the same
   accent. Keep in lockstep with the .el-ev-cat-bg--* rules. */
.el-ev-cal-chip.el-ev-cal-chip--placeholder.el-ev-cat-bg--competition { border-color: #dc2626; color: #dc2626; }
.el-ev-cal-chip.el-ev-cal-chip--placeholder.el-ev-cat-bg--social      { border-color: #16a34a; color: #16a34a; }
.el-ev-cal-chip.el-ev-cal-chip--placeholder.el-ev-cat-bg--junior      { border-color: #f59e0b; color: #f59e0b; }
.el-ev-cal-chip.el-ev-cal-chip--placeholder.el-ev-cat-bg--coaching    { border-color: #3b82f6; color: #3b82f6; }
.el-ev-cal-chip.el-ev-cal-chip--placeholder.el-ev-cat-bg--other       { border-color: var(--el-hero); color: var(--el-hero); }

/* Rained Out chip — painted on past Wed/Sat cells with zero game
   history. Desaturated grey-blue so it reads as a neutral "no play"
   state rather than an accented category. */
.el-ev-cal-chip--rain {
    background: rgba(100, 116, 139, 0.22);
    color: var(--el-text);
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.el-ev-cal-chip--rain .mdi { font-size: 0.78rem; }
html.night-mode .el-ev-cal-chip--rain {
    background: rgba(255, 255, 255, 0.1);
    color: var(--el-text-inv-muted);
}
/* Dim the whole cell a notch so the Rained Out state reads as
   "nothing happened" without overwhelming the calendar. */
.el-ev-cal-cell.is-rained-out {
    opacity: 0.72;
    background: repeating-linear-gradient(
        -45deg,
        transparent 0,
        transparent 6px,
        rgba(100, 116, 139, 0.06) 6px,
        rgba(100, 116, 139, 0.06) 10px
    );
}
html.night-mode .el-ev-cal-cell.is-rained-out {
    background: repeating-linear-gradient(
        -45deg,
        transparent 0,
        transparent 6px,
        rgba(255, 255, 255, 0.04) 6px,
        rgba(255, 255, 255, 0.04) 10px
    );
}
@media (max-width: 680px) {
    .el-ev-cal-cell { min-height: 70px; padding: 8px 5px 6px; }
    .el-ev-cal-num { font-size: 0.84rem; }
    .el-ev-cal-chip { font-size: 0.56rem; padding: 2px 4px; letter-spacing: 0.02em; }
}

/* ── Event view toggle (Month / Day) ─────────────────────────────
   Inline card-style buttons sitting in the rail next to TODAY /
   THIS MONTH. Inactive = outlined; Active = filled navy (matches
   the existing TODAY card vocabulary). Same dimensions as
   .el-res-today so the row reads as a uniform strip of tiles. */
.el-res-view {
    background: transparent;
    color: var(--club-accent);
    box-shadow: inset 0 0 0 2px rgba(2, 12, 146, 0.18);
    transition: background 0.2s, color 0.2s, box-shadow 0.2s, filter 0.2s, transform 0.2s;
}
html.night-mode .el-res-view {
    color: var(--el-text-inv);
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.18);
}
.el-res-view:hover {
    box-shadow: inset 0 0 0 2px var(--club-accent);
    transform: translateY(-1px);
}
html.night-mode .el-res-view:hover {
    box-shadow: inset 0 0 0 2px var(--el-accent);
}
.el-res-view.is-active {
    background: var(--el-hero);
    color: var(--el-text-inv);
    box-shadow: inset 0 0 0 2px var(--el-hero), 0 6px 18px rgba(2, 12, 146, 0.28);
}
html.night-mode .el-res-view.is-active {
    background: var(--el-accent);
    color: var(--el-green-text);
    box-shadow: inset 0 0 0 2px var(--el-accent), 0 6px 18px rgba(125, 211, 252, 0.32);
}

/* ── Event day view (timeline) ─────────────────────────────────── */
/* Both the Day-view container AND the Month-view wrapper share the
   same column-flex layout so the rail → timeline → grid spacing is
   identical between the two views (otherwise the Month wrap had no
   gap and the Day view had 20px → padding looked off when toggling). */
.el-ev-day,
.el-ev-month-wrap {
    margin-top: 8px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}
/* Explicit override — a class-level `display: flex` on .el-ev-day /
   .el-ev-month-wrap beats the UA [hidden] display:none, so toggling
   between views would otherwise leave BOTH visible at once. Force
   hide when the attribute is set on either container. */
.el-ev-day[hidden],
.el-ev-month-wrap[hidden] { display: none; }
.el-ev-day-grid {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    padding: 18px 14px;
    box-shadow: var(--el-glow-idle);
    position: relative;
    overflow: hidden;
}
html.night-mode .el-ev-day-grid { background: #12141b; }

/* Timeline host when it sits inside the Day view (above the 3-col
   grid) or the Month view (above the calendar). Spacing comes from
   the parent flex `gap: 20px` (.el-ev-day / .el-ev-month-wrap), so
   no own margin — keeps Day and Month views perfectly symmetric. */
.el-ev-day-timeline-host {
    margin: 0;
}
.el-ev-day-timeline-host .el-preview-timeline { padding: 14px 16px 10px; }

/* Month scroller — reuses .el-res-day chips from the Day rail, so
   the only new styling needed is the small "has-events" dot that
   sits inside the chip's bottom slot. */
.el-ev-month-dot {
    display: inline-block;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--el-accent);
    vertical-align: middle;
}
.el-res-day.is-active .el-ev-month-dot { background: #ffffff; }
html.night-mode .el-res-day.is-active .el-ev-month-dot { background: var(--el-green-text); }

/* Column count comes from the inline `--ev-day-cols` set by JS based
   on viewport width (1 → 6). The axis column narrows on small screens
   to give more horizontal space to the event lanes. */
.el-ev-day-grid-inner {
    position: relative;
    display: grid;
    grid-template-columns: 64px repeat(var(--ev-day-cols, 3), minmax(0, 1fr));
    gap: 0;
    align-items: start;
}
@media (max-width: 720px) {
    .el-ev-day-grid-inner {
        grid-template-columns: 48px repeat(var(--ev-day-cols, 2), minmax(0, 1fr));
    }
}
.el-ev-day-axis-wrap {
    display: flex;
    flex-direction: column;
}
.el-ev-day-axis {
    position: relative;
    display: flex;
    flex-direction: column;
}
.el-ev-day-axis-row {
    flex: 1 0 0;
    display: flex;
    align-items: flex-start;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--el-text-muted);
    letter-spacing: 0.02em;
    padding-right: 10px;
    text-align: right;
    justify-content: flex-end;
    border-top: 1px dashed transparent;
}
.el-ev-day-axis-row.is-hour {
    border-top-color: rgba(2, 12, 146, 0.08);
    color: var(--club-accent);
}
html.night-mode .el-ev-day-axis-row { color: var(--el-text-inv-muted); }
html.night-mode .el-ev-day-axis-row.is-hour {
    border-top-color: rgba(255, 255, 255, 0.08);
    color: var(--el-accent);
}

/* Day column — header (dow / date / "Today" pill) + event lane. */
.el-ev-day-col {
    display: flex;
    flex-direction: column;
    border-left: 1px solid rgba(2, 12, 146, 0.08);
    min-width: 0;
}
html.night-mode .el-ev-day-col {
    border-left-color: rgba(255, 255, 255, 0.08);
}
.el-ev-day-col-head {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 1px solid rgba(2, 12, 146, 0.08);
    font-weight: 800;
    color: var(--el-text);
    font-size: 0.82rem;
}
html.night-mode .el-ev-day-col-head {
    border-bottom-color: rgba(255, 255, 255, 0.08);
    color: var(--el-text);
}
.el-ev-day-col-head--spacer {
    /* Placeholder block over the time axis so the axis rows align with
       the column lanes (same vertical offset as the real headers). */
    visibility: hidden;
}
.el-ev-day-col-dow {
    color: var(--club-accent);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-size: 0.72rem;
}
html.night-mode .el-ev-day-col-dow { color: var(--el-accent); }
.el-ev-day-col-num {
    font-size: 0.92rem;
    letter-spacing: 0.02em;
}
.el-ev-day-col-today {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--el-green);
    color: var(--el-green-text);
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
.el-ev-day-col.is-today .el-ev-day-col-head {
    background: rgba(125, 211, 252, 0.08);
}
html.night-mode .el-ev-day-col.is-today .el-ev-day-col-head {
    background: rgba(125, 211, 252, 0.1);
}

.el-ev-day-lane {
    position: relative;
    min-width: 0;
}

/* Event blocks — absolutely positioned at their start_time offset +
   height = duration. Category background comes from shared
   .el-ev-cat-bg--* classes. */
.el-ev-day-block {
    position: absolute;
    left: 6px;
    right: 6px;
    border-radius: 10px;
    padding: 8px 10px;
    color: #ffffff;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow: hidden;
    transition: transform 0.2s var(--el-ease-soft), box-shadow 0.2s;
    cursor: default;
    min-width: 0;
}
.el-ev-day-block:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}
.el-ev-day-block-title {
    font-weight: 800;
    font-size: 0.9rem;
    line-height: 1.2;
    letter-spacing: -0.01em;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
.el-ev-day-block-meta {
    font-size: 0.74rem;
    opacity: 0.88;
    letter-spacing: 0.02em;
}

.el-ev-day-empty {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: var(--el-text-muted);
    font-size: 0.92rem;
    text-align: center;
    padding: 20px;
}
.el-ev-day-empty i { font-size: 1.3rem; margin-right: 6px; vertical-align: -3px; }
html.night-mode .el-ev-day-empty { color: var(--el-text-inv-muted); }

/* Timeline highlight — sky-blue wash under the line where the current
   3-day window sits, so the user sees which slice of the timeline
   their columns represent. */
.el-ev-day-tl-window {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    height: 14px;
    background: rgba(125, 211, 252, 0.35);
    border-radius: 999px;
    pointer-events: none;
    z-index: 0;
    box-shadow: 0 0 12px rgba(125, 211, 252, 0.45);
}
html.night-mode .el-ev-day-tl-window {
    background: rgba(125, 211, 252, 0.28);
}
@media (max-width: 480px) {
    .el-ev-cal-chip { font-size: 0; padding: 3px; }
    .el-ev-cal-chip::before { content: ''; }
    /* On very small screens fall back to coloured bars without text */
}

/* Clickable event cells — subtle cursor hint + hover lift */
.el-ev-cal-cell.is-clickable {
    cursor: pointer;
    border: 1px solid transparent;
}
.el-ev-cal-cell.is-clickable.has-event:hover {
    background: rgba(2, 12, 146, 0.15);
    border-color: rgba(2, 12, 146, 0.4);
    transform: translateY(-1px);
}
html.night-mode .el-ev-cal-cell.is-clickable.has-event:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.22);
}
button.el-ev-cal-cell {
    font-family: inherit;
    text-align: inherit;
}

/* Day popup — anchored floating card with a directional arrow. */
.el-ev-cal {
    position: relative;            /* anchor for the popup's absolute positioning */
}
.el-ev-cal-popup {
    position: absolute;
    z-index: 30;
    width: min(320px, calc(100% - 16px));
    background: #ffffff;
    border: 1px solid rgba(2, 12, 146, 0.18);
    border-radius: 12px;
    box-shadow:
        0 0 0 1px rgba(2, 12, 146, 0.1),
        0 18px 50px rgba(2, 12, 146, 0.25);
    padding: 14px 16px 16px;
    animation: el-popup-in 0.18s var(--el-ease-soft);
    --el-popup-arrow-x: 50%;
}
html.night-mode .el-ev-cal-popup {
    background: #111827;
    border-color: rgba(255, 255, 255, 0.15);
}
.el-ev-cal-popup[hidden] { display: none; }
@keyframes el-popup-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.el-ev-cal-popup-arrow {
    position: absolute;
    width: 14px; height: 14px;
    background: inherit;
    border: 1px solid rgba(2, 12, 146, 0.18);
    top: -8px;
    left: var(--el-popup-arrow-x);
    transform: translateX(-50%) rotate(45deg);
    border-right: 0;
    border-bottom: 0;
    border-radius: 2px 0 0 0;
}
html.night-mode .el-ev-cal-popup-arrow {
    background: #111827;
    border-color: rgba(255, 255, 255, 0.15);
}
.el-ev-cal-popup--above .el-ev-cal-popup-arrow {
    top: auto;
    bottom: -8px;
    border: 1px solid rgba(2, 12, 146, 0.18);
    border-left: 0;
    border-top: 0;
    border-radius: 0 0 2px 0;
}
html.night-mode .el-ev-cal-popup--above .el-ev-cal-popup-arrow {
    border-color: rgba(255, 255, 255, 0.15);
}
.el-ev-cal-popup-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding-bottom: 10px;
    border-bottom: 1px solid rgba(2, 12, 146, 0.1);
    margin-bottom: 10px;
}
html.night-mode .el-ev-cal-popup-head { border-bottom-color: rgba(255, 255, 255, 0.1); }
.el-ev-cal-popup-date {
    font-size: 0.88rem;
    font-weight: 800;
    color: var(--el-text);
    letter-spacing: -0.01em;
}
.el-ev-cal-popup-close {
    background: transparent;
    border: 0;
    color: var(--el-text-muted);
    width: 26px; height: 26px;
    border-radius: 50%;
    cursor: pointer;
    display: grid;
    place-items: center;
}
.el-ev-cal-popup-close:hover {
    background: rgba(2, 12, 146, 0.08);
    color: var(--el-text);
}
.el-ev-cal-popup-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 280px;
    overflow-y: auto;
}
.el-ev-cal-popup-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-bottom: 10px;
    border-bottom: 1px dashed rgba(2, 12, 146, 0.08);
}
.el-ev-cal-popup-item:last-child { border-bottom: 0; padding-bottom: 0; }
html.night-mode .el-ev-cal-popup-item { border-bottom-color: rgba(255, 255, 255, 0.08); }
.el-ev-cal-popup-title {
    font-size: 0.95rem;
    font-weight: 800;
    color: var(--el-text);
    line-height: 1.3;
    margin-top: 2px;
}
.el-ev-cal-popup-sub {
    font-size: 0.8rem;
    color: var(--el-text-muted);
    line-height: 1.4;
}
.el-ev-cal-popup-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 0.76rem;
    color: var(--el-text-muted);
    margin-top: 4px;
}
.el-ev-cal-popup-meta .mdi { margin-right: 3px; }

/* ═══════════════════════════════════════════════════════════════════════
   NEWS PAGE — hero search, featured card, filterable grid, subscribe
   ═══════════════════════════════════════════════════════════════════ */

/* Add matching category pill colours for Maintenance + Community since
   news uses those categories too (events don't). */
.el-ev-cat-pill--maintenance { color: #b45309; }
.el-ev-cat-pill--community   { color: #7c3aed; }
.el-ev-cat-pill--sponsor     { color: #0369a1; }
.el-ev-cat-bg--maintenance   { background: #64748b; color: #fff; }   /* matches dot */
.el-ev-cat-bg--community     { background: #10b981; color: #fff; }   /* matches dot */
.el-ev-cat-bg--sponsor       { background: #a855f7; color: #fff; }   /* matches dot */
.el-ev-cat-bg--sponsor       { background: #0369a1; color: #fff; }

/* Hero search bar — rounded pill, semi-transparent on the navy hero */
.el-news-search {
    position: relative;
    max-width: 460px;
    margin-top: 24px;
}
.el-news-search > .mdi {
    position: absolute;
    left: 18px;
    top: 50%;
    transform: translateY(-50%);
    color: rgba(255, 255, 255, 0.55);
    font-size: 1.1rem;
    pointer-events: none;
}
.el-news-search input {
    width: 100%;
    padding: 12px 18px 12px 44px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(255, 255, 255, 0.08);
    color: #ffffff;
    font-size: 0.92rem;
    font-family: inherit;
    outline: none;
    transition: border-color 0.2s, background 0.2s;
}
.el-news-search input::placeholder { color: rgba(255, 255, 255, 0.5); }
.el-news-search input:focus {
    border-color: rgba(255, 255, 255, 0.55);
    background: rgba(255, 255, 255, 0.14);
}

/* Featured card — 50/50 side-by-side on desktop, stacks on mobile */
.el-news-featured {
    margin-top: 18px;
}

/* Revolving carousel shell — track holds N cards side-by-side; only
   one is visible at a time, rest slide in/out via translateX. */
.el-news-feat-carousel {
    position: relative;
    overflow: hidden;
    border-radius: var(--el-radius-lg);
}
.el-news-feat-track {
    display: flex;
    transition: transform 0.55s var(--el-ease-soft);
    will-change: transform;
}
.el-news-feat-track > .el-news-feat-card {
    flex: 0 0 auto;
    border-radius: 0;           /* parent carousel already has rounded corners */
    box-shadow: none;            /* parent handles shadow via a wrapper */
}
.el-news-feat-carousel .el-news-feat-card {
    background: #ffffff;
}
html.night-mode .el-news-feat-carousel .el-news-feat-card { background: rgba(255, 255, 255, 0.04); }

/* Carousel wrapper gets the outer shadow so the slide transition
   doesn't re-paint the shadow per-frame. */
.el-news-feat-carousel {
    background: #ffffff;
    box-shadow:
        0 0 0 1px rgba(2, 12, 146, 0.12),
        0 16px 44px rgba(2, 12, 146, 0.18);
}
html.night-mode .el-news-feat-carousel {
    background: rgba(255, 255, 255, 0.04);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.08),
        0 16px 44px rgba(0, 0, 0, 0.35);
}

/* Prev / next nav buttons — half-transparent circles, float over the
   photo side. Only render when there's more than one slide. */
.el-news-feat-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 42px; height: 42px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid rgba(2, 12, 146, 0.15);
    color: var(--el-hero);
    display: grid;
    place-items: center;
    cursor: pointer;
    font-size: 1.3rem;
    transition: background 0.2s, transform 0.2s;
    z-index: 3;
    backdrop-filter: blur(8px);
}
.el-news-feat-nav:hover { background: #ffffff; transform: translateY(-50%) scale(1.05); }
.el-news-feat-nav--prev { left: 14px; }
.el-news-feat-nav--next { right: 14px; }
html.night-mode .el-news-feat-nav {
    background: rgba(10, 15, 30, 0.8);
    color: var(--el-accent);
    border-color: rgba(255, 255, 255, 0.14);
}
html.night-mode .el-news-feat-nav:hover { background: rgba(15, 22, 45, 0.95); }

/* Dot indicators — along the bottom of the photo side */
.el-news-feat-dots {
    position: absolute;
    left: 20px;
    bottom: 18px;
    display: flex;
    gap: 8px;
    z-index: 3;
}
.el-news-feat-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.5);
    border: 0;
    padding: 0;
    cursor: pointer;
    transition: width 0.3s, background 0.3s;
}
.el-news-feat-dot.is-active {
    width: 24px;
    border-radius: 999px;
    background: #ffffff;
}

/* Pin badge inside the featured date row */
.el-news-feat-pin {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(220, 38, 38, 0.12);
    color: #b91c1c;
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-right: 10px;
}
html.night-mode .el-news-feat-pin {
    background: rgba(239, 68, 68, 0.18);
    color: #fca5a5;
}
.el-news-feat-pin .mdi { font-size: 0.82rem; }
.el-news-feat-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0;
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s var(--el-ease-soft);
}
html.night-mode .el-news-feat-card { background: rgba(255, 255, 255, 0.04); }
.el-news-feat-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--el-glow-hover);
}
/* Cards INSIDE a carousel delegate hover + shadow to the carousel
   shell — otherwise lifting an individual card mid-rotation looks odd. */
.el-news-feat-carousel .el-news-feat-card:hover {
    transform: none;
    box-shadow: none;
}
.el-news-feat-photo {
    position: relative;
    min-height: 320px;
    background: var(--el-surface-alt);
    overflow: hidden;
}
.el-news-feat-photo img {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
.el-news-feat-placeholder {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: rgba(2, 12, 146, 0.25);
    font-size: 5rem;
}
.el-news-feat-body {
    padding: 32px 36px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    justify-content: center;
}
.el-news-feat-title {
    margin: 4px 0 0;
    font-size: clamp(1.6rem, 3vw, 2.4rem);
    font-weight: 800;
    color: var(--el-text);
    line-height: 1.15;
    letter-spacing: -0.01em;
}
.el-news-feat-sub {
    margin: 0;
    font-size: 0.98rem;
    color: var(--el-text-muted);
    line-height: 1.5;
}
.el-news-feat-date {
    font-size: 0.82rem;
    color: var(--el-text-muted);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* Article grid — 2-up on desktop, stacks on mobile */
.el-news-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
    margin-top: 6px;
}
.el-news-card {
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border-radius: var(--el-radius);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s var(--el-ease-soft);
}
/* Hollow card on the navy section: kill the white-tint overlay so
   the section's gradient + sky glow shows through. The existing
   --el-glow-idle box-shadow + a faint sky-blue border frame the
   card without filling it. */
html.night-mode .el-news-card {
    background: transparent;
    border: 1px solid rgba(125, 211, 252, 0.18);
}
.el-news-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--el-glow-hover);
}
.el-news-card-link {
    display: flex;
    flex-direction: column;
    height: 100%;
    color: inherit;
    text-decoration: none;
}
.el-news-card-photo {
    position: relative;
    aspect-ratio: 16 / 10;
    background: var(--el-surface-alt);
    overflow: hidden;
}
.el-news-card-photo img {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
.el-news-card-body {
    padding: 18px 20px 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1;
}
.el-news-card-meta {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.el-news-card-date {
    font-size: 0.78rem;
    color: var(--el-text-muted);
}
.el-news-card-title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--el-text);
    line-height: 1.3;
    letter-spacing: -0.01em;
}
.el-news-card-sub {
    margin: 0;
    font-size: 0.88rem;
    color: var(--el-text-muted);
    line-height: 1.5;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Read More link (used in both featured + card) */
.el-news-more-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: auto;
    padding-top: 8px;
    font-size: 0.82rem;
    font-weight: 800;
    color: var(--el-hero);
    text-transform: none;
    transition: gap 0.2s;
}
html.night-mode .el-news-more-link { color: var(--el-accent); }
.el-news-more-link:hover { gap: 8px; }

.el-news-more {
    display: flex;
    justify-content: center;
    margin-top: 30px;
}

/* Category pill gets the icon + text inline — nudge icon size */
.el-ev-cat-pill .mdi {
    font-size: 0.88rem;
    vertical-align: -1px;
    margin-right: 4px;
}

/* Subscribe CTA — 50/50 split on wide, stacks on mobile */
.el-news-cta-card {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(28px, 4vw, 56px);
    background:
        radial-gradient(ellipse at 10% 100%, rgba(125, 211, 252, 0.1) 0%, transparent 50%),
        linear-gradient(135deg, #020c92 0%, #000659 100%);
    color: var(--el-text-inv);
    padding: 48px clamp(24px, 4vw, 48px);
    border-radius: var(--el-radius-lg);
    box-shadow: var(--el-shadow);
    align-items: center;
}
.el-news-cta-title {
    margin: 0 0 12px;
    font-size: clamp(1.8rem, 3vw, 2.4rem);
    font-weight: 900;
    line-height: 1.15;
    letter-spacing: -0.02em;
}
.el-news-cta-sub {
    margin: 0 0 16px;
    font-size: 0.98rem;
    color: var(--el-text-inv-muted);
    line-height: 1.5;
    max-width: 440px;
}
.el-news-cta-bullets {
    list-style: none;
    padding: 0;
    margin: 12px 0 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: 0.92rem;
}
.el-news-cta-bullets li {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--el-text-inv);
}
.el-news-cta-bullets .mdi {
    color: var(--el-accent);
    font-size: 1.1rem;
    text-shadow: 0 0 12px rgba(125, 211, 252, 0.45);
}

/* Subscribe form is the inner ("child") card sitting inside the
   navy CTA panel. Day mode: solid white cutout against the navy
   panel — clean white card with a subtle shadow. Night mode:
   transparent cutout — the navy panel shows through, only a faint
   sky-blue outline frames the form. */
.el-news-cta-form {
    background: #ffffff;
    border: 1px solid rgba(2, 12, 146, 0.10);
    border-radius: var(--el-radius);
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18);
}
html.night-mode .el-news-cta-form {
    background: transparent;
    border: 1px solid rgba(125, 211, 252, 0.22);
    box-shadow: none;
}
.el-news-cta-field input[type="email"] {
    width: 100%;
    padding: 12px 16px;
    background: rgba(255, 255, 255, 0.9);
    border: 1px solid transparent;
    border-radius: 8px;
    color: #0b1220;
    font-size: 0.92rem;
    outline: none;
    font-family: inherit;
}
.el-news-cta-field input[type="email"]:focus {
    border-color: var(--el-accent);
    background: #ffffff;
}
.el-news-cta-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.86rem;
    color: var(--el-text-muted);
    cursor: pointer;
}
html.night-mode .el-news-cta-check {
    color: var(--el-text-inv-muted);
}
.el-news-cta-check input { accent-color: var(--el-accent); }
/* Subscribe (parent) — uses the same el-btn--green treatment as
   every other terminal CTA on the bespoke pages. The form keeps its
   own padding/radius via .el-news-cta-form, only the button picks up
   the green pill styling so it reads as the page's end-point action. */
.el-news-cta-submit {
    padding: 14px 24px;
    border-radius: 999px;
    background: var(--el-green);
    color: var(--el-green-text);
    border: 2px solid var(--el-hero);
    font-size: 0.88rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: filter 0.2s, transform 0.2s, box-shadow 0.25s;
    box-shadow:
        0 0 28px rgba(2, 12, 146, 0.45),
        0 8px 24px rgba(188, 255, 0, 0.20);
}
.el-news-cta-submit:hover:not(:disabled) {
    filter: brightness(1.08);
    transform: translateY(-2px);
    box-shadow:
        0 0 38px rgba(2, 12, 146, 0.60),
        0 12px 32px rgba(188, 255, 0, 0.30);
}
html.night-mode .el-news-cta-submit {
    box-shadow:
        0 0 28px rgba(125, 211, 252, 0.45),
        0 8px 24px rgba(188, 255, 0, 0.22);
}
html.night-mode .el-news-cta-submit:hover:not(:disabled) {
    box-shadow:
        0 0 40px rgba(125, 211, 252, 0.65),
        0 12px 32px rgba(188, 255, 0, 0.32);
}
.el-news-cta-submit:disabled { opacity: 0.5; cursor: not-allowed; }
.el-news-cta-privacy {
    font-size: 0.78rem;
    color: var(--el-text-muted);
    text-align: center;
}
html.night-mode .el-news-cta-privacy {
    color: var(--el-text-inv-muted);
}
.el-news-cta-ok {
    font-size: 0.88rem;
    font-weight: 700;
    color: var(--el-accent);
    text-shadow: 0 0 12px rgba(125, 211, 252, 0.45);
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: center;
}
.el-news-cta-ok .mdi { font-size: 1.1rem; }

@media (max-width: 900px) {
    .el-news-feat-card { grid-template-columns: 1fr; }
    .el-news-feat-photo { min-height: 220px; aspect-ratio: 16 / 10; }
    .el-news-feat-body { padding: 24px 22px; }
    .el-news-cta-card { grid-template-columns: 1fr; padding: 36px 24px; }
}

/* ═══════════════════════════════════════════════════════════════════════
   CONTACT PAGE — hero strip, form + card, map, visiting, emergency
   ═══════════════════════════════════════════════════════════════════ */

/* Hero quick-contact strip */
.el-contact-hero-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 22px;
    margin-top: 22px;
    font-size: 0.88rem;
}
.el-contact-hero-strip > * {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--el-text-inv-muted);
    text-decoration: none;
    transition: color 0.15s;
}
.el-contact-hero-strip a:hover { color: var(--el-text-inv); }
.el-contact-hero-strip .mdi { color: var(--el-green); font-size: 1.05rem; }

/* 2-col: form (left) + club-info card (right) */
.el-contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: clamp(24px, 4vw, 56px);
    align-items: start;
}

/* ── Combined shell: Club Info (left) + Send-Us-a-Message (right) ─────
   Single full-width card that owns the white bg, border and shadow.
   Both inner panels shed their own shell via the scoped overrides below
   so the effect is one wide card with an internal vertical rule. */
.el-contact-combo {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft);
    padding: clamp(24px, 3.2vw, 40px);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    gap: clamp(28px, 4vw, 56px);
    position: relative;
}
.el-contact-combo:hover { box-shadow: var(--el-glow-hover); }
html.night-mode .el-contact-combo {
    background: rgba(255, 255, 255, 0.04);
}
/* Vertical rule between the two panels (desktop only) */
.el-contact-combo::before {
    content: '';
    position: absolute;
    top: clamp(24px, 3.2vw, 40px);
    bottom: clamp(24px, 3.2vw, 40px);
    left: 50%;
    width: 1px;
    background: var(--el-border);
    pointer-events: none;
}
/* Strip the nested children of their own shell — they're flat panels
   inside the combined parent card now. The :hover stripes also cancel
   the glow + lift the base .el-contact-card / .el-contact-form rules
   otherwise paint on hover (nested-card double-glow bug). */
.el-contact-combo .el-contact-card,
.el-contact-combo .el-contact-form,
.el-contact-combo .el-contact-card:hover,
.el-contact-combo .el-contact-form:hover {
    background: transparent;
    box-shadow: none;
    transform: none;
    padding: 0;
    border-radius: 0;
}
html.night-mode .el-contact-combo .el-contact-card,
html.night-mode .el-contact-combo .el-contact-form {
    background: transparent;
}
.el-contact-form {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    padding: 32px;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft), transform 0.35s var(--el-ease-soft);
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.el-contact-form:hover {
    transform: translateY(-3px);
    box-shadow: var(--el-glow-hover);
}
html.night-mode .el-contact-form { background: rgba(255, 255, 255, 0.04); }
.el-contact-form-title {
    margin: 0 0 4px;
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--el-text);
}
.el-contact-form-sub {
    margin: 0 0 10px;
    font-size: 0.88rem;
    color: var(--el-text-muted);
}
.el-contact-field { display: block; }
.el-contact-field input,
.el-contact-field select,
.el-contact-field textarea {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--el-border);
    border-radius: 8px;
    background: var(--el-surface);
    color: var(--el-text);
    font-size: 0.92rem;
    font-family: inherit;
    outline: none;
    transition: border-color 0.2s, background 0.2s;
}
html.night-mode .el-contact-field input,
html.night-mode .el-contact-field textarea {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.12);
}
/* Select needs individual bg-color (not shorthand) so the chevron
   background-image + no-repeat isn't wiped by night-mode overrides. */
html.night-mode .el-contact-field select {
    background-color: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.12);
}
.el-contact-field input:focus,
.el-contact-field textarea:focus {
    border-color: var(--el-hero);
    background: #ffffff;
}
.el-contact-field select:focus {
    border-color: var(--el-hero);
    background-color: #ffffff;
}
html.night-mode .el-contact-field input:focus,
html.night-mode .el-contact-field textarea:focus {
    background: rgba(255, 255, 255, 0.08);
    border-color: var(--el-accent);
}
html.night-mode .el-contact-field select:focus {
    background-color: rgba(255, 255, 255, 0.08);
    border-color: var(--el-accent);
}
/* Option popup — the native dropdown is rendered by the browser; we
   can only style each <option>. Pair these with color-scheme: dark on
   html.night-mode so the surrounding popup chrome is dark too. */
.el-contact-field select option {
    background-color: #ffffff;
    color: var(--el-text);
}
html.night-mode .el-contact-field select option {
    background-color: #0f0f10;
    color: #ffffff;
}
html.night-mode .el-contact-field select option:checked,
html.night-mode .el-contact-field select option:hover {
    background-color: #020c92;
    color: #ffffff;
}
/* Custom chevron on the <select> — the default UA arrow often reads
   as a tiny grey triangle on dark themes. Replace with a consistent
   navy (day) / accent (night) caret. */
.el-contact-field select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='%23020c92' d='M6 8 0 0h12z'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 38px;
}
html.night-mode .el-contact-field select {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='%237dd3fc' d='M6 8 0 0h12z'/></svg>");
    background-repeat: no-repeat;               /* belt-and-braces — keeps the chevron single */
    background-position: right 14px center;
}
.el-contact-field textarea { resize: vertical; min-height: 100px; }
.el-contact-submit {
    padding: 14px 22px;
    background: #dc2626;
    color: #ffffff;
    border: 0;
    border-radius: 8px;
    font-size: 0.88rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: filter 0.2s, transform 0.2s;
}
.el-contact-submit:hover:not(:disabled) { filter: brightness(1.1); transform: translateY(-1px); }
.el-contact-submit:disabled { opacity: 0.5; cursor: not-allowed; }
.el-contact-form-note {
    margin: 4px 0 0;
    font-size: 0.82rem;
    color: var(--el-text-muted);
    text-align: center;
}
/* Success banner: floating toast pill — slides down from the top when the
   form submits successfully, fades out after a few seconds. Hidden until
   contact.js explicitly flips the `hidden` attribute + adds `.is-visible`. */
.el-contact-form-ok {
    position: fixed;
    top: 24px;
    left: 50%;
    transform: translate(-50%, -20px);
    z-index: 1200;
    padding: 14px 22px;
    border-radius: 999px;
    background: #15803d;
    border: 1px solid rgba(21, 128, 61, 0.9);
    color: #ffffff;
    font-size: 0.92rem;
    font-weight: 600;
    box-shadow: 0 14px 40px rgba(21, 128, 61, 0.35);
    display: flex;
    align-items: center;
    gap: 10px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.25s ease, transform 0.35s var(--el-ease-soft);
}
.el-contact-form-ok.is-visible {
    opacity: 1;
    transform: translate(-50%, 0);
}
/* The `display: flex` above defeats the HTML `hidden` attribute — reinstate it. */
.el-contact-form-ok[hidden] { display: none !important; }
html.night-mode .el-contact-form-ok {
    background: #15803d;
    color: #ffffff;
    border-color: rgba(134, 239, 172, 0.4);
}
.el-contact-form-ok .mdi { font-size: 1.2rem; color: inherit; }

/* Same hidden-override gotcha on the error banner. */
.el-contact-form-err {
    display: flex;
    align-items: center;
    gap: 8px;
}
.el-contact-form-err[hidden] { display: none !important; }

/* Honeypot field — visually and assistive-tech hidden, but still
   submittable so bots trip over it. Position off-screen rather than
   `display:none` so automated fillers still target it. */
.el-contact-field.el-contact-field--hp {
    position: absolute;
    left: -9999px;
    top: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

/* Club Info card on the right */
.el-contact-card {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    padding: 32px;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft), transform 0.35s var(--el-ease-soft);
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.el-contact-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--el-glow-hover);
}
html.night-mode .el-contact-card { background: rgba(255, 255, 255, 0.04); }
.el-contact-card-eyebrow {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}
.el-contact-card-title {
    margin: -4px 0 6px;
    font-size: 1.3rem;
    font-weight: 800;
    color: var(--el-text);
    letter-spacing: -0.01em;
}
.el-contact-card-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.el-contact-card-list > li {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    font-size: 0.92rem;
    color: var(--el-text);
    line-height: 1.4;
}
/* The `display: flex` above defeats the HTML `hidden` attribute — reinstate
   it so rows that start hidden (WhatsApp, Website) stay collapsed until
   contact.js populates them. */
.el-contact-card-list > li[hidden] { display: none !important; }
.el-contact-card-list > li > .mdi {
    color: var(--el-hero);
    font-size: 1.2rem;
    margin-top: 1px;
    flex-shrink: 0;
}
html.night-mode .el-contact-card-list > li > .mdi { color: var(--el-accent); }
.el-contact-card-list a { color: var(--el-text); text-decoration: underline; text-decoration-color: rgba(2, 12, 146, 0.3); text-underline-offset: 3px; }
.el-contact-card-list a:hover { text-decoration-color: var(--el-hero); }
html.night-mode .el-contact-card-list a:hover { text-decoration-color: var(--el-accent); }
.el-contact-card-label {
    font-weight: 700;
}
.el-contact-card-sub {
    font-size: 0.82rem;
    color: var(--el-text-muted);
    margin-top: 2px;
}
.el-contact-card-socials {
    display: flex;
    gap: 10px;
    margin-top: 4px;
}
.el-contact-card-socials a {
    width: 38px; height: 38px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--el-hero);
    color: #ffffff;
    transition: transform 0.2s, filter 0.2s;
}
.el-contact-card-socials a:hover { transform: translateY(-2px); filter: brightness(1.2); }
.el-contact-card-socials a svg  { width: 16px; height: 16px; }
.el-contact-card-socials a .mdi { font-size: 1.05rem; }
.el-contact-card-dir {
    align-self: flex-start;
    margin-top: 6px;
}

/* Map + Street View split — 2-col grid on desktop, stacked on mobile */
.el-contact-map-section {
    padding: 0;
    margin-top: 0;
}
.el-contact-map-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    width: 100%;
    min-height: 320px;
    aspect-ratio: 16 / 5;
    max-height: 440px;
    background: var(--el-surface-alt);
    overflow: hidden;
}
.el-contact-map-wrap,
.el-contact-sv-wrap {
    position: relative;
    overflow: hidden;
    background: var(--el-surface-alt);
}
.el-contact-map-frame,
.el-contact-sv-frame {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}
/* Fallback Street View card — shown when the committee hasn't supplied
   a Street View embed URL but we DO have coords from the map embed. */
.el-contact-sv-card {
    display: block;
    width: 100%; height: 100%;
    background:
        radial-gradient(circle at 30% 20%, rgba(125, 211, 252, 0.15) 0%, transparent 55%),
        linear-gradient(135deg, #020c92 0%, #000659 100%);
    color: #ffffff;
    text-decoration: none;
    transition: filter 0.2s;
}
.el-contact-sv-card:hover { filter: brightness(1.1); }
.el-contact-sv-card-inner {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 24px;
    text-align: center;
}
.el-contact-sv-card-inner .mdi {
    font-size: 3rem;
    color: var(--el-green);
}
.el-contact-sv-card-title {
    font-size: 1.1rem;
    font-weight: 800;
    letter-spacing: -0.01em;
}
.el-contact-sv-card-sub {
    font-size: 0.88rem;
    color: rgba(255, 255, 255, 0.75);
}
.el-contact-sv-placeholder {
    display: grid;
    place-items: center;
    height: 100%;
    color: var(--el-text-muted);
}
@media (max-width: 860px) {
    .el-contact-map-grid {
        grid-template-columns: 1fr;
        aspect-ratio: auto;
        max-height: none;
    }
    .el-contact-map-wrap,
    .el-contact-sv-wrap { min-height: 280px; aspect-ratio: 4 / 3; }
}

/* Visiting the Club — 4-up icon cards */
.el-visit-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 22px;
    margin-top: 32px;
}
.el-visit-card {
    background: #ffffff;
    border-radius: var(--el-radius);
    padding: 28px 24px;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: center;
    box-shadow: var(--el-glow-idle);
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s var(--el-ease-soft);
}
html.night-mode .el-visit-card { background: rgba(255, 255, 255, 0.04); }
.el-visit-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--el-glow-hover);
}
.el-visit-icon {
    width: 48px; height: 48px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(2, 12, 146, 0.08);
    color: var(--el-hero);
    font-size: 1.4rem;
    margin-bottom: 4px;
}
html.night-mode .el-visit-icon {
    background: rgba(255, 255, 255, 0.08);
    color: var(--el-accent);
}
.el-visit-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--el-text);
}
.el-visit-card > p {
    margin: 0;
    font-size: 0.88rem;
    color: var(--el-text-muted);
    line-height: 1.5;
}
.el-visit-card .el-news-more-link {
    margin-top: 6px;
    font-size: 0.78rem;
}

/* Emergency Contacts section — dark navy strip at the page bottom.
   Tightened vertical rhythm: smaller padding above so the dark card
   sits closer to the Visiting-the-Club strip; small padding below so
   it has breathing room before the footer (instead of 0 gap). */
.el-contact-emg {
    padding-top: clamp(28px, 4vw, 48px);
    padding-bottom: clamp(28px, 4vw, 48px);
}
.el-contact-emg-card {
    background:
        radial-gradient(ellipse at 15% 100%, rgba(239, 68, 68, 0.12) 0%, transparent 55%),
        linear-gradient(135deg, #020c92 0%, #000659 100%);
    color: var(--el-text-inv);
    padding: 40px clamp(24px, 4vw, 48px);
    border-radius: var(--el-radius-lg);
    box-shadow: var(--el-shadow);
}
.el-contact-emg-title {
    margin: 0 0 8px;
    font-size: clamp(1.4rem, 2.6vw, 1.9rem);
    font-weight: 800;
    letter-spacing: -0.01em;
}
.el-contact-emg-sub {
    margin: 0 0 20px;
    font-size: 0.92rem;
    color: var(--el-text-inv-muted);
    max-width: 560px;
}
.el-contact-emg-list {
    list-style: none;
    padding: 0;
    margin: 0 0 20px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 10px;
}
.el-contact-emg-list li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.92rem;
    color: var(--el-text-inv);
}
.el-contact-emg-list .mdi { color: #ef4444; font-size: 1.15rem; flex-shrink: 0; }
.el-contact-emg-lab { color: var(--el-text-inv-muted); margin-right: 2px; }
.el-contact-emg-list a { color: var(--el-green); text-decoration: none; }
.el-contact-emg-list a:hover { text-decoration: underline; }
.el-contact-emg-medical {
    margin: 0;
    padding-top: 16px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    font-size: 0.86rem;
    color: var(--el-text-inv-muted);
}
.el-contact-emg-medical strong { color: var(--el-text-inv); }

@media (max-width: 860px) {
    .el-contact-grid { grid-template-columns: 1fr; }
    .el-contact-form, .el-contact-card { padding: 24px; }
    .el-contact-map-wrap { aspect-ratio: 4 / 3; min-height: 320px; }
    /* Combined shell: stack panels; rule flips to horizontal */
    .el-contact-combo { grid-template-columns: 1fr; gap: 32px; }
    .el-contact-combo::before {
        top: auto;
        bottom: auto;
        left: clamp(24px, 6vw, 40px);
        right: clamp(24px, 6vw, 40px);
        width: auto;
        height: 1px;
        top: calc(50% - 0.5px);
    }
}

/* Event list */
.el-ev-list { display: flex; flex-direction: column; gap: 8px; }
.el-ev-list-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 16px;
    background: rgba(255, 255, 255, 0.6);
    border-radius: 10px;
    transition: background 0.2s, transform 0.2s;
    color: var(--el-text);
    text-decoration: none;
}
html.night-mode .el-ev-list-row { background: rgba(255, 255, 255, 0.04); }
.el-ev-list-row:hover {
    background: rgba(2, 12, 146, 0.06);
    transform: translateX(3px);
}
html.night-mode .el-ev-list-row:hover { background: rgba(255, 255, 255, 0.08); }
.el-ev-list-date {
    flex-shrink: 0;
    width: 56px;
    aspect-ratio: 1;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-weight: 800;
}
.el-ev-list-day { font-size: 1.1rem; line-height: 1; }
.el-ev-list-mo  { font-size: 0.6rem; letter-spacing: 0.1em; opacity: 0.85; margin-top: 2px; }
.el-ev-list-body {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; gap: 4px;
}
.el-ev-list-title {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--el-text);
    line-height: 1.35;
}
.el-ev-list-meta {
    display: flex; flex-wrap: wrap; gap: 14px;
    font-size: 0.76rem;
    color: var(--el-text-muted);
}
.el-ev-list-meta .mdi { margin-right: 3px; }
.el-ev-list-chev { color: var(--el-text-muted); font-size: 1.3rem; flex-shrink: 0; }

/* Divider between Upcoming + Past sections in the event list */
.el-ev-list-divider {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 4px;
    margin: 14px 0 4px;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}
.el-ev-list-divider:first-child { margin-top: 0; }
.el-ev-list-divider .mdi { font-size: 0.95rem; }
.el-ev-list-divider--upcoming { color: var(--el-hero); }
html.night-mode .el-ev-list-divider--upcoming { color: var(--el-accent); }

/* 'Show more past events' button */
.el-ev-list-more {
    align-self: center;
    margin-top: 10px;
    padding: 10px 22px;
    border-radius: 999px;
    border: 1px solid var(--el-border);
    background: transparent;
    color: var(--el-text);
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 0.2s, border-color 0.2s;
}
.el-ev-list-more:hover {
    background: rgba(2, 12, 146, 0.06);
    border-color: rgba(2, 12, 146, 0.3);
}
html.night-mode .el-ev-list-more:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.25);
}

/* Tournaments — alternating 50/50 cards */
.el-tourn-list {
    display: flex;
    flex-direction: column;
    gap: 32px;
    margin-top: 28px;
}
.el-tourn-card {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s var(--el-ease-soft);
}
html.night-mode .el-tourn-card { background: rgba(255, 255, 255, 0.04); }
.el-tourn-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--el-glow-hover);
}
.el-tourn-card--flipped .el-tourn-photo { order: 2; }
.el-tourn-photo {
    position: relative;
    min-height: 280px;
    background: var(--el-surface-alt);
    overflow: hidden;
}
.el-tourn-photo img {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
.el-tourn-photo-placeholder {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: rgba(2, 12, 146, 0.25);
    font-size: 5rem;
}
.el-tourn-body {
    padding: 32px 36px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    justify-content: center;
}
.el-tourn-title {
    margin: 6px 0 0;
    font-size: clamp(1.4rem, 2.6vw, 2rem);
    font-weight: 800;
    color: var(--el-text);
    line-height: 1.15;
    letter-spacing: -0.01em;
}
.el-tourn-sub {
    margin: 0;
    font-size: 0.95rem;
    color: var(--el-text-muted);
    line-height: 1.45;
}
.el-tourn-prize {
    margin: 10px 0 0;
    display: flex;
    align-items: baseline;
    gap: 10px;
}
.el-tourn-prize-value {
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    font-weight: 900;
    color: #dc2626;
    letter-spacing: -0.02em;
}
.el-tourn-prize-label {
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}
.el-tourn-specs {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px 28px;
    margin: 16px 0 0;
}
.el-tourn-specs > div { display: flex; flex-direction: column; gap: 2px; }
.el-tourn-specs dt {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}
.el-tourn-specs dd {
    margin: 0;
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--el-text);
}

.el-cta-card-contact {
    font-size: 0.85rem;
    color: var(--el-text-inv-muted);
    margin: 22px 0 0;
}
.el-cta-card-contact a { color: var(--el-accent); text-decoration: underline; }

@media (max-width: 820px) {
    .el-tourn-card { grid-template-columns: 1fr; }
    .el-tourn-card--flipped .el-tourn-photo { order: 0; }
    .el-tourn-photo { min-height: 220px; aspect-ratio: 16 / 10; }
    .el-tourn-body { padding: 24px 22px; }
    .el-tourn-specs { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 500px) {
    .el-ev-cal { padding: 14px 14px; }
    .el-ev-cal-cell { font-size: 0.78rem; padding: 4px 2px; }
    .el-ev-list-row { padding: 10px 12px; gap: 12px; }
    .el-ev-list-date { width: 48px; }
}

/* ──────────────────────────────────────────────────────────────────────
   Memberships page — tier grid, comparison table, steps, benefits, FAQ,
   Ready-to-Join card.

   Palette notes:
   • Plan cards sit on the light cream/blue surface; each card has its own
     accent hue (from `membership_types.color`) exposed via `--card-hue`.
   • The "Most Popular" ribbon + hovered card escalate to the club's royal
     navy to keep the page visually anchored.
   • Member Benefits section is the lone dark block — dark navy bg with
     the tennis-ball green accent for the supporting flourishes.
   ────────────────────────────────────────────────────────────────────── */

/* Hero info pill under the sub-heading */
.el-hero-note {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.86rem;
    font-weight: 500;
    color: var(--el-text-inv);
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.22);
    padding: 8px 16px;
    border-radius: 999px;
    margin-top: 22px;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
.el-hero-note i { font-size: 1.05rem; color: var(--el-green); }

/* ── Plan grid ─────────────────────────────────────────────────────── */
.el-ms-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 24px;
    align-items: stretch;
}
@media (min-width: 1100px) {
    .el-ms-grid { grid-template-columns: repeat(3, 1fr); }
}

.el-ms-card {
    --card-hue: var(--club-accent);
    position: relative;
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border: 1px solid var(--el-border);
    border-radius: var(--el-radius-lg);
    padding: 28px 24px 24px;
    box-shadow: var(--el-shadow-sm);
    transition: transform 0.32s var(--el-ease-soft), box-shadow 0.32s, border-color 0.32s;
    overflow: hidden;
}
.el-ms-card::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 5px;
    background: var(--card-hue);
    border-top-left-radius: var(--el-radius-lg);
    border-top-right-radius: var(--el-radius-lg);
}
.el-ms-card:hover {
    transform: translateY(-6px);
    box-shadow: var(--el-shadow);
    border-color: rgba(2, 12, 146, 0.22);
}
html.night-mode .el-ms-card {
    background: #12141b;
    border-color: var(--el-border);
}
html.night-mode .el-ms-card:hover {
    border-color: rgba(255, 255, 255, 0.2);
}

.el-ms-card--popular {
    border-color: var(--club-accent);
    box-shadow: 0 14px 42px rgba(2, 12, 146, 0.22);
}
html.night-mode .el-ms-card--popular {
    border-color: var(--el-green);
    box-shadow: 0 14px 42px rgba(188, 255, 0, 0.2);
}
/* 45° corner ribbon in the BOTTOM-LEFT of the card. Card has
   overflow:hidden so the ribbon's over-hanging ends get clipped
   cleanly into a triangular corner flag. Text reads along the
   diagonal, lower-left to upper-right.

   Sizing notes: keep the ribbon SHORT (narrower padding) so the
   diagonal doesn't push the text past the card's right edge —
   rotating a wide element 45° means its visible horizontal run
   is `width * cos(45)` ≈ 70% of the unrotated width. Short text
   inside narrow padding keeps it inside the clip region. */
.el-ms-card-ribbon {
    position: absolute;
    bottom: 20px;
    left: -32px;
    transform: rotate(45deg);
    transform-origin: center center;
    background: var(--club-accent);
    color: #ffffff;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 5px 30px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    box-shadow: 0 4px 12px rgba(2, 12, 146, 0.3);
    z-index: 2;
    pointer-events: none;
    white-space: nowrap;
}
.el-ms-card-ribbon i { font-size: 0.78rem; color: var(--el-green); }

/* Family-discount ribbon — same diagonal in the bottom-left but in
   tennis-ball green so it reads as a savings cue. When a tier is
   both popular AND discount-eligible, the discount ribbon stacks
   ABOVE the popular one at a higher `bottom` offset so they sit
   on parallel diagonals without overlapping. */
.el-ms-card-ribbon--discount {
    background: var(--el-green);
    color: var(--el-green-text);
    box-shadow: 0 4px 12px rgba(188, 255, 0, 0.35);
}
.el-ms-card-ribbon--discount i { color: var(--el-green-text); }
.el-ms-card--popular.el-ms-card--discount .el-ms-card-ribbon--discount {
    bottom: 58px;
}

/* ── Unify the card's accent ────────────────────────────────────────
   When a tier card is marked as Popular or Family-Discount, every
   accent on the card (top edge line, icon chip, spec-row icons,
   outer border glow) shifts to a single hue that matches the ribbon
   so the whole card reads as one coherent callout rather than the
   tier's stored `color` fighting with a green border. Discount wins
   over popular when both flags are set (rare — family-discount is
   more actionable). */
.el-ms-card--popular  { --card-hue: var(--club-accent); }
.el-ms-card--discount { --card-hue: var(--el-green);   }

/* Outer border + glow when a card is discount-eligible, echoing the
   same treatment .el-ms-card--popular already applies but in the
   accent green. */
.el-ms-card--discount {
    border-color: var(--el-green);
    box-shadow: 0 14px 42px rgba(188, 255, 0, 0.2);
}
html.night-mode .el-ms-card--discount {
    border-color: var(--el-green);
    box-shadow: 0 14px 42px rgba(188, 255, 0, 0.25);
}

/* Card head: icon chip beside the name/role stack so the top row
   scans quickly without stealing vertical space from the card. */
.el-ms-card-head {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 14px;
}
.el-ms-card-head-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.el-ms-card-icon {
    width: 44px;
    height: 44px;
    border-radius: 12px;
    display: grid;
    place-items: center;
    background: color-mix(in srgb, var(--card-hue) 14%, transparent);
    color: var(--card-hue);
    font-size: 1.4rem;
    flex-shrink: 0;
}
.el-ms-card-icon i { font-size: 1.4rem; }
html.night-mode .el-ms-card-icon {
    background: color-mix(in srgb, var(--card-hue) 22%, transparent);
}
.el-ms-card-name {
    font-size: 1.15rem;
    font-weight: 800;
    line-height: 1.2;
    color: var(--el-text);
    margin: 0;
    letter-spacing: -0.01em;
}
.el-ms-card-role {
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--el-text-muted);
}

/* Single-sentence price summary. Keeps the card airy — full price
   breakdown lives in the details popup. */
.el-ms-card-summary {
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--el-text);
    margin: 0 0 16px;
}

/* Restriction rows: icon + label + value aligned to a consistent grid
   so values line up neatly down the card. Each row is bordered at the
   top so they read as specs rather than bullet points. */
.el-ms-card-specs {
    list-style: none;
    margin: 0 0 20px;
    padding: 0;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}
.el-ms-card-specs li {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    font-size: 0.88rem;
    color: var(--el-text);
    border-top: 1px dashed var(--el-border);
}
.el-ms-card-specs li:first-child { border-top: none; padding-top: 6px; }
.el-ms-card-specs li i {
    color: var(--card-hue);
    font-size: 1.05rem;
    flex-shrink: 0;
}
html.night-mode .el-ms-card-specs li { border-top-color: rgba(255, 255, 255, 0.08); }
/* In night mode the tier's stored hue is usually a navy variant
   that blends into the dark card. Flip spec-row icons to the
   sky-blue accent so they pop. Popular/Discount cards keep their
   unified hue via the variant overrides above. */
html.night-mode .el-ms-card:not(.el-ms-card--popular):not(.el-ms-card--discount) .el-ms-card-specs li i {
    color: var(--el-accent);
}
html.night-mode .el-ms-card:not(.el-ms-card--popular):not(.el-ms-card--discount) .el-ms-card-head-text .el-ms-card-name {
    color: var(--el-text);
}
.el-ms-card-spec-label {
    color: var(--el-text-muted);
    font-weight: 500;
}
.el-ms-card-spec-value {
    font-weight: 700;
    color: var(--el-text);
    text-align: right;
    letter-spacing: -0.01em;
    white-space: nowrap;
}

.el-ms-card-cta {
    margin-top: auto;
    display: flex;
    justify-content: flex-end;
}
/* "More details →" is a subtle secondary action, not a loud CTA. The
   pill style matches the example mockup. */
.el-ms-card-more {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 18px;
    border-radius: 999px;
    background: var(--el-surface-alt);
    border: 1px solid var(--el-border);
    color: var(--el-text);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: gap 0.2s ease, background 0.2s, border-color 0.2s, color 0.2s, transform 0.2s var(--el-ease-soft);
}
.el-ms-card-more:hover {
    gap: 10px;
    background: var(--club-accent);
    border-color: var(--club-accent);
    color: var(--club-accent-text);
    transform: translateY(-1px);
}
html.night-mode .el-ms-card-more {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.1);
    color: var(--el-text);
}
html.night-mode .el-ms-card-more:hover {
    background: var(--el-green);
    border-color: var(--el-green);
    color: var(--el-green-text);
}
.el-ms-card-more i { font-size: 1rem; }

/* Off-screen add-to-cart anchor. Stays in the DOM so the details
   popup's "Add to Cart" button can programmatically click it via its
   `data-add-to-cart` attribute, but never visible to the user. */
.el-ms-card-cart-hidden,
.el-mship-cart-hidden {
    position: absolute;
    left: -9999px;
    top: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
    border: 0;
    background: transparent;
    padding: 0;
}

.el-ms-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 48px 20px;
    background: var(--el-surface-alt);
    border: 1px dashed var(--el-border);
    border-radius: var(--el-radius);
    color: var(--el-text-muted);
    font-size: 0.95rem;
}
.el-ms-empty i { font-size: 1.3rem; margin-right: 6px; vertical-align: -2px; }

/* ── Comparison table ──────────────────────────────────────────────── */
.el-ms-compare-wrap {
    background: #ffffff;
    border: none;
    border-radius: var(--el-radius-lg);
    overflow-x: auto;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft);
}
.el-ms-compare-wrap:hover { box-shadow: var(--el-glow-hover); }
html.night-mode .el-ms-compare-wrap {
    background: #12141b;
}

.el-ms-compare {
    width: 100%;
    border-collapse: collapse;
    min-width: 640px;
}
.el-ms-compare thead th {
    --col-hue: var(--club-accent);
    background: color-mix(in srgb, var(--col-hue) 8%, #ffffff);
    color: var(--el-text);
    font-weight: 700;
    font-size: 0.86rem;
    text-align: left;
    padding: 18px 16px;
    border-bottom: 2px solid var(--col-hue);
    position: sticky;
    top: 0;
    z-index: 1;
}
.el-ms-compare thead th:first-child {
    background: var(--el-surface-alt);
    border-bottom-color: var(--el-border);
    color: var(--el-text-muted);
    font-size: 0.74rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    /* Frozen-pane: left column stays visible when scrolling the tier
       columns horizontally. Top-left cell needs the higher z-index
       so it layers over both the top (sticky thead) and left
       (sticky tbody th) neighbours. */
    position: sticky;
    left: 0;
    z-index: 3;
    /* Right-edge shadow hints that more content is scrollable. */
    box-shadow: 4px 0 8px -4px rgba(2, 12, 146, 0.15);
}
html.night-mode .el-ms-compare thead th {
    background: color-mix(in srgb, var(--col-hue) 18%, #0a0a0f);
}
html.night-mode .el-ms-compare thead th:first-child {
    background: #0a0a0f;
    box-shadow: 4px 0 8px -4px rgba(0, 0, 0, 0.55);
}
.el-ms-compare-th {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.el-ms-compare-th i {
    color: var(--col-hue);
    font-size: 1.1rem;
}

/* 2026-07-17 (Tier 3 · 3.2) — Compare-table caption underneath the
   wrap. Explains the "charged per roster" rule the operator wanted
   as a general callout rather than per-row column. */
.el-ms-compare-note {
    margin: 12px 4px 0;
    font-size: 0.86rem;
    color: var(--el-text-muted);
    line-height: 1.5;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    max-width: 720px;
}
.el-ms-compare-note i {
    color: var(--club-accent);
    font-size: 1.05rem;
    margin-top: 2px;
    flex-shrink: 0;
}
html.night-mode .el-ms-compare-note {
    color: rgba(243, 244, 246, 0.75);
}

/* 2026-07-17 (Tier 3 · 3.2) — Scroll-hint on the compare wrap. The
   frozen left column + right-edge shadow already existed for the
   in-table scroll affordance; this puts a subtle "drag / scroll to
   compare more tiers" nudge on wide tables that overflow. Only
   renders on non-mobile where hover is meaningful. */
.el-ms-compare-wrap {
    position: relative;
}
.el-ms-compare-wrap::after {
    content: '';
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 32px;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 100%);
    border-radius: 0 var(--el-radius-lg) var(--el-radius-lg) 0;
    opacity: 0;
    transition: opacity 0.25s var(--el-ease-soft);
}
.el-ms-compare-wrap[data-can-scroll="true"]::after {
    opacity: 1;
}
html.night-mode .el-ms-compare-wrap::after {
    background: linear-gradient(90deg, rgba(18, 20, 27, 0) 0%, rgba(18, 20, 27, 0.85) 100%);
}

.el-ms-compare tbody th {
    text-align: left;
    font-weight: 700;
    font-size: 0.88rem;
    color: var(--el-text);
    padding: 14px 16px;
    background: var(--el-surface-alt);
    border-bottom: 1px solid var(--el-border);
    white-space: nowrap;
    /* Frozen-pane: row headers stick to the left edge when the tier
       columns scroll horizontally. Z-index is one lower than the
       top-left corner cell so they tuck under it cleanly. */
    position: sticky;
    left: 0;
    z-index: 2;
    box-shadow: 4px 0 8px -4px rgba(2, 12, 146, 0.12);
}
.el-ms-compare tbody td {
    padding: 14px 16px;
    font-size: 0.92rem;
    color: var(--el-text);
    border-bottom: 1px solid var(--el-border);
    text-align: center;
    white-space: nowrap;
}
.el-ms-compare tbody tr:hover td,
.el-ms-compare tbody tr:hover th {
    background: color-mix(in srgb, var(--club-accent) 4%, transparent);
}
html.night-mode .el-ms-compare tbody th,
html.night-mode .el-ms-compare tbody td {
    background: #12141b;
    border-bottom-color: rgba(255, 255, 255, 0.06);
    color: var(--el-text);
}
html.night-mode .el-ms-compare tbody th {
    box-shadow: 4px 0 8px -4px rgba(0, 0, 0, 0.5);
}
html.night-mode .el-ms-compare tbody tr:hover td,
html.night-mode .el-ms-compare tbody tr:hover th {
    background: color-mix(in srgb, var(--el-green) 6%, transparent);
}
.el-ms-compare .mdi-check-bold { color: var(--club-accent); font-size: 1.2rem; }
.el-ms-compare .mdi-shield-check-outline { color: var(--club-accent); font-size: 1.2rem; }
html.night-mode .el-ms-compare .mdi-check-bold,
html.night-mode .el-ms-compare .mdi-shield-check-outline { color: var(--el-accent); }

/* ── Three Steps ───────────────────────────────────────────────────── */
.el-ms-steps {
    display: grid;
    grid-template-columns: 1fr auto 1fr auto 1fr;
    align-items: start;
    gap: 20px;
    max-width: 1000px;
    margin: 0 auto;
}
.el-ms-step {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 28px 20px;
}
.el-ms-step-icon {
    width: 76px;
    height: 76px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: color-mix(in srgb, var(--club-accent) 10%, transparent);
    color: var(--club-accent);
    margin-bottom: 18px;
    border: 2px solid color-mix(in srgb, var(--club-accent) 22%, transparent);
    transition: transform 0.32s var(--el-ease-soft);
}
.el-ms-step-icon i { font-size: 2rem; }
.el-ms-step:hover .el-ms-step-icon { transform: scale(1.08); }
html.night-mode .el-ms-step-icon {
    background: color-mix(in srgb, var(--el-green) 12%, transparent);
    color: var(--el-green);
    border-color: color-mix(in srgb, var(--el-green) 32%, transparent);
}
.el-ms-step-title {
    font-size: 1.2rem;
    font-weight: 800;
    color: var(--el-text);
    margin: 0 0 8px;
}
.el-ms-step p {
    font-size: 0.92rem;
    color: var(--el-text-muted);
    line-height: 1.55;
    max-width: 260px;
    margin: 0;
}

.el-ms-step-line {
    width: 48px;
    height: 2px;
    background: linear-gradient(90deg, var(--el-border), var(--club-accent), var(--el-border));
    margin-top: 62px;
    align-self: start;
}
html.night-mode .el-ms-step-line {
    background: linear-gradient(90deg, rgba(255,255,255,0.08), var(--el-green), rgba(255,255,255,0.08));
}

.el-ms-steps-cta {
    text-align: center;
    margin-top: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}
.el-ms-steps-cta .el-btn--cta { padding: 16px 36px; font-size: 1rem; }
.el-ms-steps-login {
    font-size: 0.9rem;
    color: var(--el-text-muted);
    margin: 0;
}
.el-ms-steps-login a {
    color: var(--club-accent);
    font-weight: 700;
    text-decoration: none;
    border-bottom: 1px solid currentColor;
}
.el-ms-steps-login a:hover { color: var(--el-cta); }
html.night-mode .el-ms-steps-login a { color: var(--el-accent); }

@media (max-width: 900px) {
    .el-ms-steps {
        grid-template-columns: 1fr;
    }
    .el-ms-step-line {
        width: 2px;
        height: 36px;
        justify-self: center;
        background: linear-gradient(180deg, var(--el-border), var(--club-accent), var(--el-border));
        margin: 0 auto;
    }
    html.night-mode .el-ms-step-line {
        background: linear-gradient(180deg, rgba(255,255,255,0.08), var(--el-green), rgba(255,255,255,0.08));
    }
    /* Vertical layout: lines draw top → bottom instead of left → right */
    .el-ms-steps .el-ms-step-line {
        transform-origin: top center;
        transform: scaleY(0);
    }
    .el-ms-steps.is-populated .el-ms-step-line {
        transform: scaleY(1);
    }
}

/* ── Steps section: scroll-cascade + icon halo pulse ─────────────────
   `.el-ms-steps` gets `.is-populated` toggled by an IntersectionObserver
   in memberships.js. Each step + its connector line reveal staggered
   left-to-right; once revealed, the icon circle continues to emit a
   slow expanding halo so the section doesn't feel static. */
.el-ms-steps .el-ms-step,
.el-ms-steps .el-ms-step-line {
    opacity: 0;
    transition:
        opacity 0.6s var(--el-ease-soft, cubic-bezier(0.22, 1, 0.36, 1)),
        transform 0.7s var(--el-ease-soft, cubic-bezier(0.22, 1, 0.36, 1));
}
.el-ms-steps .el-ms-step {
    transform: translateY(20px) scale(0.96);
}
.el-ms-steps .el-ms-step-line {
    transform-origin: left center;
    transform: scaleX(0);
}
/* Stagger: step 1 → line 1 → step 2 → line 2 → step 3 */
.el-ms-steps > :nth-child(1) { transition-delay: 0.05s; }
.el-ms-steps > :nth-child(2) { transition-delay: 0.30s; }
.el-ms-steps > :nth-child(3) { transition-delay: 0.45s; }
.el-ms-steps > :nth-child(4) { transition-delay: 0.70s; }
.el-ms-steps > :nth-child(5) { transition-delay: 0.85s; }

.el-ms-steps.is-populated .el-ms-step {
    opacity: 1;
    transform: translateY(0) scale(1);
}
.el-ms-steps.is-populated .el-ms-step-line {
    opacity: 1;
    transform: scaleX(1);
}

/* Icon halo — slow expanding ring of light that fades out, then
   restarts. Lives on a ::after so it doesn't fight the existing hover
   scale on the icon itself. Only runs once the cascade has finished. */
.el-ms-step-icon { position: relative; }
.el-ms-step-icon::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid currentColor;
    opacity: 0;
    pointer-events: none;
}
.el-ms-steps.is-populated .el-ms-step:nth-child(1) .el-ms-step-icon::after { animation: el-ms-step-halo 3.4s ease-out 1.0s infinite; }
.el-ms-steps.is-populated .el-ms-step:nth-child(3) .el-ms-step-icon::after { animation: el-ms-step-halo 3.4s ease-out 1.6s infinite; }
.el-ms-steps.is-populated .el-ms-step:nth-child(5) .el-ms-step-icon::after { animation: el-ms-step-halo 3.4s ease-out 2.2s infinite; }

@keyframes el-ms-step-halo {
    0%   { transform: scale(1);    opacity: 0.55; }
    70%  { transform: scale(1.55); opacity: 0;    }
    100% { transform: scale(1.55); opacity: 0;    }
}

/* Hover bump — also brighten the halo and sharpen the icon circle */
.el-ms-step:hover .el-ms-step-icon {
    box-shadow:
        0 0 0 4px color-mix(in srgb, currentColor 14%, transparent),
        0 0 28px color-mix(in srgb, currentColor 35%, transparent);
}

@media (prefers-reduced-motion: reduce) {
    .el-ms-steps .el-ms-step,
    .el-ms-steps .el-ms-step-line {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .el-ms-step-icon::after { display: none; }
}

/* ── Member Benefits (dark navy block) ─────────────────────────────── */
.el-ms-benefits {
    background: linear-gradient(180deg, var(--el-hero) 0%, var(--el-hero-deep) 100%);
    color: var(--el-text-inv);
    position: relative;
    overflow: hidden;
}
.el-ms-benefits::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 15% 30%, rgba(188, 255, 0, 0.08), transparent 42%),
        radial-gradient(circle at 85% 70%, rgba(125, 211, 252, 0.08), transparent 40%);
    pointer-events: none;
}
.el-ms-benefits > .el-container { position: relative; z-index: 1; }
.el-ms-benefits-eyebrow {
    /* Match how every other section eyebrow reads — a muted variant
       of the section's body text. The benefits section sits on a navy
       bg in day mode and the hero-blue tinted dark surface in night
       mode, both light-on-dark contexts, so the inverse-muted token
       is the right one for both. Previously hardcoded to var(--el-green). */
    color: var(--el-text-inv-muted);
}
.el-ms-benefits-title {
    color: var(--el-text-inv);
}

.el-ms-benefits-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 22px;
    margin-top: 10px;
}
@media (min-width: 900px) {
    .el-ms-benefits-grid { grid-template-columns: repeat(3, 1fr); }
}

.el-ms-benefit {
    position: relative;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(125, 211, 252, 0.10);
    border-radius: var(--el-radius);
    padding: 28px 24px;
    box-shadow: var(--el-glow-idle);
    overflow: hidden;
    isolation: isolate;
    transition:
        transform 0.45s var(--el-ease-soft),
        box-shadow 0.45s var(--el-ease-soft),
        border-color 0.45s var(--el-ease-soft),
        background 0.3s;
}
/* Soft corner glow — radial bloom behind the icon, brightening
   gently to anchor the eye. Lives on a ::before so it sits behind
   the card content but above the card bg. */
.el-ms-benefit::before {
    content: '';
    position: absolute;
    top: -40px;
    left: -40px;
    width: 200px;
    height: 200px;
    background: radial-gradient(circle, color-mix(in srgb, var(--el-accent) 22%, transparent) 0%, transparent 65%);
    opacity: 0.55;
    pointer-events: none;
    z-index: -1;
    transition: opacity 0.5s var(--el-ease-soft), transform 0.6s var(--el-ease-soft);
}
/* Diagonal sheen sweep — only fires on hover. Pre-translated off
   to the upper-left so the sweep enters from there. */
.el-ms-benefit::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(110deg,
        transparent 30%,
        rgba(125, 211, 252, 0.18) 48%,
        rgba(255, 255, 255, 0.08) 50%,
        rgba(125, 211, 252, 0.18) 52%,
        transparent 70%);
    transform: translateX(-130%);
    pointer-events: none;
    z-index: -1;
    transition: transform 0.9s var(--el-ease-soft);
}
.el-ms-benefit:hover {
    transform: translateY(-6px);
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(125, 211, 252, 0.45);
    box-shadow:
        var(--el-glow-hover),
        0 0 32px rgba(125, 211, 252, 0.28);
}
.el-ms-benefit:hover::before {
    opacity: 0.9;
    transform: scale(1.15);
}
.el-ms-benefit:hover::after {
    transform: translateX(130%);
}

/* Cascade reveal — stagger by index when the grid enters viewport.
   IntersectionObserver in memberships.js toggles .is-populated; CSS
   reverses the transform when the class is removed so re-entering
   the section replays the cascade. */
.el-ms-benefits-grid .el-ms-benefit {
    opacity: 0;
    transform: translateY(20px) scale(0.97);
    transition:
        opacity 0.6s var(--el-ease-soft),
        transform 0.7s var(--el-ease-soft),
        box-shadow 0.45s var(--el-ease-soft),
        border-color 0.45s var(--el-ease-soft),
        background 0.3s;
}
.el-ms-benefits-grid .el-ms-benefit:nth-child(1) { transition-delay: 0.05s; }
.el-ms-benefits-grid .el-ms-benefit:nth-child(2) { transition-delay: 0.13s; }
.el-ms-benefits-grid .el-ms-benefit:nth-child(3) { transition-delay: 0.21s; }
.el-ms-benefits-grid .el-ms-benefit:nth-child(4) { transition-delay: 0.29s; }
.el-ms-benefits-grid .el-ms-benefit:nth-child(5) { transition-delay: 0.37s; }
.el-ms-benefits-grid .el-ms-benefit:nth-child(6) { transition-delay: 0.45s; }
.el-ms-benefits-grid.is-populated .el-ms-benefit {
    opacity: 1;
    transform: translateY(0) scale(1);
}

/* Icon — slow continuous pulse on a 4s loop, phase-offset per card
   so the row stays alive without feeling synced. */
.el-ms-benefit-icon {
    transition: transform 0.32s var(--el-ease-soft), box-shadow 0.32s var(--el-ease-soft);
}
.el-ms-benefits-grid.is-populated .el-ms-benefit:nth-child(1) .el-ms-benefit-icon { animation: el-ms-benefit-pulse 4s ease-in-out 0.6s infinite; }
.el-ms-benefits-grid.is-populated .el-ms-benefit:nth-child(2) .el-ms-benefit-icon { animation: el-ms-benefit-pulse 4s ease-in-out 1.2s infinite; }
.el-ms-benefits-grid.is-populated .el-ms-benefit:nth-child(3) .el-ms-benefit-icon { animation: el-ms-benefit-pulse 4s ease-in-out 1.8s infinite; }
.el-ms-benefits-grid.is-populated .el-ms-benefit:nth-child(4) .el-ms-benefit-icon { animation: el-ms-benefit-pulse 4s ease-in-out 2.4s infinite; }
.el-ms-benefits-grid.is-populated .el-ms-benefit:nth-child(5) .el-ms-benefit-icon { animation: el-ms-benefit-pulse 4s ease-in-out 3.0s infinite; }
.el-ms-benefits-grid.is-populated .el-ms-benefit:nth-child(6) .el-ms-benefit-icon { animation: el-ms-benefit-pulse 4s ease-in-out 3.6s infinite; }
@keyframes el-ms-benefit-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--el-accent) 20%, transparent); }
    50%      { box-shadow: 0 0 0 8px color-mix(in srgb, var(--el-accent) 0%,  transparent); }
}
.el-ms-benefit:hover .el-ms-benefit-icon {
    transform: scale(1.08);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--el-accent) 22%, transparent);
}

@media (prefers-reduced-motion: reduce) {
    .el-ms-benefits-grid .el-ms-benefit {
        opacity: 1;
        transform: none;
        transition: background 0.3s, box-shadow 0.3s;
    }
    .el-ms-benefit::after { display: none; }
    .el-ms-benefit-icon { animation: none !important; }
}
.el-ms-benefit-icon {
    width: 56px;
    height: 56px;
    border-radius: 14px;
    display: grid;
    place-items: center;
    /* Sky-blue accent — replaces the previous tennis-ball green, matches
       every other accent treatment on the bespoke site (icons, links,
       active states use --el-accent across the board). */
    background: color-mix(in srgb, var(--el-accent) 14%, transparent);
    color: var(--el-accent);
    margin-bottom: 16px;
}
.el-ms-benefit-icon i { font-size: 1.6rem; }
.el-ms-benefit h3 {
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--el-text-inv);
    margin: 0 0 8px;
}
.el-ms-benefit p {
    font-size: 0.92rem;
    color: var(--el-text-inv-muted);
    line-height: 1.6;
    margin: 0;
}

.el-ms-benefits-cta {
    text-align: center;
    margin-top: 40px;
}
/* The Member Benefits section already has a green terminal CTA at
   the page bottom (Become a Member in the Ready-to-Join card), so
   this in-section "Join Our Community" button steps down to a solid
   white pill with navy text — supports rather than competes. */
.el-ms-join-btn {
    background: #ffffff;
    color: var(--el-hero);
    border: 2px solid #ffffff;
    padding: 14px 36px;
    font-weight: 800;
    letter-spacing: 0.02em;
    transition: transform 0.2s, box-shadow 0.3s;
}
.el-ms-join-btn:hover {
    background: rgba(255, 255, 255, 0.92);
    border-color: rgba(255, 255, 255, 0.92);
    transform: translateY(-2px);
    box-shadow: 0 10px 30px rgba(255, 255, 255, 0.25);
}

/* ── FAQ + Ready-to-Join 2-col ─────────────────────────────────────── */
.el-ms-faq-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: clamp(28px, 5vw, 60px);
    align-items: start;
}
@media (max-width: 900px) {
    .el-ms-faq-grid { grid-template-columns: 1fr; }
}

.el-ms-faq .el-section-title { margin-bottom: 28px; }

/* Ready-to-Join card — sticky aside */
.el-ms-ready {
    background: linear-gradient(180deg, var(--el-hero) 0%, var(--el-hero-deep) 100%);
    color: var(--el-text-inv);
    border-radius: var(--el-radius-lg);
    padding: 40px 32px;
    text-align: center;
    box-shadow: var(--el-shadow);
    position: sticky;
    top: 90px;
    overflow: hidden;
}
.el-ms-ready::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 50% 0%, rgba(188, 255, 0, 0.12), transparent 60%);
    pointer-events: none;
}
/* Hover sheen sweep — same diagonal sky-blue light sweep used on the
   benefit cards, pre-translated off to the upper-left so the sweep
   only enters on hover. */
.el-ms-ready::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(110deg,
        transparent 30%,
        rgba(125, 211, 252, 0.18) 48%,
        rgba(255, 255, 255, 0.10) 50%,
        rgba(125, 211, 252, 0.18) 52%,
        transparent 70%);
    transform: translateX(-130%);
    pointer-events: none;
    transition: transform 1s var(--el-ease-soft);
}
.el-ms-ready:hover::after {
    transform: translateX(130%);
}
.el-ms-ready > * { position: relative; z-index: 1; }

.el-ms-ready-avatar {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    margin: 0 auto 18px;
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, 0.08);
    border: 2px solid rgba(255, 255, 255, 0.2);
    padding: 8px;
}
.el-ms-ready-avatar img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    border-radius: 50%;
}
.el-ms-ready-title {
    font-size: 1.7rem;
    font-weight: 800;
    color: var(--el-text-inv);
    margin: 0 0 6px;
    letter-spacing: -0.01em;
}
.el-ms-ready-sub {
    font-size: 0.95rem;
    color: var(--el-text-inv-muted);
    margin: 0 0 22px;
}
.el-ms-ready-sub span { color: var(--el-green); font-weight: 800; }

.el-ms-ready-list {
    list-style: none;
    padding: 0;
    margin: 0 0 22px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: center;
}
.el-ms-ready-list li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.95rem;
}
.el-ms-ready-list li i {
    color: var(--el-accent);
    font-size: 1.15rem;
    text-shadow: 0 0 12px rgba(125, 211, 252, 0.45);
}
.el-ms-ready-list a {
    color: var(--el-text-inv);
    text-decoration: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.3);
    transition: border-color 0.2s, color 0.2s;
}
.el-ms-ready-list a:hover {
    color: var(--el-accent);
    border-color: var(--el-accent);
}

.el-ms-ready-cta {
    background: var(--el-green) !important;
    color: var(--el-green-text) !important;
    border: 2px solid var(--el-green) !important;
    padding: 14px 28px;
    width: 100%;
    justify-content: center;
    font-weight: 800;
    letter-spacing: 0.02em;
    margin-bottom: 14px;
}
.el-ms-ready-cta:hover {
    background: #a6e800 !important;
    border-color: #a6e800 !important;
    transform: translateY(-2px);
    box-shadow: 0 10px 30px rgba(188, 255, 0, 0.3);
}
.el-ms-ready-contact {
    display: inline-block;
    color: var(--el-text-inv-muted);
    font-size: 0.88rem;
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: color 0.2s, border-color 0.2s;
}
.el-ms-ready-contact:hover {
    color: var(--el-green);
    border-bottom-color: var(--el-green);
}

/* ── Smaller-viewport tweaks ───────────────────────────────────────── */
@media (max-width: 600px) {
    .el-ms-card { padding: 24px 20px 20px; }
    .el-ms-card-name { font-size: 1.08rem; }
    .el-ms-card-summary { font-size: 0.9rem; }
    .el-ms-benefit { padding: 24px 20px; }
    .el-ms-ready { padding: 32px 24px; position: static; }
}

/* ── FAQ intro "ask the committee" link ─────────────────────────────── */
.el-ms-faq .el-section-sub {
    margin-top: 14px;
}
.el-ms-faq-ask {
    color: var(--club-accent);
    font-weight: 700;
    text-decoration: none;
    border-bottom: 1px solid currentColor;
    white-space: nowrap;
}
.el-ms-faq-ask:hover { color: var(--el-cta); }
html.night-mode .el-ms-faq-ask { color: var(--el-accent); }

/* ── FAQ-embedded closer ─────────────────────────────────────────────
   Stats + tagline now live INSIDE the FAQ column (below the accordion)
   so the content isn't duplicated by a separate closer banner. CTAs
   (Become a Member / Contact the Committee) stay on the sticky
   Ready-to-Join aside to the right — no redundant buttons.

   Styling stays subtle to match the FAQ accordion's light surface —
   a muted card with an accent divider and the green numerals carrying
   the visual weight. */
.el-ms-faq-closer {
    margin-top: 36px;
    padding-top: 28px;
    border-top: 1px dashed var(--el-border);
    color: var(--el-text);
}
.el-ms-faq-closer-eyebrow {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    margin-bottom: 10px;
}
.el-ms-faq-closer-title {
    font-size: clamp(1.3rem, 2.4vw, 1.7rem);
    font-weight: 800;
    color: var(--el-text);
    letter-spacing: -0.015em;
    line-height: 1.2;
    margin: 0 0 10px;
}
.el-ms-faq-closer-sub {
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--el-text-muted);
    margin: 0 0 22px;
    max-width: 560px;
}
.el-ms-faq-closer-sub span { color: var(--club-accent); font-weight: 800; }
html.night-mode .el-ms-faq-closer-sub span { color: var(--el-accent); }

.el-ms-faq-closer-stats {
    display: flex;
    gap: clamp(16px, 3vw, 36px);
    flex-wrap: wrap;
}
.el-ms-faq-closer-stat { min-width: 110px; }
.el-ms-faq-closer-stat-value {
    font-size: clamp(1.6rem, 2.8vw, 2rem);
    font-weight: 900;
    line-height: 1;
    color: var(--club-accent);
    letter-spacing: -0.02em;
    margin-bottom: 4px;
}
html.night-mode .el-ms-faq-closer-stat-value { color: var(--el-accent); }
.el-ms-faq-closer-stat-label {
    font-size: 0.8rem;
    color: var(--el-text-muted);
    letter-spacing: 0.02em;
}

/* ══════════════════════════════════════════════════════════════════════
   SPONSORS PAGE

   Shared chrome with the rest of the site:
   • `.el-sp-grid` renders a responsive wall of sponsor cards that prefer
     the committee-supplied logo and fall back to the cover image.
   • `.el-sp-why` is a dark navy block mirroring the Memberships
     Benefits block — the green flourish lives on the stats column so
     the numbers read as the headline while the benefits grid supports.
   • Tiers mirror the three-step card pattern from the Memberships page.
   • `.el-sp-form` reuses the `.el-contact-form` shell so the submit
     pipeline + success toast pill carries across without duplicating
     CSS. Only the two-column surround is new.
   ══════════════════════════════════════════════════════════════════════ */

/* Hero action row (same shape as other pages with double CTA) */
.el-sp-hero-note {
    display: inline-flex;
    gap: 8px;
    color: var(--el-text-inv-muted);
    font-size: 0.9rem;
}

/* ── Active sponsorship drives (Phase 5 Chunk 5a, 2026-08-19) ─────────
   Renders above the sponsor roster when active drives exist. Uses
   --el-* tokens so dark + light modes both work with the club-site
   night-mode toggle. */
.el-sp-drives {
    padding-block: 60px 40px;
}
.el-sp-drives-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 20px;
    margin-top: 24px;
}
.el-sp-drive-card {
    background: var(--el-surface-alt);
    border: 1px solid var(--el-border);
    border-radius: 14px;
    padding: 20px 22px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    transition: transform 0.15s ease-out, border-color 0.15s;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}
.el-sp-drive-card:hover {
    transform: translateY(-3px);
    border-color: var(--el-accent);
}
.el-sp-drive-title {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--el-text);
    line-height: 1.3;
    margin: 0;
}
.el-sp-drive-tagline {
    font-size: 0.88rem;
    color: color-mix(in srgb, var(--el-text) 65%, transparent);
    line-height: 1.5;
    margin: 0;
}
.el-sp-drive-progress-nums {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}
.el-sp-drive-raised {
    font-size: 1.55rem;
    font-weight: 800;
    color: var(--el-text);
    font-variant-numeric: tabular-nums;
}
.el-sp-drive-target {
    font-size: 0.85rem;
    color: color-mix(in srgb, var(--el-text) 60%, transparent);
}
/* Sponsors-list 3-band bar — mirrors the detail-page thermometer with a
   compact 10px height. Uses the same --el-fund-* tokens so a design
   change ripples to both surfaces. */
.el-sp-drive-bar {
    display: flex;
    height: 10px;
    background: var(--el-fund-track);
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid var(--el-border);
}
.el-sp-drive-bar-fill,
.el-sp-drive-bar-pledged {
    height: 100%;
    transition: width 0.5s ease-out;
}
.el-sp-drive-bar-fill    { background: var(--el-fund-paid); }
.el-sp-drive-bar-pledged {
    background:
        repeating-linear-gradient(
            45deg,
            var(--el-fund-pledged) 0,
            var(--el-fund-pledged) 5px,
            color-mix(in srgb, var(--el-fund-pledged) 78%, black) 5px,
            color-mix(in srgb, var(--el-fund-pledged) 78%, black) 10px
        );
}
.el-sp-drive-pledged-meta { color: color-mix(in srgb, var(--el-text) 75%, transparent); }
.el-sp-drive-pledged-meta .mdi { color: var(--el-fund-pledged); margin-right: 3px; }
.el-sp-drive-pledged-meta strong { color: var(--el-text); }
.el-sp-drive-meta {
    display: flex;
    gap: 14px;
    font-size: 0.8rem;
    color: color-mix(in srgb, var(--el-text) 60%, transparent);
    flex-wrap: wrap;
}
.el-sp-drive-meta strong {
    color: var(--el-text);
    font-weight: 700;
}
.el-sp-drive-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 18px;
    background: var(--el-accent-strong);
    color: #ffffff;
    border-radius: 24px;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    transition: background 0.15s, transform 0.1s;
    min-height: 44px;
    align-self: stretch;
    text-align: center;
    margin-top: auto;
}
.el-sp-drive-cta:hover {
    background: var(--el-accent);
    transform: translateY(-1px);
    text-decoration: none;
}
.el-sp-drive-in-kind-hint {
    font-size: 0.75rem;
    color: color-mix(in srgb, var(--el-text) 55%, transparent);
    font-style: italic;
}

@media (max-width: 640px) {
    .el-sp-drives-grid { grid-template-columns: 1fr; }
}

/* ── Drive detail page (/share/drive/:slug, 2026-08-19 rework) ──────
   Native templated-site page (nav + hero + footer + night-mode from the
   shell). This block styles the BODY only — progress card, CTAs,
   purpose section, leaderboard, and the bespoke donate + pledge modals.
   All colours via --el-* tokens so night-mode inherits automatically. */
.el-hero--drive {
    padding-block: 60px 40px;
}
.el-drive-body {
    padding-block: 40px 60px;
}

/* Progress card */
.el-drive-progress {
    background: var(--el-surface-alt);
    border: 1px solid var(--el-border);
    border-radius: 14px;
    padding: 24px 26px;
    margin-bottom: 24px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}
.el-drive-progress-nums {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}
.el-drive-progress-raised {
    font-size: clamp(1.75rem, 5vw, 2.4rem);
    font-weight: 800;
    color: var(--el-text);
    font-variant-numeric: tabular-nums;
}
.el-drive-progress-target {
    color: color-mix(in srgb, var(--el-text) 65%, transparent);
    font-size: 1rem;
}
/* Fundraiser tokens — 3 semantic colours for the paid / pledged / shortfall
   thermometer. Deliberately distinct hues so a glance at the bar tells the
   story: solid brand navy = money in, amber = commitment, muted red-brown =
   still to raise. Night mode uses lighter variants for contrast on the
   #08152e hero background. */
:root {
    --el-fund-paid:      #0b2e6e;   /* deep brand navy — matches --el-accent-strong */
    --el-fund-paid-fg:   #ffffff;
    --el-fund-pledged:   #eab308;   /* amber — future commitment */
    --el-fund-pledged-fg:#1a1a1a;
    --el-fund-short:     #b1454c;   /* muted red-brown — still-to-raise */
    --el-fund-short-fg:  #ffffff;
    --el-fund-track:     rgba(0, 0, 0, 0.08);
}
html.night-mode {
    --el-fund-paid:      #3d6cc9;   /* lighter navy on dark for contrast */
    --el-fund-pledged:   #f4c542;
    --el-fund-short:     #d16972;
    --el-fund-track:     rgba(255, 255, 255, 0.08);
}

/* 3-band thermometer bar */
.el-drive-bar {
    display: flex;
    height: 16px;
    background: var(--el-fund-track);
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--el-border);
}
.el-drive-bar-fill,
.el-drive-bar-pledged,
.el-drive-bar-shortfall {
    height: 100%;
    transition: width 0.6s ease-out;
}
.el-drive-bar-fill      { background: var(--el-fund-paid); }
.el-drive-bar-pledged   {
    /* Solid amber + subtle diagonal stripe so it reads as "committed but not banked" */
    background:
        repeating-linear-gradient(
            45deg,
            var(--el-fund-pledged) 0,
            var(--el-fund-pledged) 8px,
            color-mix(in srgb, var(--el-fund-pledged) 78%, black) 8px,
            color-mix(in srgb, var(--el-fund-pledged) 78%, black) 16px
        );
}
.el-drive-bar-shortfall { background: transparent; }   /* Track shows through — no visual weight on "empty" */

/* Header — CURRENT TOTAL / GOAL split */
.el-drive-progress-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 12px;
}
.el-drive-progress-block { display: flex; flex-direction: column; gap: 4px; }
.el-drive-progress-block--right { align-items: flex-end; text-align: right; }
.el-drive-progress-eyebrow {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--el-text) 55%, transparent);
}
.el-drive-progress-raised {
    font-size: clamp(1.75rem, 5vw, 2.4rem);
    font-weight: 800;
    color: var(--el-fund-paid);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.el-drive-progress-target-big {
    font-size: clamp(1.3rem, 4vw, 1.7rem);
    font-weight: 700;
    color: var(--el-fund-short);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* Three metric tiles */
.el-drive-tiles {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-top: 12px;
}
.el-drive-tile {
    padding: 12px 10px;
    border-radius: 8px;
    text-align: center;
    color: #fff;
}
.el-drive-tile-label {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    opacity: 0.9;
}
.el-drive-tile-pct {
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    margin-top: 2px;
}
.el-drive-tile-amount {
    font-size: 0.82rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    opacity: 0.9;
}
.el-drive-tile--paid     { background: var(--el-fund-paid);    color: var(--el-fund-paid-fg); }
.el-drive-tile--pledged  { background: var(--el-fund-pledged); color: var(--el-fund-pledged-fg); }
.el-drive-tile--shortfall{ background: var(--el-fund-short);   color: var(--el-fund-short-fg); }

@media (max-width: 480px) {
    .el-drive-tile-pct { font-size: 1.25rem; }
    .el-drive-tile-amount { font-size: 0.75rem; }
    .el-drive-tile { padding: 10px 6px; }
}
.el-drive-progress-meta {
    display: flex;
    gap: 20px;
    margin-top: 14px;
    font-size: 0.9rem;
    color: color-mix(in srgb, var(--el-text) 65%, transparent);
    flex-wrap: wrap;
}
.el-drive-progress-meta strong { color: var(--el-text); font-weight: 700; }
.el-drive-in-kind-hint {
    margin-top: 10px;
    font-size: 0.82rem;
    color: color-mix(in srgb, var(--el-text) 55%, transparent);
    font-style: italic;
}

/* CTA row */
.el-drive-ctas {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 12px;
    margin-bottom: 24px;
}
.el-drive-cta {
    justify-content: center;
    padding: 14px 20px;
    font-size: 1rem;
    min-height: 52px;
}
.el-drive-cta.is-disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
.el-drive-cta.is-disabled small {
    font-weight: 400;
    opacity: 0.75;
    margin-left: 4px;
}

/* Purpose + leaderboard sections */
.el-drive-section {
    background: var(--el-surface-alt);
    border: 1px solid var(--el-border);
    border-radius: 14px;
    padding: 20px 24px;
    margin-bottom: 20px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}
.el-drive-section .el-section-eyebrow {
    margin-bottom: 10px;
}
.el-drive-purpose {
    color: var(--el-text);
    line-height: 1.6;
    font-size: 1rem;
}
.el-drive-purpose p:first-child { margin-top: 0; }
.el-drive-purpose p:last-child  { margin-bottom: 0; }

.el-drive-empty-lb {
    color: color-mix(in srgb, var(--el-text) 60%, transparent);
    text-align: center;
    padding: 16px 8px;
    font-style: italic;
}

/* Leaderboard rows */
.el-drive-lb { display: flex; flex-direction: column; gap: 6px; }
.el-drive-lb-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 14px;
    background: color-mix(in srgb, var(--el-text) 4%, transparent);
    border-radius: 8px;
    font-size: 0.95rem;
}
.el-drive-lb-donor {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--el-text);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.el-drive-lb-donor.is-anon { color: color-mix(in srgb, var(--el-text) 60%, transparent); font-style: italic; }
.el-drive-lb-when {
    font-weight: 400;
    color: color-mix(in srgb, var(--el-text) 50%, transparent);
    font-size: 0.82rem;
}
.el-drive-lb-amount {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    color: var(--el-text);
}
.el-drive-kind-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 8px;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    font-weight: 700;
    background: color-mix(in srgb, var(--el-accent) 20%, transparent);
    color: var(--el-accent-strong);
    flex-shrink: 0;
}

/* Info / success / error banners
   Solid backgrounds — no transparent color-mix into transparent — so the
   banner reads as its own surface inside the modal, not a tinted overlay
   on whatever sits behind (gotcha #51). */
.el-drive-info, .el-drive-success, .el-drive-error {
    padding: 12px 16px;
    border-radius: 10px;
    font-size: 0.92rem;
    margin: 8px 0 20px;
    line-height: 1.5;
}
.el-drive-info {
    background: color-mix(in srgb, var(--el-accent) 12%, var(--el-modal-panel));
    color: var(--el-text);
    border: 1px solid color-mix(in srgb, var(--el-accent) 35%, var(--el-border));
}
.el-drive-success {
    background: rgba(34, 197, 94, 0.14);
    color: #14804a;
    border: 1px solid rgba(34, 197, 94, 0.35);
}
html.night-mode .el-drive-success {
    background: rgba(34, 197, 94, 0.20);
    color: #4ade80;
}
.el-drive-error {
    background: rgba(239, 68, 68, 0.12);
    color: #b91c1c;
    border: 1px solid rgba(239, 68, 68, 0.35);
}
html.night-mode .el-drive-error {
    background: rgba(239, 68, 68, 0.18);
    color: #f87171;
}

/* Modal (donate + pledge — same shell)
   Backdrop is intentionally near-opaque + heavily blurred so page content
   never leaks visually through the modal envelope (gotcha #51 territory —
   cards behind a translucent overlay read as "the modal itself is
   transparent"). Ceiling is 0.92 not 1.0 so we keep a whisper of depth
   from the page underneath — pure black behind reads flatter. */
.el-drive-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.92);
    -webkit-backdrop-filter: blur(20px);
    backdrop-filter: blur(20px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 500;
    padding: 20px;
    animation: el-drive-fadein 0.15s ease-out;
}
@keyframes el-drive-fadein { from { opacity: 0; } to { opacity: 1; } }
/* Modal panel token — separate from --el-surface-alt because on night mode
   --el-surface-alt is #08152e (same navy as hero), which makes the modal
   blend into the hero visually + read as "transparent" even when solid.
   Panel token is a distinct lighter navy on dark so the modal always
   stands out from anything behind it. */
:root {
    --el-modal-panel: #ffffff;
    --el-modal-panel-elev: #f5f7fb;
}
:root:not([data-theme="light"]) {
    /* Dark systems that haven't chosen a mode — matches the html.night-mode branch. */
}
html.night-mode {
    --el-modal-panel: #132852;
    --el-modal-panel-elev: #0e2044;
}
.el-drive-modal {
    background-color: var(--el-modal-panel);
    background-image: none;
    color: var(--el-text);
    border: 1px solid var(--el-border);
    border-radius: 16px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.65);
    width: 100%;
    max-width: 500px;
    max-height: 92dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: el-drive-slidein 0.2s ease-out;
    isolation: isolate;
}
@keyframes el-drive-slidein { from { transform: translateY(20px); opacity: 0; } to { transform: none; opacity: 1; } }
.el-drive-modal-head {
    padding: 14px 20px;
    background: var(--el-modal-panel-elev);
    border-bottom: 1px solid var(--el-border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}
.el-drive-modal-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--el-text);
}
.el-drive-modal-title .mdi {
    color: var(--el-accent-strong);
    margin-right: 4px;
}
.el-drive-modal-close {
    background: transparent;
    border: none;
    color: color-mix(in srgb, var(--el-text) 60%, transparent);
    font-size: 1.4rem;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    line-height: 1;
}
.el-drive-modal-close:hover {
    background: color-mix(in srgb, var(--el-text) 8%, transparent);
    color: var(--el-text);
}
.el-drive-modal-body {
    padding: 18px 20px;
    background: var(--el-modal-panel);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.el-drive-modal-foot {
    padding: 12px 20px;
    border-top: 1px solid var(--el-border);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    background: var(--el-modal-panel-elev);
}

/* Signed-in banner inside donate + pledge modals — thin strip with a
   checkmark + "Not you?" clear link. Uses accent-tinted panel so it
   reads as "you're identified" without stealing focus from the form. */
.el-drive-member-banner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    margin: 0 0 8px;
    background: color-mix(in srgb, var(--el-accent) 10%, var(--el-modal-panel));
    border: 1px solid color-mix(in srgb, var(--el-accent) 30%, var(--el-border));
    border-radius: 8px;
    font-size: 0.85rem;
    color: var(--el-text);
}
.el-drive-member-banner .mdi {
    color: var(--el-accent-strong);
    margin-right: 4px;
}
.el-drive-member-clear {
    background: transparent;
    border: none;
    color: var(--el-accent-strong);
    font-weight: 600;
    font-size: 0.82rem;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.el-drive-member-clear:hover {
    background: color-mix(in srgb, var(--el-accent) 12%, var(--el-modal-panel));
    text-decoration: none;
}

.el-drive-field { display: flex; flex-direction: column; gap: 5px; }
.el-drive-field-label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--el-text);
    display: flex;
    align-items: baseline;
    gap: 6px;
}
.el-drive-field-hint {
    font-size: 0.75rem;
    color: color-mix(in srgb, var(--el-text) 60%, transparent);
    line-height: 1.4;
}
.el-required { color: #ef4444; }
.el-drive-input {
    padding: 10px 12px;
    background: var(--el-surface);
    border: 1px solid var(--el-border);
    border-radius: 8px;
    color: var(--el-text);
    font-size: 0.95rem;
    font-family: inherit;
    min-height: 44px;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.el-drive-input:focus {
    outline: none;
    border-color: var(--el-accent-strong);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--el-accent-strong) 25%, transparent);
}
.el-drive-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 0.9rem;
    color: var(--el-text);
}
.el-drive-checkbox input {
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: var(--el-accent-strong);
}

@media (max-width: 640px) {
    .el-drive-ctas { grid-template-columns: 1fr; }
    .el-drive-progress { padding: 18px; }
    .el-drive-section { padding: 16px; }
}

/* ── Sponsor roster section — locked to light surface ────────────────
   Keeps the logo wall on the clean light-blue/white backdrop even in
   night mode so brand marks (usually drawn for light backgrounds)
   stay legible. The rest of the page continues to invert in dark
   mode; only the roster block opts out. */
.el-sp-roster {
    background: var(--el-surface);
    color: var(--el-text);
}
/* Night-mode sponsors section follows the page background like every
   other section. The original override locked it to light blue to keep
   sponsor logos "legible", but the cards themselves are white so the
   logos already pop. Removing the lock makes the page feel coherent
   instead of having one bright stripe in the middle of dark mode. */

/* ── Sponsor grid ──────────────────────────────────────────────────── */
.el-sp-grid {
    display: grid;
    /* Bigger cards — min bumped from 240 -> 300 so cards fill the
       container at ~3-per-row on wide screens, 2-per-row on tablets,
       and stack on mobile. */
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 28px;
}
@media (min-width: 1100px) {
    .el-sp-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 720px) and (max-width: 1099px) {
    .el-sp-grid { grid-template-columns: repeat(2, 1fr); }
}

.el-sp-card {
    position: relative;
    background: #ffffff;
    border: none;
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition: transform 0.28s var(--el-ease-soft), box-shadow 0.28s var(--el-ease-soft);
}
.el-sp-card:hover {
    transform: translateY(-6px);
    box-shadow: var(--el-glow-hover);
}
/* Night-mode sponsor cards now match the rest of the page — dark card
   body to mirror the coach-card treatment (#12141b). The .el-sp-card-media
   --logo block stays white at the dedicated rule below so sponsor logos
   (which are designed for light backgrounds) remain legible. */
html.night-mode .el-sp-card {
    background: #12141b;
}
/* Navy text → sky-blue accent in night mode so titles stay legible
   against the dark card background. Matches the .el-italic accent
   used in section headings. */
html.night-mode .el-sp-card-title {
    color: var(--el-accent);
}
html.night-mode .el-sp-card-sub {
    color: rgba(255, 255, 255, 0.62);
}
html.night-mode .el-sp-card-web {
    color: var(--el-accent);
}
html.night-mode .el-sp-card-media {
    border-bottom-color: rgba(255, 255, 255, 0.08);
}
.el-sp-card--pinned {
    border-color: var(--club-accent);
}
html.night-mode .el-sp-card--pinned {
    border-color: var(--el-green);
}

.el-sp-card-link {
    display: flex;
    flex-direction: column;
    height: 100%;
    text-decoration: none;
    color: inherit;
}
.el-sp-pin {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 2;
    background: var(--el-green);
    color: var(--el-green-text);
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 4px 10px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    box-shadow: 0 4px 12px rgba(188, 255, 0, 0.4);
}
.el-sp-pin i { font-size: 0.78rem; }

.el-sp-card-media {
    aspect-ratio: 16 / 10;
    background: var(--el-surface-alt);
    display: grid;
    place-items: center;
    overflow: hidden;
    border-bottom: 1px solid var(--el-border);
}
.el-sp-card-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s var(--el-ease-soft);
}
.el-sp-card:hover .el-sp-card-media img {
    transform: scale(1.04);
}
/* Logo-first variant: use `contain` and a generous pad so wordmarks
   don't bleed to the edge. */
.el-sp-card-media--logo {
    background: #ffffff;
    padding: clamp(24px, 4vw, 40px);
}
.el-sp-card-media--logo img {
    object-fit: contain;
}
html.night-mode .el-sp-card-media--logo {
    background: #ffffff;   /* Keep logo-safe white behind logos even at night */
}

.el-sp-card-initial {
    width: 72px; height: 72px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--club-accent) 12%, transparent);
    color: var(--club-accent);
    font-size: 2rem;
    font-weight: 800;
    display: grid;
    place-items: center;
}

.el-sp-card-body {
    padding: 22px 24px 26px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.el-sp-card-title {
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--el-text);
    margin: 0;
    line-height: 1.25;
}
.el-sp-card-sub {
    font-size: 0.86rem;
    color: var(--el-text-muted);
    margin: 0;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.el-sp-card-web {
    margin-top: 8px;
    font-size: 0.82rem;
    color: var(--club-accent);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    letter-spacing: 0;
    word-break: break-word;
}
.el-sp-card-web i { font-size: 0.98rem; }
.el-sp-card-web--muted { color: var(--el-text-muted); }
html.night-mode .el-sp-card-web { color: var(--el-accent); }

.el-sp-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 48px 24px;
    background: var(--el-surface-alt);
    border: 1px dashed var(--el-border);
    border-radius: var(--el-radius);
    color: var(--el-text-muted);
}
.el-sp-empty i { font-size: 2.4rem; color: var(--club-accent); display: block; margin-bottom: 10px; }
.el-sp-empty h3 { margin: 0 0 6px; color: var(--el-text); font-size: 1.15rem; font-weight: 800; }
.el-sp-empty p { margin: 0; font-size: 0.92rem; }
.el-sp-empty a { color: var(--club-accent); font-weight: 700; }
html.night-mode .el-sp-empty i { color: var(--el-accent); }
html.night-mode .el-sp-empty a { color: var(--el-accent); }

/* ── Why-Partner block (dark navy) ─────────────────────────────────── */
.el-sp-why {
    background: linear-gradient(180deg, var(--el-hero) 0%, var(--el-hero-deep) 100%);
    color: var(--el-text-inv);
    position: relative;
    overflow: hidden;
}
.el-sp-why::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 15% 20%, rgba(188, 255, 0, 0.08), transparent 42%),
        radial-gradient(circle at 85% 80%, rgba(125, 211, 252, 0.08), transparent 40%);
    pointer-events: none;
}
.el-sp-why > .el-container { position: relative; z-index: 1; }
.el-sp-why-eyebrow { color: var(--el-green); }
.el-sp-why-title   { color: var(--el-text-inv); }
.el-sp-why-sub     { color: var(--el-text-inv-muted); }

/* Stats row — big green numbers, supporting white copy */
.el-sp-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 18px;
    margin: 24px 0 56px;
}
@media (min-width: 900px) {
    .el-sp-stats { grid-template-columns: repeat(4, 1fr); }
}
.el-sp-stat {
    background: rgba(255, 255, 255, 0.05);
    border: none;
    border-radius: var(--el-radius);
    padding: 24px 20px;
    text-align: center;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.3s, background 0.3s, transform 0.3s var(--el-ease-soft);
}
.el-sp-stat:hover {
    background: rgba(255, 255, 255, 0.07);
    box-shadow: var(--el-glow-hover);
    transform: translateY(-3px);
}
.el-sp-stat-value {
    font-size: clamp(2.2rem, 4.2vw, 3rem);
    font-weight: 900;
    line-height: 1;
    color: var(--el-green);
    letter-spacing: -0.02em;
    margin-bottom: 8px;
}
.el-sp-stat-label {
    font-size: 0.96rem;
    font-weight: 700;
    color: var(--el-text-inv);
    margin-bottom: 2px;
}
.el-sp-stat-sub {
    font-size: 0.82rem;
    color: var(--el-text-inv-muted);
}

/* Benefits carousel — narrow, one slide at a time. Structure:
     .el-sp-benefits-carousel (outer, overflow VISIBLE so arrows poke
                               outside the track)
       .el-sp-benefits-viewport (overflow HIDDEN — clips the track)
         .el-sp-benefits-track (translateX'd)
   Arrows are positioned using NEGATIVE left/right values so they
   float outside the viewport. The outer wrapper keeps extra room
   on either side so the arrows still fit within the page gutter. */
.el-sp-benefits-carousel {
    position: relative;
    max-width: 880px;           /* track is ~760px, arrows use the extra 120px */
    margin: 0 auto;
    padding: 0 60px;            /* reserves room for the outside arrows */
    overflow: visible;
}
.el-sp-benefits-viewport {
    overflow: hidden;
    border-radius: var(--el-radius);
}
.el-sp-benefits-track {
    display: flex;
    transition: transform 0.6s var(--el-ease-soft);
    will-change: transform;
}
.el-sp-benefit {
    background: rgba(255, 255, 255, 0.04);
    border: none;
    border-radius: var(--el-radius);
    padding: 36px 40px;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.3s, background 0.3s;
}
/* Slide variant only — stretches to fill the carousel shell. */
.el-sp-benefit--slide {
    flex: 0 0 auto;
    min-height: 240px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}
.el-sp-benefit:hover {
    background: rgba(255, 255, 255, 0.06);
    box-shadow: var(--el-glow-hover);
}
.el-sp-benefit-icon {
    width: 64px; height: 64px;
    border-radius: 16px;
    display: grid;
    place-items: center;
    background: rgba(188, 255, 0, 0.14);
    color: var(--el-green);
    margin-bottom: 18px;
}
.el-sp-benefit-icon i { font-size: 1.8rem; }
.el-sp-benefit h3 {
    font-size: 1.2rem;
    font-weight: 800;
    color: var(--el-text-inv);
    margin: 0 0 10px;
    letter-spacing: -0.01em;
}
.el-sp-benefit p {
    margin: 0;
    font-size: 0.95rem;
    color: var(--el-text-inv-muted);
    line-height: 1.6;
}

/* Nav arrows — sit vertically-centred, half inside the track edge.
   Kept small + glassy so they read as controls, not a primary CTA. */
.el-sp-benefits-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px; height: 40px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: var(--el-text-inv);
    font-size: 1.4rem;
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: background 0.2s, border-color 0.2s, transform 0.2s var(--el-ease-soft);
    z-index: 2;
}
.el-sp-benefits-nav:hover {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-green);
    transform: translateY(-50%) scale(1.08);
}
.el-sp-benefits-nav--prev { left: 6px; }
.el-sp-benefits-nav--next { right: 6px; }
.el-sp-benefits-nav i { font-size: 1.6rem; }

@media (max-width: 640px) {
    /* On narrow screens, shrink the outer padding so the carousel
       uses the full width, and move the arrows back INSIDE the
       track where they can float over the card edges. */
    .el-sp-benefits-carousel { padding: 0; }
    .el-sp-benefits-nav--prev { left: 8px; }
    .el-sp-benefits-nav--next { right: 8px; }
}

/* Dots strip below the track */
.el-sp-benefits-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 22px;
}
.el-sp-benefits-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    border: 0;
    padding: 0;
    background: rgba(255, 255, 255, 0.25);
    cursor: pointer;
    transition: background 0.2s, width 0.25s var(--el-ease-soft);
}
.el-sp-benefits-dot:hover { background: rgba(255, 255, 255, 0.45); }
.el-sp-benefits-dot.is-active {
    background: var(--el-green);
    width: 22px;
    border-radius: 999px;
}

@media (max-width: 640px) {
    .el-sp-benefit { padding: 28px 24px; }
    .el-sp-benefits-nav { width: 36px; height: 36px; }
}

/* ── Become a Sponsor — pitch column + form column ─────────────────── */
.el-sp-form-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    gap: clamp(28px, 5vw, 60px);
    align-items: start;
}
@media (max-width: 900px) {
    .el-sp-form-grid { grid-template-columns: 1fr; }
}
.el-sp-form-pitch h2 { margin: 8px 0 16px; }
.el-sp-form-pitch p {
    font-size: 0.98rem;
    color: var(--el-text-muted);
    line-height: 1.6;
    margin: 0 0 18px;
}
.el-sp-checklist {
    list-style: none;
    padding: 0;
    margin: 0 0 26px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.el-sp-checklist li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 0.92rem;
    color: var(--el-text);
    line-height: 1.5;
}
.el-sp-checklist li i {
    color: var(--club-accent);
    font-size: 1.1rem;
    flex-shrink: 0;
    margin-top: 1px;
}
html.night-mode .el-sp-checklist li i { color: var(--el-accent); }

.el-sp-pitch-call {
    background: #ffffff;
    border: 1px solid var(--el-border);
    border-radius: var(--el-radius);
    padding: 18px 20px;
}
html.night-mode .el-sp-pitch-call {
    background: rgba(255, 255, 255, 0.04);
}
.el-sp-pitch-call-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--el-text-muted);
    margin-bottom: 4px;
}
.el-sp-pitch-call-link {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--club-accent);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: gap 0.2s ease;
}
.el-sp-pitch-call-link:hover { gap: 10px; }
html.night-mode .el-sp-pitch-call-link { color: var(--el-accent); }

/* Reuse Contact form chrome — only tweak max-width + padding. */
.el-sp-form {
    max-width: 560px;
    margin-left: auto;
}
@media (max-width: 900px) {
    .el-sp-form { max-width: none; }
}

/* Responsive rhythm tweaks for the Why-Partner block */
@media (max-width: 700px) {
    .el-sp-stat { padding: 20px 16px; }
}

/* ══════════════════════════════════════════════════════════════════════
   COACHING PAGE

   - Hero pills sit under the hero subtitle (3-up horizontal row).
   - Academy spotlight is a 2-col image/body grid, photo left.
   - Coach cards mirror the Your-Coaches mockup — portrait photo,
     name + role, short bio, specialty chips, phone contact line.
     Whole card is clickable (data-open-coach-id is caught by the
     builder's existing handler and opens the coach detail modal).
   - Programmes render as a 2x2 (desktop) grid of large media cards.
   - Final CTA echoes the sponsors/memberships navy closers with a
     two-column layout: copy + contact rows left, decorative SVG right.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Hero pills ──────────────────────────────────────────────────── */
.el-coach-hero-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 22px;
}
.el-coach-hero-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 16px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: var(--el-text-inv);
    font-size: 0.82rem;
    font-weight: 600;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
.el-coach-hero-pill i {
    color: var(--el-accent);
    font-size: 0.96rem;
}

/* ── Academy spotlight ──────────────────────────────────────────── */
.el-coach-academy {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    gap: clamp(28px, 4vw, 56px);
    align-items: center;
}
@media (max-width: 860px) {
    .el-coach-academy { grid-template-columns: 1fr; }
}
.el-coach-academy-photo {
    position: relative;
    aspect-ratio: 4 / 3;
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    transition: box-shadow 0.35s var(--el-ease-soft);
}
.el-coach-academy-photo:hover { box-shadow: var(--el-glow-hover); }
.el-coach-academy-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.el-coach-academy-placeholder {
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, var(--el-surface-alt), var(--el-surface));
    display: grid;
    place-items: center;
    color: var(--el-text-muted);
    font-size: 4rem;
}
.el-coach-academy-body .el-section-title { margin: 6px 0 12px; }
.el-coach-academy-tagline {
    font-size: 1.05rem;
    color: var(--el-text-muted);
    margin: 0 0 18px;
    line-height: 1.55;
}
.el-coach-academy-body p {
    font-size: 0.96rem;
    color: var(--el-text);
    line-height: 1.65;
    margin: 0 0 14px;
}
.el-coach-academy-stats {
    display: flex;
    gap: clamp(20px, 4vw, 40px);
    flex-wrap: wrap;
    margin: 22px 0 26px;
    padding: 18px 0;
    border-top: 1px solid var(--el-border);
    border-bottom: 1px solid var(--el-border);
}
.el-coach-academy-stat-value {
    font-size: 2rem;
    font-weight: 900;
    color: var(--club-accent);
    letter-spacing: -0.02em;
    line-height: 1;
    margin-bottom: 4px;
}
html.night-mode .el-coach-academy-stat-value { color: var(--el-accent); }
.el-coach-academy-stat-label {
    font-size: 0.78rem;
    color: var(--el-text-muted);
    letter-spacing: 0.04em;
}
.el-coach-academy-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

/* ── Coaches grid ───────────────────────────────────────────────── */
.el-coach-section-header { text-align: center; }
.el-coach-section-header .el-section-title,
.el-coach-section-header .el-section-sub { margin-left: auto; margin-right: auto; }
.el-coach-section-header .el-section-sub { max-width: 520px; }

.el-coach-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 28px;
}
@media (min-width: 980px) {
    .el-coach-grid { grid-template-columns: repeat(3, 1fr); }
}

.el-coach-card {
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    padding: 14px;
    display: flex;
    flex-direction: column;
    cursor: pointer;
    box-shadow: var(--el-glow-idle);
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s var(--el-ease-soft);
}
html.night-mode .el-coach-card { background: #12141b; }
.el-coach-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--el-glow-hover);
}
.el-coach-card:focus-visible {
    outline: 3px solid var(--club-accent);
    outline-offset: 4px;
}

.el-coach-card-photo {
    aspect-ratio: 1 / 1;
    background: linear-gradient(135deg, #d9e5cf, #c7d4be);
    border-radius: var(--el-radius);
    overflow: hidden;
    display: grid;
    place-items: center;
    margin-bottom: 18px;
    box-shadow: var(--el-shadow-sm);
}
html.night-mode .el-coach-card-photo {
    background: linear-gradient(135deg, #1a1d24, #12141b);
}
.el-coach-card-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.el-coach-card-photo-fallback {
    color: rgba(2, 12, 146, 0.3);
    font-size: 5rem;
}
html.night-mode .el-coach-card-photo-fallback { color: rgba(255, 255, 255, 0.2); }

.el-coach-card-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 0 4px;
}
.el-coach-card-name {
    font-size: 1.2rem;
    font-weight: 800;
    color: var(--el-text);
    margin: 0;
    letter-spacing: -0.01em;
}
.el-coach-card-role {
    font-size: 0.85rem;
    color: var(--el-text-muted);
    font-weight: 600;
    margin: 0;
}
.el-coach-card-bio {
    font-size: 0.9rem;
    color: var(--el-text);
    line-height: 1.55;
    margin: 4px 0 6px;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.el-coach-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 4px 0 8px;
}
.el-coach-card-chip {
    background: rgba(125, 211, 252, 0.18);
    color: var(--el-cta);
    font-size: 0.72rem;
    font-weight: 700;
    padding: 3px 10px;
    border-radius: 999px;
    letter-spacing: 0.01em;
}
html.night-mode .el-coach-card-chip {
    background: rgba(125, 211, 252, 0.16);
    color: var(--el-accent);
}
.el-coach-card-phone {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--el-text-muted);
    font-size: 0.88rem;
    text-decoration: none;
    transition: color 0.2s;
    margin-top: auto;
}
.el-coach-card-phone:hover { color: var(--club-accent); }
.el-coach-card-phone i { font-size: 1rem; }
html.night-mode .el-coach-card-phone:hover { color: var(--el-accent); }

.el-coach-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 48px 24px;
    background: var(--el-surface-alt);
    border: 1px dashed var(--el-border);
    border-radius: var(--el-radius);
    color: var(--el-text-muted);
}
.el-coach-empty i { font-size: 2.4rem; color: var(--club-accent); display: block; margin-bottom: 10px; }
.el-coach-empty h3 { margin: 0 0 6px; color: var(--el-text); font-size: 1.15rem; font-weight: 800; }
.el-coach-empty p { margin: 0; font-size: 0.92rem; }
.el-coach-empty a { color: var(--club-accent); font-weight: 700; }
html.night-mode .el-coach-empty a { color: var(--el-accent); }

/* ── Programmes ─────────────────────────────────────────────────── */
.el-coach-progs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 24px;
}
@media (min-width: 900px) {
    .el-coach-progs { grid-template-columns: repeat(2, 1fr); }
}
.el-coach-prog {
    background: #ffffff;
    border: none;
    border-radius: var(--el-radius-lg);
    overflow: hidden;
    box-shadow: var(--el-glow-idle);
    display: flex;
    flex-direction: column;
    transition: transform 0.3s var(--el-ease-soft), box-shadow 0.3s;
}
.el-coach-prog:hover { transform: translateY(-4px); box-shadow: var(--el-glow-hover); }
html.night-mode .el-coach-prog {
    background: #12141b;
}
.el-coach-prog-media {
    aspect-ratio: 16 / 9;
    position: relative;
    overflow: hidden;
    display: grid;
    place-items: center;
}
/* Decorative tennis-court net lines drawn with a repeating linear
   gradient — same motif across every programme card, but the hue
   underneath changes per programme via the `--prog-hue` custom prop
   on each `.el-coach-prog--*` variant. */
.el-coach-prog-media::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
        /* Horizontal centre net */
        linear-gradient(0deg, transparent 48%, rgba(255,255,255,0.28) 48%, rgba(255,255,255,0.28) 52%, transparent 52%),
        /* Diagonal court lines */
        linear-gradient(115deg, transparent 0%, transparent 38%, rgba(255,255,255,0.18) 38%, rgba(255,255,255,0.18) 40%, transparent 40%),
        linear-gradient(65deg,  transparent 0%, transparent 38%, rgba(255,255,255,0.18) 38%, rgba(255,255,255,0.18) 40%, transparent 40%);
    pointer-events: none;
    z-index: 1;
}
/* Soft radial glow behind the ball for depth */
.el-coach-prog-media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 50% 55%, rgba(255,255,255,0.22), transparent 55%);
    pointer-events: none;
    z-index: 1;
}

/* Per-programme hues */
.el-coach-prog--red    .el-coach-prog-media { background: linear-gradient(135deg, #f97316 0%, #dc2626 100%); }
.el-coach-prog--green  .el-coach-prog-media { background: linear-gradient(135deg, #86efac 0%, #16a34a 100%); }
.el-coach-prog--junior .el-coach-prog-media { background: linear-gradient(135deg, #fbbf24 0%, #f97316 100%); }
.el-coach-prog--adult  .el-coach-prog-media { background: linear-gradient(135deg, #3b82f6 0%, var(--el-hero) 100%); }

/* Tennis-ball centerpiece */
.el-coach-prog-ball {
    position: relative;
    z-index: 2;
    width: 40%;
    max-width: 140px;
    aspect-ratio: 1;
    object-fit: contain;
    filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.25));
    transition: transform 0.5s var(--el-ease-soft);
}
.el-coach-prog:hover .el-coach-prog-ball { transform: scale(1.08) rotate(-8deg); }

.el-coach-prog-ball--large { width: 46%; max-width: 170px; }

/* Junior Club — three balls fanned out across the media area */
.el-coach-prog-ball--trio {
    width: 28%;
    max-width: 110px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.el-coach-prog-ball--trio.el-coach-prog-ball--offset-1 {
    transform: translate(-130%, -50%) rotate(-12deg);
}
.el-coach-prog-ball--trio.el-coach-prog-ball--offset-2 {
    transform: translate(30%, -50%) rotate(14deg);
}
.el-coach-prog--junior:hover .el-coach-prog-ball--trio {
    transition: transform 0.6s var(--el-ease-soft);
}
.el-coach-prog--junior:hover .el-coach-prog-ball--trio.el-coach-prog-ball--offset-1 {
    transform: translate(-145%, -58%) rotate(-18deg);
}
.el-coach-prog--junior:hover .el-coach-prog-ball--trio.el-coach-prog-ball--offset-2 {
    transform: translate(45%, -58%) rotate(20deg);
}
.el-coach-prog--junior:hover .el-coach-prog-ball--trio:not(.el-coach-prog-ball--offset-1):not(.el-coach-prog-ball--offset-2) {
    transform: translate(-50%, -62%) rotate(6deg);
}
.el-coach-prog-badge {
    position: absolute;
    top: 14px;
    left: 14px;
    background: rgba(255, 255, 255, 0.95);
    color: var(--el-hero);
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 5px 12px;
    border-radius: 999px;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.22);
    z-index: 3;                  /* above court-line decoratives */
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.el-coach-prog-body {
    padding: 24px 26px 26px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex-grow: 1;
}
.el-coach-prog-title {
    font-size: 1.35rem;
    font-weight: 800;
    color: var(--el-text);
    margin: 0;
    letter-spacing: -0.01em;
}
.el-coach-prog-body > p {
    font-size: 0.94rem;
    color: var(--el-text-muted);
    line-height: 1.55;
    margin: 0;
}
.el-coach-prog-meta {
    list-style: none;
    padding: 0;
    margin: 6px 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
}
.el-coach-prog-meta li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.82rem;
    color: var(--el-text-muted);
}
.el-coach-prog-meta i {
    color: var(--club-accent);
    font-size: 0.98rem;
}
html.night-mode .el-coach-prog-meta i { color: var(--el-accent); }
.el-coach-prog-price {
    font-weight: 800;
    color: var(--el-text);
    font-size: 0.95rem;
    margin-top: 6px;
}
.el-coach-prog-note {
    color: var(--el-cta);
    font-weight: 600;
    font-size: 0.88rem;
}
.el-coach-prog .el-btn {
    align-self: flex-start;
    margin-top: auto;
}

/* ── Start Your Journey CTA ───────────────────────────────────────
   Sky-blue surface to match the Latest Stories / Weather / Ready-to-
   Play strips; night-mode flips back to the deep navy gradient. */
.el-coach-cta {
    background: linear-gradient(180deg, #e7eefa 0%, #dce6f5 100%);
    color: var(--el-text);
    position: relative;
    /* overflow:visible — balls serve IN from off-screen left and
       OUT past off-screen right. The radial ::after gradient uses
       inset:0 so it stays within the section regardless. */
    overflow: visible;
}
html.night-mode .el-coach-cta {
    background: linear-gradient(135deg, var(--el-hero) 0%, var(--el-hero-deep) 100%);
    color: var(--el-text-inv);
}
.el-coach-cta::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 10% 30%, rgba(2, 12, 146, 0.08), transparent 45%),
        radial-gradient(circle at 90% 70%, rgba(125, 211, 252, 0.18), transparent 40%);
    pointer-events: none;
}
html.night-mode .el-coach-cta::after {
    background:
        radial-gradient(circle at 10% 30%, rgba(188, 255, 0, 0.08), transparent 45%),
        radial-gradient(circle at 90% 70%, rgba(125, 211, 252, 0.08), transparent 40%);
}
.el-coach-cta > .el-container { position: relative; z-index: 2; }
.el-coach-cta-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: clamp(28px, 5vw, 72px);
    align-items: center;
}
@media (max-width: 900px) {
    .el-coach-cta-grid { grid-template-columns: 1fr; justify-items: center; }
    .el-coach-cta-glyph {
        /* Keep the glyph slot as an empty spacer on narrow screens so
           the absolute ball track has somewhere to render the balls
           below the copy rather than overlapping it. */
        width: 260px;
        height: 220px;
        aspect-ratio: auto;
    }
}
.el-coach-cta-title {
    font-size: clamp(2rem, 4.2vw, 3rem);
    font-weight: 900;
    letter-spacing: -0.02em;
    line-height: 1.12;
    color: var(--club-accent);
    margin: 0 0 14px;
    text-shadow:
        0 6px 22px rgba(2, 12, 146, 0.18),
        0 2px 6px rgba(2, 12, 146, 0.14);
}
html.night-mode .el-coach-cta-title {
    color: var(--el-text-inv);
    text-shadow: none;
}
.el-coach-cta-sub {
    color: var(--el-text-muted);
    font-size: 1rem;
    line-height: 1.65;
    margin: 0 0 22px;
    max-width: 560px;
}
html.night-mode .el-coach-cta-sub { color: var(--el-text-inv-muted); }
.el-coach-cta-contact {
    list-style: none;
    padding: 0;
    margin: 0 0 26px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.el-coach-cta-contact li {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--el-text);
    font-size: 0.96rem;
}
html.night-mode .el-coach-cta-contact li { color: var(--el-text-inv); }
.el-coach-cta-contact li i {
    color: var(--club-accent);
    font-size: 1.15rem;
    flex-shrink: 0;
}
html.night-mode .el-coach-cta-contact li i { color: var(--el-accent); }
.el-coach-cta-contact a {
    color: var(--club-accent);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: border-color 0.2s;
}
html.night-mode .el-coach-cta-contact a { color: var(--el-accent); }
.el-coach-cta-contact a:hover { border-bottom-color: var(--club-accent); }
html.night-mode .el-coach-cta-contact a:hover { border-bottom-color: var(--el-accent); }

.el-coach-cta-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}
/* Reusable button modifier kept in this neighbourhood (next to the
   coaching CTA where it was first introduced). Apply alongside
   .el-btn (e.g. <a class="el-btn el-btn--green">) on the page's
   terminal CTA — Become a Member, Open the App, Subscribe, Book a
   Coaching Session, Explore Memberships, etc.

   Tennis-ball green fill + navy text + 2 px navy outline so the pill
   pops against any backdrop. Box-shadow stack:
     • diffuse coloured halo (navy in day, sky-blue in night) so the
       glow matches whichever surface is behind it
     • lime drop-shadow underneath for the cushion / lift feel
   The default .el-btn--cta token would flip to white-on-white in
   night mode — this class avoids that. */
.el-btn--green {
    background: var(--el-green);
    border: 2px solid var(--el-hero);
    color: var(--el-green-text);
    box-shadow:
        0 0 28px rgba(2, 12, 146, 0.45),
        0 8px 24px rgba(188, 255, 0, 0.20);
}
.el-btn--green:hover {
    filter: brightness(1.08);
    transform: translateY(-2px);
    box-shadow:
        0 0 38px rgba(2, 12, 146, 0.60),
        0 12px 32px rgba(188, 255, 0, 0.30);
}
html.night-mode .el-btn--green {
    box-shadow:
        0 0 28px rgba(125, 211, 252, 0.45),
        0 8px 24px rgba(188, 255, 0, 0.22);
}
html.night-mode .el-btn--green:hover {
    box-shadow:
        0 0 40px rgba(125, 211, 252, 0.65),
        0 12px 32px rgba(188, 255, 0, 0.32);
}
.el-coach-cta .el-btn--outline {
    color: var(--club-accent);
    border-color: rgba(2, 12, 146, 0.4);
    background: transparent;
}
.el-coach-cta .el-btn--outline:hover {
    background: rgba(2, 12, 146, 0.06);
    border-color: var(--club-accent);
    color: var(--club-accent);
}
html.night-mode .el-coach-cta .el-btn--outline {
    color: var(--el-text-inv);
    border-color: rgba(255, 255, 255, 0.32);
}
html.night-mode .el-coach-cta .el-btn--outline:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.55);
    color: var(--el-text-inv);
}

/* ── Coach CTA tennis-ball choreography ───────────────────────────
   THREE balls serve in from the far left, cascade out from behind
   each other on the right side of the section, idle-spin with
   random-feeling rates / direction flips, cascade back behind each
   other, then the green ball serves away (toss + arc + shrink).
   Cycle repeats every 18s.

   Positioning: balls live in the full-section `.el-coach-cta-balls`
   overlay — they use the whole section width to travel, not the
   narrow right grid column. The original `.el-coach-cta-glyph`
   stays in the grid as an empty placeholder so the copy/glyph
   columns keep their widths.
   ─────────────────────────────────────────────────────────────── */
.el-coach-cta-balls {
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;
    pointer-events: none;
    /* Sit BEHIND the section copy + buttons (which carry z-index: 2 on
       the .el-container). The ball animation passes behind the text
       column so the headline + CTA stay legible while the balls play. */
    z-index: 1;
}
.el-coach-cta-glyph {
    /* Empty grid placeholder — reserves the right column width so
       the copy column + ball overlay align with the same visual
       centre as before. */
    width: clamp(260px, 36vw, 380px);
    aspect-ratio: 1;
}
/* Anchor for ball positioning — the "home" of the three balls is
   the centre of the right 40 % of the section (roughly where the
   glyph column sits). --ball-home-x is used by every keyframe as
   the base left-position of the group; individual balls offset
   from it. */
.el-coach-cta-balls {
    --ball-home-x: 72%;
    --ball-home-y: 50%;
    --ball-size: clamp(120px, 14vw, 180px);
}

/* Halo breathing behind the ball group. */
.el-coach-cta-balls::before {
    content: '';
    position: absolute;
    top: var(--ball-home-y);
    left: var(--ball-home-x);
    width: calc(var(--ball-size) * 2.1);
    height: calc(var(--ball-size) * 2.1);
    transform: translate(-50%, -50%);
    background: radial-gradient(
        circle at 50% 50%,
        rgba(188, 255, 0, 0.28) 0%,
        rgba(188, 255, 0, 0.14) 28%,
        rgba(188, 255, 0, 0.05) 52%,
        transparent 72%);
    filter: blur(6px);
    animation: coachCtaHaloBreath 5.5s ease-in-out infinite;
}

/* Base ball — opaque, fully sized in every idle/resting frame.
   Opacity 0 is used for the "hidden behind another ball" states
   so overlapping PNG alpha edges don't wash the colour out. */
.el-coach-cta-ball {
    position: absolute;
    top: var(--ball-home-y);
    left: var(--ball-home-x);
    width: var(--ball-size);
    aspect-ratio: 1;
    object-fit: contain;
    pointer-events: auto;
    transform: translate(-50%, -50%);
    /* Promote each ball to its own composited layer so the spin +
       offset-path translation runs on the GPU. Without this the
       first cycle stuttered while the layer was created. */
    will-change: transform, opacity, offset-distance, filter;
    transform: translateZ(0) translate(-50%, -50%);
    backface-visibility: hidden;
    animation-timing-function: cubic-bezier(0.65, 0.02, 0.35, 0.98);
    animation-iteration-count: infinite;
}
/* Single drop-shadow per ball — multi-layer drop-shadow is repainted
   every frame and was the chief cause of the jerky cycle on first
   load. One layer reads visually identical at typical viewing
   distances. */
.el-coach-cta-ball--green {
    z-index: 3;
    filter: drop-shadow(0 0 22px rgba(188, 255, 0, 0.5));
    /* `linear` so the constant-rate rotation between keyframes doesn't
       acquire micro-eases at each segment boundary — combined with the
       sub-5% intermediate keyframes below this gives a smooth glide. */
    animation: coachCtaBallGreen 18s linear infinite;
}
.el-coach-cta-ball--orange {
    z-index: 2;
    filter: drop-shadow(0 0 22px rgba(249, 115, 22, 0.55));
    animation: coachCtaBallOrange 18s linear infinite;
}
.el-coach-cta-ball--red {
    z-index: 1;
    filter: drop-shadow(0 0 22px rgba(220, 38, 38, 0.55));
    animation: coachCtaBallRed 18s linear infinite;
}

/* Hover: spread the balls apart horizontally, keep a free-running
   linear spin on each at different durations for independence.
   Per-ball `--spread-x` feeds the coachCtaSpinFree keyframe so the
   rotation stays anchored at each ball's spread position. */
.el-coach-cta-balls:hover .el-coach-cta-ball  { opacity: 1 !important; }
.el-coach-cta-balls:hover .el-coach-cta-ball--green  { --spread-x: calc(-50% - 140px); animation: coachCtaSpinFree 2.7s linear infinite; }
.el-coach-cta-balls:hover .el-coach-cta-ball--orange { --spread-x: -50%;                animation: coachCtaSpinFree 4.4s linear infinite reverse; }
.el-coach-cta-balls:hover .el-coach-cta-ball--red    { --spread-x: calc(-50% + 140px); animation: coachCtaSpinFree 3.2s linear infinite; }

/* Halo breathing — unchanged. */
@keyframes coachCtaHaloBreath {
    0%, 100% { opacity: 0.9; transform: translate(-50%, -50%) scale(1); }
    50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.08); }
}

/* Simple hover spin — single continuous rotation, duration varies
   per ball. Transform stays at the spread position while rotating. */
@keyframes coachCtaSpinFree {
    from { transform: translate(var(--spread-x, -50%), -50%) rotate(0deg); }
    to   { transform: translate(var(--spread-x, -50%), -50%) rotate(360deg); }
}

/* ── GREEN ball — serves in from LEFT across the whole section,
       idles at the centre position, then serves OUT to the right.
       Ball stays FULL SIZE + FULL OPACITY in idle phases; scale is
       only used for the serve in/out airborne moments. Transforms
       are relative to (--ball-home-x, --ball-home-y) via the
       translate(-50%, -50%) base in .el-coach-cta-ball. */
/* ── Smooth-arc serve trajectory via CSS offset-path ─────────────
   The ball follows a TRUE cubic-Bezier curve instead of linear
   interpolation between manually-placed waypoints (which read as
   jagged straight-line segments). offset-path lays down the curve
   once; offset-distance animates the ball along it.

   Path is TWO cubic curves stitched at the home position:
     • serve-in  M(-1400,-280) → C ctrl + C end → home(0,0)
     • serve-out home(0,0)     → C ctrl + C ctrl → exit(-1400,200)

   Home sits at ~48% of total path length. We pin offset-distance
   there during the idle phase; release it down the second half
   for the serve-out. Coordinates are pixels relative to home. With
   home at 72 % of section width, -1400 X clears viewports up to
   ~1950 px wide — the ball is just off-screen at the start/end
   without the over-long runway -2500 was creating. Inner control
   points scaled with the endpoints so the curve shape stays the
   same dip-and-swoop in + arc-and-fall out. On <860 px the
   narrow override falls back to a simple fade-in. */
.el-coach-cta-ball--green {
    offset-path: path("M -1400,-280 C -900,260 -340,-30 0,0 C -200,-220 -900,-120 -1400,200");
    offset-rotate: 0deg;            /* spin handled separately via transform: rotate() */
    offset-anchor: 50% 50%;         /* path tracks the ball's centre */
}
@keyframes coachCtaBallGreen {
    /* Serve-in (0% → 10%): ride the first half of the curve into
       home. The Bezier dips through control point (-700, 260) ≈
       offset-distance 25 % of total path — that's the "ground" of
       the arc. Layered drop-shadow follows: halo only when high,
       tight + dark at the low point of the bounce, softens back
       to halo-only at home. */
    0%   {
        offset-distance: 0%;
        transform: scale(0.25) rotate(-240deg);
        opacity: 0;
        filter: drop-shadow(0 0 22px rgba(188, 255, 0, 0.5));
    }
    2%   {
        opacity: 1;
        filter:
            drop-shadow(0 0 22px rgba(188, 255, 0, 0.5))
            drop-shadow(0 50px 24px rgba(0, 0, 0, 0.12));
    }
    4%   {
        offset-distance: 14%;
        transform: scale(0.45) rotate(-90deg);
        filter:
            drop-shadow(0 0 22px rgba(188, 255, 0, 0.5))
            drop-shadow(0 28px 14px rgba(0, 0, 0, 0.30));
    }
    /* Ground hit — tight dark shadow as the curve dips through
       control1 (-700, 260) ≈ offset-distance 25%. */
    5%   {
        offset-distance: 22%;
        transform: scale(0.7) rotate(0deg);
        filter:
            drop-shadow(0 0 22px rgba(188, 255, 0, 0.5))
            drop-shadow(0 8px 5px rgba(0, 0, 0, 0.55));
    }
    7%   {
        offset-distance: 32%;
        transform: scale(0.85) rotate(150deg);
        filter:
            drop-shadow(0 0 22px rgba(188, 255, 0, 0.5))
            drop-shadow(0 22px 13px rgba(0, 0, 0, 0.30));
    }
    10%  {
        offset-distance: 48%;
        transform: scale(1) rotate(460deg);
        filter:
            drop-shadow(0 0 22px rgba(188, 255, 0, 0.5))
            drop-shadow(0 38px 22px rgba(0, 0, 0, 0.16));
    }
    12%  {
        offset-distance: 48%;
        transform: scale(1) rotate(480deg);
        opacity: 1;
        filter:
            drop-shadow(0 0 22px rgba(188, 255, 0, 0.5))
            drop-shadow(0 38px 22px rgba(0, 0, 0, 0.14));
    }

    /* Idle (12% → 65%) — pinned at home (48% of path), rotation
       chain forward + back for "random" spin. Reversal points get a
       fast-approach + slow-departure pair so the velocity discontinuity
       at each peak/trough is split into two smaller steps instead of
       one big flip — the eye reads it as inertial slow-down → reverse
       → accelerate-out, not as a jerk. */
    17%  { offset-distance: 48%;  transform: scale(1)    rotate(580deg); }
    20%  { offset-distance: 48%;  transform: scale(1)    rotate(665deg); }   /* fast approach to peak */
    22%  { offset-distance: 48%;  transform: scale(1)    rotate(680deg); }   /* peak — momentary stop */
    24%  { offset-distance: 48%;  transform: scale(1)    rotate(670deg); }   /* slow departure backward */
    27%  { offset-distance: 48%;  transform: scale(1)    rotate(640deg); }
    30%  { offset-distance: 48%;  transform: scale(1)    rotate(607deg); }   /* fast approach to trough */
    32%  { offset-distance: 48%;  transform: scale(1)    rotate(600deg); }   /* trough — reversed */
    34%  { offset-distance: 48%;  transform: scale(1)    rotate(615deg); }   /* slow departure forward */
    37%  { offset-distance: 48%;  transform: scale(1)    rotate(730deg); }
    40%  { offset-distance: 48%;  transform: scale(1)    rotate(845deg); }   /* fast approach to peak */
    42%  { offset-distance: 48%;  transform: scale(1)    rotate(860deg); }   /* peak */
    44%  { offset-distance: 48%;  transform: scale(1)    rotate(850deg); }   /* slow departure backward */
    47%  { offset-distance: 48%;  transform: scale(1)    rotate(820deg); }
    50%  { offset-distance: 48%;  transform: scale(1)    rotate(787deg); }   /* fast approach to trough */
    52%  { offset-distance: 48%;  transform: scale(1)    rotate(780deg); }   /* trough — reversed */
    54%  { offset-distance: 48%;  transform: scale(1)    rotate(795deg); }   /* slow departure forward */
    57%  { offset-distance: 48%;  transform: scale(1)    rotate(920deg); }
    60%  { offset-distance: 48%;  transform: scale(1)    rotate(1010deg); }
    62%  { offset-distance: 48%;  transform: scale(1)    rotate(1060deg); }
    63.5% { offset-distance: 48%; transform: scale(1)    rotate(1080deg); }
    65%  { offset-distance: 48%;  transform: scale(1)    rotate(1100deg); }

    /* Cascade-back window — green stays put while red + orange
       tuck behind it (65% → 74%). */
    74%  { offset-distance: 48%;  transform: scale(1)    rotate(1200deg); opacity: 1; }

    /* Serve-out (74% → 86%): ride the second half of the curve out
       to off-screen left, smooth Bezier descent. */
    77%  { offset-distance: 56%;  transform: scale(1.05) rotate(1300deg); }
    81%  { offset-distance: 72%;  transform: scale(0.95) rotate(1500deg); }
    84%  { offset-distance: 88%;  transform: scale(0.7)  rotate(1700deg); }
    86%  { offset-distance: 100%; transform: scale(0.4)  rotate(1900deg); opacity: 1; }

    /* Hidden gap before the loop restart */
    87%, 99% { offset-distance: 100%; transform: scale(0.4) rotate(1900deg); opacity: 0; }
    100% { offset-distance: 0%;   transform: scale(0.25) rotate(-240deg); opacity: 0; }
}
/* Browsers without offset-path → fall back to the narrow keyframes
   (fade-in-place at home; orange + red still cascade in normally). */
@supports not (offset-path: path("M 0 0")) {
    .el-coach-cta-ball--green { animation-name: coachCtaBallGreenNarrow; }
}

/* ── ORANGE ball — stacked behind green (opacity 0 when hidden);
       slides OUT to the right of green, idles, then slides back
       in and fades out. Scale stays 1 in every keyframe. */
@keyframes coachCtaBallOrange {
    /* Hidden behind green while green serves in (0% → 10%).
       Opacity 0 → prevents PNG-alpha edges washing out green. */
    0%, 10% { transform: translate(calc(-50% - 60px), -50%) rotate(0deg); opacity: 0; }

    /* Slide out right of green (10% → 14%), fade in */
    12%     { transform: translate(calc(-50% + 20px), -50%) rotate(30deg); opacity: 0.6; }
    14%     { transform: translate(calc(-50% + 90px), -50%) rotate(60deg); opacity: 1; }

    /* Idle spin — different rate + flips. Sub-5% intermediates so
       the reversals stay smooth under linear timing. */
    17%  { transform: translate(calc(-50% + 90px), calc(-50% - 2px)) rotate(160deg);  opacity: 1; }
    22%  { transform: translate(calc(-50% + 90px), calc(-50% - 4px)) rotate(260deg); }
    27%  { transform: translate(calc(-50% + 90px), calc(-50% - 1px)) rotate(220deg); }
    32%  { transform: translate(calc(-50% + 90px), calc(-50% + 3px)) rotate(180deg); }   /* reversed */
    37%  { transform: translate(calc(-50% + 90px), calc(-50% + 1px)) rotate(340deg); }
    42%  { transform: translate(calc(-50% + 90px), calc(-50% - 2px)) rotate(500deg); }
    47%  { transform: translate(calc(-50% + 90px), calc(-50% - 1px)) rotate(450deg); }
    52%  { transform: translate(calc(-50% + 90px), calc(-50% + 4px)) rotate(400deg); }   /* reversed */
    56%  { transform: translate(calc(-50% + 90px), calc(-50% + 2px)) rotate(560deg); }
    60%  { transform: translate(calc(-50% + 90px), -50%)             rotate(720deg); opacity: 1; }

    /* Slide BACK behind green (64% → 70%), fade out */
    67%  { transform: translate(calc(-50% + 20px), -50%) rotate(780deg); opacity: 0.6; }
    70%  { transform: translate(calc(-50% - 60px), -50%) rotate(820deg); opacity: 0; }

    /* Stay hidden through green's serve-out and the loop reset */
    100% { transform: translate(calc(-50% - 60px), -50%) rotate(0deg); opacity: 0; }
}

/* ── RED ball — stacked behind orange; slides out furthest right;
       idles; slides back behind orange; fades out. */
@keyframes coachCtaBallRed {
    0%, 16% { transform: translate(calc(-50% - 60px), -50%) rotate(0deg); opacity: 0; }

    18%     { transform: translate(calc(-50% + 90px), -50%)  rotate(40deg); opacity: 0.6; }
    20%     { transform: translate(calc(-50% + 220px), -50%) rotate(80deg); opacity: 1; }

    /* Idle — different rotation phase again. Sub-5% intermediates
       so the reversals stay smooth under linear timing. */
    23%  { transform: translate(calc(-50% + 220px), calc(-50% - 3px)) rotate(40deg);  opacity: 1; }
    28%  { transform: translate(calc(-50% + 220px), calc(-50% - 5px)) rotate(-80deg); }   /* reversed */
    33%  { transform: translate(calc(-50% + 220px), calc(-50% - 1px)) rotate(80deg); }
    38%  { transform: translate(calc(-50% + 220px), calc(-50% + 2px)) rotate(240deg); }
    43%  { transform: translate(calc(-50% + 220px), calc(-50% + 1px)) rotate(190deg); }
    48%  { transform: translate(calc(-50% + 220px), calc(-50% - 3px)) rotate(140deg); }   /* reversed */
    53%  { transform: translate(calc(-50% + 220px), calc(-50% - 2px)) rotate(340deg); }
    58%  { transform: translate(calc(-50% + 220px), -50%)             rotate(540deg); opacity: 1; }

    /* Slide BACK behind orange then green (62% → 68%) */
    64%  { transform: translate(calc(-50% + 90px), -50%)  rotate(600deg); opacity: 0.6; }
    68%  { transform: translate(calc(-50% - 60px), -50%)  rotate(660deg); opacity: 0; }

    100% { transform: translate(calc(-50% - 60px), -50%) rotate(0deg); opacity: 0; }
}

/* ── Narrow-screen override ────────────────────────────────────────
   On phones + small tablets the serve-in (arc from far left of the
   section) and serve-out (arc off right) overflow the layout or
   overlap the CTA copy. Centre the ball home + strip the airborne
   serve — keep the slide-out / slide-in between the three balls so
   the cascade still plays. */
@media (max-width: 860px) {
    .el-coach-cta-balls {
        /* Centre horizontally + park vertically inside the glyph
           spacer that sits below the copy on narrow layouts. */
        --ball-home-x: 50%;
        --ball-home-y: calc(100% - 170px);
        --ball-size: clamp(100px, 26vw, 160px);
    }
    .el-coach-cta-ball--green {
        animation-name: coachCtaBallGreenNarrow;
        /* Disable the offset-path — narrow keyframes use plain
           translate() so the ball can fade in/out at home rather
           than ride the wide-screen serve curve. */
        offset-path: none;
    }
    /* Tighter hover spread on small screens */
    .el-coach-cta-balls:hover .el-coach-cta-ball--green  { --spread-x: calc(-50% - 80px); }
    .el-coach-cta-balls:hover .el-coach-cta-ball--red    { --spread-x: calc(-50% + 80px); }
}
@keyframes coachCtaBallGreenNarrow {
    /* Fade in AT the resting position — no serve-in arc. Orange &
       red still slide out from behind via their normal keyframes. */
    0%   { transform: translate(calc(-50% - 60px), -50%) scale(0.7) rotate(0deg);    opacity: 0; }
    6%   { transform: translate(calc(-50% - 60px), -50%) scale(1)   rotate(50deg);   opacity: 1; }
    /* Idle spin */
    20%  { transform: translate(calc(-50% - 60px), -50%) scale(1)   rotate(360deg); }
    35%  { transform: translate(calc(-50% - 60px), -50%) scale(1)   rotate(240deg); }
    50%  { transform: translate(calc(-50% - 60px), -50%) scale(1)   rotate(520deg); }
    65%  { transform: translate(calc(-50% - 60px), -50%) scale(1)   rotate(780deg); }
    74%  { transform: translate(calc(-50% - 60px), -50%) scale(1)   rotate(860deg); opacity: 1; }
    /* Fade out in place — no airborne arc. */
    82%  { transform: translate(calc(-50% - 60px), -50%) scale(0.85) rotate(940deg);  opacity: 0.5; }
    86%, 99% { transform: translate(calc(-50% - 60px), -50%) scale(0.5) rotate(1000deg); opacity: 0; }
    100% { transform: translate(calc(-50% - 60px), -50%) scale(0.7) rotate(0deg); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .el-coach-cta-ball,
    .el-coach-cta-glyph::before { animation: none; }
    /* Fallback: only show the green ball, parked centred. */
    .el-coach-cta-ball--orange,
    .el-coach-cta-ball--red { display: none; }
    .el-coach-cta-ball--green { transform: translate(-50%, -50%); opacity: 1; }
}

@media (max-width: 600px) {
    .el-coach-hero-pill { font-size: 0.76rem; padding: 6px 12px; }
    .el-coach-card-photo { aspect-ratio: 4 / 5; }
    .el-coach-prog-body { padding: 20px 22px 22px; }
}

/* ── Coach detail popup overrides (light-mode default) ────────────────
   The shared builder CSS renders the popup against `--club-bg` which
   is painted DARK by applyClubTheme even when the Eldoraigne page is
   otherwise in day-mode (the builder defaults fight our light surface).
   These overrides restore a clean white card + dark text in day mode
   and keep the overlay centred vertically on tall screens. Night-mode
   keeps the builder's dark treatment via its own `html.night-mode`
   rules — we only override the day path here. */
.cs-coach-detail-overlay {
    align-items: center !important;
}
html:not(.night-mode) .cs-coach-detail-card {
    background: #ffffff !important;
    color: var(--el-text) !important;
    border-color: rgba(2, 12, 146, 0.15) !important;
    box-shadow:
        0 0 0 1px rgba(2, 12, 146, 0.08),
        0 24px 60px rgba(2, 12, 146, 0.2) !important;
}
html:not(.night-mode) .cs-coach-detail-card,
html:not(.night-mode) .cs-coach-detail-card * {
    color: var(--el-text);
}
html:not(.night-mode) .cs-coach-detail-card .cs-coach-chip {
    background: rgba(2, 12, 146, 0.08);
    color: var(--el-text);
    border: 1px solid rgba(2, 12, 146, 0.15);
}
html:not(.night-mode) .cs-coach-detail-tagline {
    color: var(--el-text-muted) !important;
}
html:not(.night-mode) .cs-coach-detail-academy,
html:not(.night-mode) .cs-coach-detail-academy * {
    color: var(--club-accent) !important;
}
html:not(.night-mode) .cs-coach-detail-status.is-available {
    color: #15803d !important;
    background: rgba(22, 163, 74, 0.1);
    border-color: rgba(22, 163, 74, 0.25);
}
html:not(.night-mode) .cs-coach-detail-status.is-available i { color: #15803d !important; }
html:not(.night-mode) .cs-coach-detail-status.is-unavailable {
    color: #b91c1c !important;
}
html:not(.night-mode) .cs-coach-detail-close {
    background: rgba(2, 12, 146, 0.12);
    color: var(--el-text);
}
html:not(.night-mode) .cs-coach-detail-close:hover {
    background: rgba(2, 12, 146, 0.22);
}
/* The "Request a Lesson" CTA reads against white now, so keep its own
   accent paint — accent bg + white text. */
html:not(.night-mode) .cs-coach-detail-card .cs-coach-request-btn {
    background: var(--club-accent) !important;
    color: var(--club-accent-text) !important;
    border-color: var(--club-accent) !important;
}
html:not(.night-mode) .cs-coach-detail-card .cs-coach-request-btn * {
    color: var(--club-accent-text) !important;
}

/* ══════════════════════════════════════════════════════════════════════
   FAQ PAGE

   - Search bar in the hero with a clear-X button
   - Category filter pills row with horizontal scroll on narrow screens
   - Grouped accordion, each group titled with an icon
   - Empty-state card when search yields zero matches
   - AI "Ask the Club" form card with chip suggestions and a response
     panel that shows a tier pill (Guest / Logged-in member)
   ══════════════════════════════════════════════════════════════════════ */

/* ── Search bar ────────────────────────────────────────────────────── */
.el-faq-search {
    position: relative;
    margin: 26px auto 0;
    max-width: 640px;
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: 999px;
    padding: 0 52px 0 52px;
    display: flex;
    align-items: center;
    transition: border-color 0.2s, background 0.2s;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}
.el-faq-search:focus-within {
    border-color: var(--el-green);
    background: rgba(255, 255, 255, 0.18);
    box-shadow: 0 0 0 4px rgba(188, 255, 0, 0.18);
}
.el-faq-search-icon {
    position: absolute;
    left: 18px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--el-text-inv);
    font-size: 1.3rem;
    opacity: 0.85;
    pointer-events: none;
}
.el-faq-search input[type="search"] {
    flex: 1;
    width: 100%;
    border: 0;
    background: transparent;
    color: var(--el-text-inv);
    font-size: 1rem;
    padding: 16px 0;
    outline: none;
    font-family: inherit;
}
.el-faq-search input[type="search"]::placeholder {
    color: rgba(255, 255, 255, 0.65);
}
.el-faq-search input[type="search"]::-webkit-search-cancel-button {
    display: none;   /* we use our own X */
}
.el-faq-search-clear {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 34px; height: 34px;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.16);
    color: var(--el-text-inv);
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: background 0.2s, transform 0.2s;
}
.el-faq-search-clear:hover {
    background: rgba(255, 255, 255, 0.3);
}
.el-faq-search-clear.hidden { display: none; }

/* ── Category pills row ────────────────────────────────────────────── */
.el-faq-filters-section {
    padding-top: clamp(24px, 3vw, 40px);
    padding-bottom: 0;
}
.el-faq-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: center;
}
@media (max-width: 720px) {
    .el-faq-filters {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;
        padding-bottom: 4px;
        justify-content: flex-start;
    }
    .el-faq-filters::-webkit-scrollbar { display: none; }
}
.el-faq-filter {
    padding: 8px 18px;
    border-radius: 999px;
    background: var(--el-surface-alt);
    border: 1px solid var(--el-border);
    color: var(--el-text);
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.15s;
}
.el-faq-filter:hover {
    background: var(--club-accent);
    color: var(--club-accent-text);
    border-color: var(--club-accent);
    transform: translateY(-1px);
}
.el-faq-filter.is-active {
    background: var(--club-accent);
    color: var(--club-accent-text);
    border-color: var(--club-accent);
    box-shadow: 0 4px 14px rgba(2, 12, 146, 0.2);
}
html.night-mode .el-faq-filter {
    background: rgba(255, 255, 255, 0.04);
    color: var(--el-text);
    border-color: rgba(255, 255, 255, 0.1);
}
html.night-mode .el-faq-filter:hover,
html.night-mode .el-faq-filter.is-active {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-green);
}

/* ── FAQ list (grouped accordion) ──────────────────────────────────── */
.el-faq-list-section {
    padding-top: clamp(28px, 4vw, 48px);
}
.el-faq-list {
    display: flex;
    flex-direction: column;
    /* Was gap: 44px — that was for the pre-accordion layout where
       every section was fully expanded and needed generous breathing
       room. With collapsible sections + tightened headers the same
       44px reads as broken airy. 6px is snug + still distinguishes
       each section as its own card. */
    gap: 6px;
    max-width: 880px;
    margin: 0 auto;
}
/* Items inside a faq-group sit on default block flow without the
   .el-accordion wrapper that the memberships-FAQ uses, so they had
   no inter-item spacing and read as a flush stack. Mirror the
   memberships-FAQ feel by adding a 10 px gap between accordion items
   inside each group (the group title keeps its own margin-bottom). */
/* Sections are now <details name="faq-section"> so opening one
   auto-closes the previously-open one (native HTML 2024 behaviour).
   First section starts [open]; subsequent sections start closed.
   Tightened spacing (was 14px between sections — felt too airy when
   most sections are collapsed). scroll-margin-top so header stays
   comfortably below the sticky header when scrollIntoView fires.
   overflow-anchor prevents viewport jumps when content above shrinks. */
.el-faq-list-section { overflow-anchor: auto; }
.el-faq-group {
    margin-bottom: 4px;
    border-radius: var(--el-radius);
    scroll-margin-top: 12px;
}
.el-faq-group + .el-faq-group { margin-top: 0; }
.el-faq-group > .el-faq-group-body > details + details {
    margin-top: 8px;
}
.el-faq-group.hidden { display: none; }
.el-faq-group-title {
    font-size: 1rem;
    font-weight: 800;
    color: var(--el-text);
    letter-spacing: -0.01em;
    margin: 0;
    padding: 10px 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    list-style: none;
    background: rgba(var(--club-accent-rgb), 0.04);
    border: 1px solid var(--el-border);
    border-radius: var(--el-radius);
    transition: background 0.18s ease, border-radius 0.24s ease;
    user-select: none;
}
.el-faq-group-title::-webkit-details-marker { display: none; }
.el-faq-group-title:hover { background: rgba(var(--club-accent-rgb), 0.08); }
.el-faq-group[open] > .el-faq-group-title {
    background: rgba(var(--club-accent-rgb), 0.1);
    border-radius: var(--el-radius) var(--el-radius) 0 0;
    border-bottom-color: transparent;
}
.el-faq-group-title > span { flex: 1 1 auto; min-width: 0; }
.el-faq-group-title i.mdi:first-child {
    color: var(--club-accent);
    font-size: 1.2rem;
    flex: 0 0 auto;
}
.el-faq-group-caret {
    color: var(--el-text-muted);
    font-size: 1.3rem !important; /* override the :first-child rule above */
    transition: transform 0.24s cubic-bezier(0.32, 0.72, 0.32, 1);
    flex: 0 0 auto;
}
.el-faq-group[open] > .el-faq-group-title .el-faq-group-caret {
    transform: rotate(180deg);
    color: var(--el-accent);
}
.el-faq-group-body {
    padding: 12px;
    border: 1px solid var(--el-border);
    border-top: 0;
    border-radius: 0 0 var(--el-radius) var(--el-radius);
    background: var(--el-surface, transparent);
    /* Fade the body in when the section opens — CSS-only, native details
       fires this on the [open] state flip. Doesn't animate the height
       (which would need a JS-driven max-height dance) but the opacity +
       tiny translateY takes the edge off the instant snap. */
    animation: el-faq-body-in 0.28s cubic-bezier(0.32, 0.72, 0.32, 1) both;
}
@keyframes el-faq-body-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .el-faq-group-body { animation: none; }
    .el-faq-group-caret { transition: none; }
}
html.night-mode .el-faq-group-title i.mdi:first-child { color: var(--el-accent); }
html.night-mode .el-faq-group-title {
    background: rgba(255, 255, 255, 0.03);
}
html.night-mode .el-faq-group-title:hover {
    background: rgba(255, 255, 255, 0.06);
}
html.night-mode .el-faq-group[open] > .el-faq-group-title {
    background: rgba(255, 255, 255, 0.08);
}

/* Hide individual FAQ items when filtered out */
.el-accordion-item.hidden { display: none !important; }

/* Empty state */
.el-faq-empty {
    text-align: center;
    padding: 56px 24px;
    background: var(--el-surface-alt);
    border: 1px dashed var(--el-border);
    border-radius: var(--el-radius-lg);
    color: var(--el-text-muted);
}
.el-faq-empty.hidden { display: none; }
.el-faq-empty i {
    font-size: 2.8rem;
    color: var(--club-accent);
    display: block;
    margin-bottom: 12px;
}
.el-faq-empty h3 {
    margin: 0 0 8px;
    color: var(--el-text);
    font-size: 1.2rem;
    font-weight: 800;
}
.el-faq-empty p { margin: 0; font-size: 0.94rem; }
html.night-mode .el-faq-empty i { color: var(--el-accent); }

/* ── Ask the Club (AI) ─────────────────────────────────────────────── */
.el-faq-ask {
    background: linear-gradient(135deg, var(--el-hero) 0%, var(--el-hero-deep) 100%);
    color: var(--el-text-inv);
    position: relative;
    overflow: hidden;
}
/* Night mode: drop the section's solid navy to a translucent overlay so
   the global spotlights canvas (positioned on body, z-index 0) bleeds
   through. Body's #000 backdrop + the canvas's screen-blended accent
   orbs paint behind this tint, giving a navy ambience with visible
   spotlights instead of an opaque navy cap covering everything. */
html.night-mode .el-faq-ask {
    background: linear-gradient(135deg, rgba(2, 12, 146, 0.55) 0%, rgba(0, 6, 89, 0.55) 100%);
}
.el-faq-ask::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 15% 20%, rgba(188, 255, 0, 0.08), transparent 45%),
        radial-gradient(circle at 85% 80%, rgba(125, 211, 252, 0.08), transparent 40%);
    pointer-events: none;
}
.el-faq-ask > .el-container { position: relative; z-index: 1; }

/* Ask-the-Club card — white cutout in light mode (solid white card
   on the navy section), pure transparent cutout in night mode (just a
   sky-blue outline; the section navy shows through unchanged). */
.el-faq-ask-card {
    max-width: 820px;
    margin: 0 auto;
    background: #ffffff;
    border: 1px solid rgba(2, 12, 146, 0.12);
    border-radius: var(--el-radius-lg);
    padding: clamp(28px, 4vw, 44px);
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.20);
}
html.night-mode .el-faq-ask-card {
    background: transparent;
    border: 1px solid rgba(125, 211, 252, 0.30);
    box-shadow: none;
    /* No backdrop-filter — we want the section navy to show through
       unchanged, not a frosted-glass overlay that lightens the card. */
}
.el-faq-ask-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--el-accent);
    text-shadow: 0 0 12px rgba(125, 211, 252, 0.45);
    margin-bottom: 10px;
}
.el-faq-ask-eyebrow i { font-size: 0.92rem; }
.el-faq-ask-title {
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    font-weight: 800;
    color: var(--el-text);
    letter-spacing: -0.015em;
    line-height: 1.2;
    margin: 0 0 10px;
}
html.night-mode .el-faq-ask-title { color: var(--el-text-inv); }
.el-faq-ask-sub {
    color: var(--el-text-muted);
    font-size: 0.96rem;
    line-height: 1.6;
    margin: 0 0 22px;
}
html.night-mode .el-faq-ask-sub { color: var(--el-text-inv-muted); }
.el-faq-ask-sub strong {
    color: var(--el-accent);
    font-weight: 700;
    text-shadow: 0 0 12px rgba(125, 211, 252, 0.35);
}

/* Form: textarea + submit side-by-side on wide, stacked on mobile */
.el-faq-ask-form {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: stretch;
}
.el-faq-ask-input-wrap {
    flex: 1;
    min-width: 280px;
    position: relative;
}
/* Textarea — defaults to LIGHT-mode treatment (navy text on the white
   card). Night-mode overrides below flip back to the white-on-navy
   pattern that matches the rest of the FAQ section in dark. */
.el-faq-ask-form textarea {
    width: 100%;
    min-height: 92px;
    border-radius: var(--el-radius);
    border: 1px solid rgba(2, 12, 146, 0.18);
    background: rgba(2, 12, 146, 0.03);
    color: var(--el-text);
    font-family: inherit;
    font-size: 1rem;
    padding: 14px 16px 28px;
    resize: vertical;
    transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;
}
.el-faq-ask-form textarea::placeholder {
    color: rgba(2, 12, 146, 0.45);
}
.el-faq-ask-form textarea:focus {
    outline: none;
    border-color: var(--el-accent);
    background: rgba(125, 211, 252, 0.06);
    box-shadow: 0 0 0 3px rgba(125, 211, 252, 0.18);
}
html.night-mode .el-faq-ask-form textarea {
    border-color: rgba(255, 255, 255, 0.20);
    background: rgba(255, 255, 255, 0.04);
    color: var(--el-text-inv);
}
html.night-mode .el-faq-ask-form textarea::placeholder {
    color: rgba(255, 255, 255, 0.5);
}
html.night-mode .el-faq-ask-form textarea:focus {
    border-color: var(--el-green);
    background: rgba(255, 255, 255, 0.08);
    box-shadow: 0 0 0 3px rgba(188, 255, 0, 0.15);
}
.el-faq-ask-counter {
    position: absolute;
    right: 12px;
    bottom: 8px;
    font-size: 0.72rem;
    color: rgba(2, 12, 146, 0.5);
    pointer-events: none;
}
html.night-mode .el-faq-ask-counter {
    color: rgba(255, 255, 255, 0.45);
}
/* Ask submit + the surrounding card use a cutout treatment — white
   pill in light mode, transparent pill in night mode — so the FAQ
   page reserves the green primary CTA for elsewhere on the site. */
.el-faq-ask-submit {
    background: #ffffff;
    color: var(--el-hero);
    border: 2px solid var(--el-hero);
    border-radius: var(--el-radius);
    padding: 0 28px;
    font-size: 0.95rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    transition: transform 0.15s, box-shadow 0.25s, background 0.2s, color 0.2s;
    min-height: 60px;
    align-self: flex-start;
}
.el-faq-ask-submit i { font-size: 1.15rem; }
.el-faq-ask-submit:hover:not([disabled]) {
    background: var(--el-hero);
    color: #ffffff;
    transform: translateY(-2px);
    box-shadow: 0 12px 28px rgba(2, 12, 146, 0.30);
}
html.night-mode .el-faq-ask-submit {
    background: transparent;
    color: var(--el-text);
    border-color: rgba(125, 211, 252, 0.45);
}
html.night-mode .el-faq-ask-submit:hover:not([disabled]) {
    background: rgba(125, 211, 252, 0.10);
    color: var(--el-text);
    border-color: rgba(125, 211, 252, 0.85);
    box-shadow: 0 12px 28px rgba(125, 211, 252, 0.30);
}
.el-faq-ask-submit[disabled] { opacity: 0.6; cursor: not-allowed; }
.el-faq-ask-submit.is-loading i { animation: faqPulse 1s ease infinite; }
@keyframes faqPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* Example chips */
.el-faq-ask-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin-top: 22px;
}
/* Chips — defaults to LIGHT-mode (navy text on white card). Night-mode
   overrides below restore the white-on-navy treatment for the
   transparent cutout card. */
.el-faq-ask-chip-label {
    font-size: 0.78rem;
    color: var(--el-text-muted);
    margin-right: 4px;
}
html.night-mode .el-faq-ask-chip-label {
    color: var(--el-text-inv-muted);
}
.el-faq-ask-chip {
    padding: 6px 14px;
    border-radius: 999px;
    background: rgba(2, 12, 146, 0.04);
    border: 1px solid rgba(2, 12, 146, 0.18);
    color: var(--el-text);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s, color 0.2s, transform 0.15s;
}
.el-faq-ask-chip:hover {
    background: rgba(125, 211, 252, 0.18);
    border-color: var(--el-accent);
    color: var(--el-hero);
    transform: translateY(-1px);
}
html.night-mode .el-faq-ask-chip {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.15);
    color: var(--el-text-inv);
}
html.night-mode .el-faq-ask-chip:hover {
    background: rgba(125, 211, 252, 0.20);
    border-color: var(--el-accent);
    color: var(--el-accent);
    transform: translateY(-1px);
}

/* Response panel */
/* Response panel — defaults to LIGHT-mode (sits inside white card).
   Night-mode below restores the inv treatment. Header eyebrow is
   sky-blue in light mode (matches the page accent), green in dark
   (the existing high-energy treatment). */
.el-faq-ask-response {
    margin-top: 22px;
    background: rgba(2, 12, 146, 0.03);
    border: 1px solid rgba(125, 211, 252, 0.35);
    border-radius: var(--el-radius);
    overflow: hidden;
}
.el-faq-ask-response.hidden { display: none; }
html.night-mode .el-faq-ask-response {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(188, 255, 0, 0.22);
}
.el-faq-ask-response-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    background: rgba(125, 211, 252, 0.10);
    border-bottom: 1px solid rgba(125, 211, 252, 0.25);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--el-accent);
}
html.night-mode .el-faq-ask-response-head {
    background: rgba(188, 255, 0, 0.10);
    border-bottom-color: rgba(188, 255, 0, 0.20);
    color: var(--el-green);
}
.el-faq-ask-response-head i { font-size: 1rem; }
.el-faq-ask-tier-pill {
    margin-left: auto;
    background: rgba(2, 12, 146, 0.08);
    color: var(--el-text);
    font-size: 0.64rem;
    letter-spacing: 0.1em;
    padding: 3px 10px;
    border-radius: 999px;
    text-transform: uppercase;
    border: 1px solid rgba(2, 12, 146, 0.18);
}
html.night-mode .el-faq-ask-tier-pill {
    background: rgba(255, 255, 255, 0.1);
    color: var(--el-text-inv);
    border-color: rgba(255, 255, 255, 0.18);
}
.el-faq-ask-tier-pill[hidden] { display: none; }
.el-faq-ask-tier-pill.is-member {
    background: rgba(125, 211, 252, 0.18);
    color: var(--el-hero);
    border-color: var(--el-accent);
}
html.night-mode .el-faq-ask-tier-pill.is-member {
    background: rgba(188, 255, 0, 0.20);
    color: var(--el-green);
    border-color: rgba(188, 255, 0, 0.40);
}
.el-faq-ask-response-body {
    padding: 20px 22px;
    font-size: 0.96rem;
    line-height: 1.65;
    color: var(--el-text);
}
html.night-mode .el-faq-ask-response-body { color: var(--el-text-inv); }
.el-faq-ask-response-body p { margin: 0 0 12px; }
.el-faq-ask-response-body p:last-child { margin-bottom: 0; }
.el-faq-ask-response-foot {
    padding: 10px 22px 14px;
    font-size: 0.78rem;
    color: var(--el-text-muted);
    display: flex;
    align-items: center;
    gap: 6px;
    border-top: 1px solid rgba(2, 12, 146, 0.08);
}
html.night-mode .el-faq-ask-response-foot {
    color: var(--el-text-inv-muted);
    border-top-color: rgba(255, 255, 255, 0.08);
}
.el-faq-ask-response-foot i { font-size: 0.92rem; color: var(--el-accent); }
html.night-mode .el-faq-ask-response-foot i { color: var(--el-green); }

/* "Thinking…" loader with dot pulse */
.el-faq-ask-thinking {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--el-text-muted);
    font-style: italic;
}
html.night-mode .el-faq-ask-thinking { color: var(--el-text-inv-muted); }
.el-faq-ask-dot {
    display: inline-block;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--el-green);
    animation: faqDot 1.1s ease infinite;
}
.el-faq-ask-dot:nth-child(2) { animation-delay: 0.18s; }
.el-faq-ask-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes faqDot {
    0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
    40%           { transform: scale(1);   opacity: 1;   }
}

/* Error state */
.el-faq-ask-err {
    margin-top: 14px;
    padding: 12px 16px;
    border-radius: var(--el-radius);
    background: rgba(239, 68, 68, 0.15);
    border: 1px solid rgba(239, 68, 68, 0.35);
    color: #fecaca;
    font-size: 0.9rem;
    display: flex;
    align-items: center;
    gap: 10px;
}
.el-faq-ask-err.hidden { display: none; }
.el-faq-ask-err i { font-size: 1.15rem; color: #fca5a5; }

/* Responsive rhythm */
@media (max-width: 560px) {
    .el-faq-ask-submit { width: 100%; }
    .el-faq-group-title { font-size: 1.05rem; }
}

/* ══════════════════════════════════════════════════════════════════════
   ACE TENNYSON — floating AI assistant (injected on every page)

   Layout: a circular FAB at bottom-right, positioned ABOVE the
   existing WhatsApp FAB so both are accessible. When opened it
   expands into a bottom-right chat panel (~380 × 560 on desktop,
   full-width drawer on mobile).
   ══════════════════════════════════════════════════════════════════════ */

/* ── FAB ──────────────────────────────────────────────────────────── */
.el-ace-fab {
    position: fixed;
    bottom: 96px;            /* above the WhatsApp FAB (bottom:24, 56+16 gap) */
    right: 24px;
    z-index: 90;
    width: 56px; height: 56px;
    border-radius: 50%;
    border: 0;
    padding: 0;
    cursor: pointer;
    background: linear-gradient(135deg, var(--el-hero) 0%, var(--el-hero-deep) 100%);
    color: var(--el-green);
    display: grid;
    place-items: center;
    box-shadow:
        0 4px 16px rgba(2, 12, 146, 0.4),
        0 2px 6px rgba(0, 0, 0, 0.25);
    transition: transform 0.25s var(--el-ease-soft), box-shadow 0.25s, opacity 0.25s;
}
.el-ace-fab:hover {
    transform: scale(1.08);
    box-shadow:
        0 8px 24px rgba(2, 12, 146, 0.5),
        0 0 0 3px rgba(188, 255, 0, 0.25);
}
.el-ace-fab.is-hidden {
    opacity: 0;
    transform: scale(0.6);
    pointer-events: none;
}

/* Green halo pulse — hints at activity */
.el-ace-fab-pulse {
    position: absolute;
    inset: -6px;
    border-radius: 50%;
    border: 2px solid var(--el-green);
    opacity: 0;
    animation: aceFabPulse 2.4s ease-out infinite;
    pointer-events: none;
}
@keyframes aceFabPulse {
    0%   { transform: scale(0.7);  opacity: 0.7; }
    80%  { transform: scale(1.15); opacity: 0;   }
    100% { transform: scale(1.15); opacity: 0;   }
}

.el-ace-fab-avatar {
    position: relative;
    z-index: 1;
    width: 100%; height: 100%;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: radial-gradient(circle at 30% 30%, rgba(188, 255, 0, 0.18), transparent 65%);
}
.el-ace-fab-avatar i { font-size: 1.7rem; }

/* Notification dot for first-visit users */
.el-ace-fab-dot {
    position: absolute;
    top: 6px; right: 6px;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: #ef4444;
    border: 2px solid var(--el-hero);
    box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.35);
    opacity: 0;
    transform: scale(0);
    transition: opacity 0.2s, transform 0.25s var(--el-ease-soft);
    z-index: 2;
}
.el-ace-fab-dot.is-visible {
    opacity: 1;
    transform: scale(1);
}

/* ── Chat panel ────────────────────────────────────────────────────── */
.el-ace-panel {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 100;
    width: 380px;
    max-width: calc(100vw - 32px);
    height: 560px;
    max-height: calc(100vh - 48px);
    background: #ffffff;
    border-radius: 20px;
    box-shadow:
        0 24px 80px rgba(2, 12, 146, 0.28),
        0 0 0 1px rgba(2, 12, 146, 0.08);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transform: translateY(24px) scale(0.96);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.28s var(--el-ease-soft), opacity 0.22s;
    transform-origin: bottom right;
}
.el-ace-panel.is-open {
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
}
/* Mobile portrait — give the panel breathing room around the screen
   edges and shrink the corner offset so it doesn't feel like a popup
   that's been squeezed in. Width still capped by max-width above. */
@media (max-width: 480px) {
    .el-ace-panel {
        right: 8px;
        bottom: 8px;
        max-width: calc(100vw - 16px);
        max-height: calc(100dvh - 16px);
    }
}
/* Landscape phone (e.g. 915x412) — viewport is too short for the
   default 560px panel height. Cap height tightly so the panel doesn't
   bleed off the top edge or hide its scrollbar. */
@media (max-height: 500px) {
    .el-ace-panel {
        height: calc(100dvh - 24px);
        max-height: calc(100dvh - 24px);
        bottom: 12px;
    }
}
html.night-mode .el-ace-panel {
    background: #0f1016;
    box-shadow:
        0 24px 80px rgba(0, 0, 0, 0.75),
        0 0 0 1px rgba(255, 255, 255, 0.08);
}

/* Head */
.el-ace-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 14px 14px 18px;
    background: linear-gradient(135deg, var(--el-hero) 0%, var(--el-hero-deep) 100%);
    color: var(--el-text-inv);
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    position: relative;
}
.el-ace-head::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 85% 20%, rgba(188, 255, 0, 0.1), transparent 55%);
    pointer-events: none;
}
.el-ace-head-avatar {
    position: relative;
    width: 42px; height: 42px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(125, 211, 252, 0.22);
    color: var(--el-accent);
    flex-shrink: 0;
    z-index: 1;
}
.el-ace-head-avatar i { font-size: 1.4rem; }
.el-ace-head-text {
    flex: 1;
    min-width: 0;
    position: relative;
    z-index: 1;
}
.el-ace-head-name {
    font-weight: 800;
    font-size: 1.02rem;
    letter-spacing: -0.01em;
    color: var(--el-text-inv);
}
.el-ace-head-status {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.76rem;
    color: var(--el-text-inv-muted);
    margin-top: 2px;
}
.el-ace-head-dot {
    display: inline-block;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--el-accent);
    box-shadow: 0 0 6px rgba(125, 211, 252, 0.8);
    animation: aceStatusPulse 2s ease-in-out infinite;
}
@keyframes aceStatusPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }

.el-ace-head-close,
.el-ace-head-icon {
    position: relative;
    z-index: 1;
    width: 34px; height: 34px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.08);
    border: 0;
    color: var(--el-text-inv);
    font-size: 1.2rem;
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: background 0.2s;
}
.el-ace-head-close:hover,
.el-ace-head-icon:hover { background: rgba(255, 255, 255, 0.18); }
.el-ace-head-icon { margin-right: 4px; }

/* ── Docked-mode panel ─────────────────────────────────────────────
   When body.el-ace-docked is set:
     1. The panel becomes a full-height column on the right edge
     2. The body gets padding-right so page content reflows around it
     3. The corner-resize handle is replaced by a left-edge grip
   Width comes from --el-ace-dock-w (CSS var on <html>) so the JS can
   smoothly drag-resize without recalculating any sibling layout. */
.el-ace-panel--docked {
    /* Override the floating-card geometry. The rail slots BELOW the
       sticky nav (top offset = --el-nav-h) so the panel header +
       greeting are never obscured by the club-brand nav bar. Height
       clamps to the remaining viewport. */
    bottom: 0    !important;
    right:  0    !important;
    top:    var(--el-nav-h, 81px) !important;
    height: calc(100vh  - var(--el-nav-h, 81px)) !important;
    height: calc(100dvh - var(--el-nav-h, 81px)) !important;
    width:  var(--el-ace-dock-w, 400px) !important;
    max-width:  var(--el-ace-dock-w, 400px) !important;
    max-height: calc(100vh - var(--el-nav-h, 81px)) !important;
    border-radius: 0 !important;
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.18) !important;
    transform: none !important;       /* was a slide-up; not needed when docked */
    transform-origin: right top !important;
}
/* Body content reflows — clears the right edge by the docked width.
   The sticky nav is REBATED back to full viewport width via a matching
   negative right-margin. Rationale: the docked rail now slots BELOW
   the nav (top: var(--el-nav-h)), so the nav's right-hand action
   icons (guest chip, night toggle, cart) belong ABOVE the rail — the
   old shrink-the-nav-too behaviour left them stranded 400px inside
   the viewport with blank body-bg on the right. Reclaiming the space
   on the nav specifically keeps main content shifted (so scrolling
   article body doesn't slide under the rail) while the header sits
   full-width above it. */
body.el-ace-docked { padding-right: var(--el-ace-dock-w, 400px); }
body.el-ace-docked .el-nav { margin-right: calc(-1 * var(--el-ace-dock-w, 400px)); }
/* But not on phones — bottom-sheet floats over instead */
@media (max-width: 720px) {
    body.el-ace-docked { padding-right: 0; }
    body.el-ace-docked .el-nav { margin-right: 0; }
}

/* Left-edge resize grip — only visible when docked. Mirrors the
   corner-resize on the floating panel, but on the left edge with a
   col-resize cursor and a wider hit target. */
.el-ace-dock-grip {
    position: absolute;
    top: 0; left: 0;
    width: 6px; height: 100%;
    cursor: col-resize;
    z-index: 10;
    background: transparent;
    transition: background 0.18s;
    display: none;
    touch-action: none;
}
.el-ace-panel--docked .el-ace-dock-grip { display: block; }
.el-ace-dock-grip:hover {
    background: linear-gradient(to right, transparent, rgba(125, 211, 252, 0.45), transparent);
}
/* Hide the corner resize handle when docked (left grip replaces it) */
.el-ace-panel--docked .el-ace-resize { display: none; }
/* And hide the dock grip + toggle on mobile (we force-float) */
@media (max-width: 720px) {
    .el-ace-dock-grip,
    .el-ace-head-icon { display: none !important; }
}

/* Log area — scrollable chat */
.el-ace-log {
    flex: 1;
    overflow-y: auto;
    padding: 18px 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    background:
        linear-gradient(180deg, rgba(232, 241, 248, 0.3), rgba(232, 241, 248, 0) 80px),
        #ffffff;
    scroll-behavior: smooth;
    scrollbar-width: thin;
    scrollbar-color: rgba(2, 12, 146, 0.2) transparent;
}
.el-ace-log::-webkit-scrollbar { width: 6px; }
.el-ace-log::-webkit-scrollbar-thumb { background: rgba(2, 12, 146, 0.2); border-radius: 999px; }
html.night-mode .el-ace-log {
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 80px),
        #0f1016;
    scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
}

/* Message bubbles */
.el-ace-msg {
    display: flex;
    gap: 10px;
    max-width: 92%;
    animation: aceMsgIn 0.3s var(--el-ease-soft);
}
@keyframes aceMsgIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.el-ace-msg--user {
    align-self: flex-end;
    flex-direction: row-reverse;
}
.el-ace-msg-avatar {
    width: 30px; height: 30px;
    border-radius: 50%;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--club-accent) 10%, transparent);
    color: var(--club-accent);
    display: grid;
    place-items: center;
}
.el-ace-msg-avatar i { font-size: 1.05rem; }
html.night-mode .el-ace-msg-avatar {
    background: rgba(125, 211, 252, 0.14);
    color: var(--el-accent);
}

.el-ace-msg-bubble {
    padding: 10px 14px;
    border-radius: 14px;
    font-size: 0.92rem;
    line-height: 1.55;
    color: var(--el-text);
    max-width: 100%;
    word-wrap: break-word;
}
.el-ace-msg--bot .el-ace-msg-bubble {
    background: #f1f5f9;
    border: 1px solid rgba(2, 12, 146, 0.06);
    border-top-left-radius: 4px;
}
.el-ace-msg--user .el-ace-msg-bubble {
    background: var(--club-accent);
    color: var(--club-accent-text);
    border-top-right-radius: 4px;
}
html.night-mode .el-ace-msg--bot .el-ace-msg-bubble {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.08);
    color: var(--el-text);
}
html.night-mode .el-ace-msg--user .el-ace-msg-bubble {
    background: var(--el-accent);
    color: var(--el-hero);
}

.el-ace-msg-bubble a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.el-ace-msg--bot .el-ace-msg-bubble a {
    color: var(--club-accent);
    font-weight: 700;
}
html.night-mode .el-ace-msg--bot .el-ace-msg-bubble a { color: var(--el-accent); }

.el-ace-msg-meta {
    margin-top: 6px;
    font-size: 0.7rem;
    color: var(--el-text-muted);
    letter-spacing: 0.02em;
}
html.night-mode .el-ace-msg-meta { color: rgba(255, 255, 255, 0.45); }

/* Markdown output inside bot bubbles — tighter paragraph rhythm and
   a compact bullet list with accent-coloured dots. */
.el-ace-msg-body > p {
    margin: 0;
}
.el-ace-msg-body > p + p,
.el-ace-msg-body > p + ul,
.el-ace-msg-body > ul + p {
    margin-top: 8px;
}
.el-ace-msg-body strong { font-weight: 700; }
.el-ace-msg-body em { font-style: italic; }
.el-ace-md-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.el-ace-md-list li {
    position: relative;
    padding-left: 16px;
    line-height: 1.5;
}
.el-ace-md-list li::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 0.62em;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--club-accent);
}
html.night-mode .el-ace-md-list li::before { background: var(--el-accent); }

/* FAQ inline ask — same treatment, slightly larger type */
.el-faq-ask-md-list {
    list-style: none;
    margin: 10px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.el-faq-ask-md-list li {
    position: relative;
    padding-left: 18px;
    line-height: 1.55;
}
.el-faq-ask-md-list li::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 0.65em;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--el-green);
}
.el-faq-ask-response-body p + p,
.el-faq-ask-response-body p + ul,
.el-faq-ask-response-body ul + p {
    margin-top: 10px;
}
.el-faq-ask-response-body strong { font-weight: 700; color: var(--el-green); }

/* CTA chips inside a bot bubble — each links to a /preview/... page
   or a tel:/mailto: handler. Tap = navigate + (internally) set the
   reopen flag so the NEXT page's Ace auto-opens with the thread.

   Selector specificity note: the generic `.el-ace-msg-bubble a` rule
   above sets `color: inherit`, which beats a plain `.el-ace-cta`
   selector (same specificity but defined earlier in the cascade).
   We scope the CTA rules to `.el-ace-msg-bubble .el-ace-cta` to
   match specificity + tilt the tie-break so the button colours
   actually paint through. */
.el-ace-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}
.el-ace-msg-bubble .el-ace-cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 999px;
    background: var(--club-accent);
    color: #ffffff;
    font-size: 0.82rem;
    font-weight: 700;
    text-decoration: none;
    border: 1px solid transparent;
    transition: transform 0.15s, box-shadow 0.2s, background 0.2s;
    line-height: 1.2;
}
.el-ace-msg-bubble .el-ace-cta i {
    font-size: 1rem;
    color: #ffffff;
}
.el-ace-msg-bubble .el-ace-cta:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(2, 12, 146, 0.28);
    background: #1a2cc7;
    color: #ffffff;
}
html.night-mode .el-ace-msg-bubble .el-ace-cta,
html.night-mode .el-ace-msg-bubble .el-ace-cta span,
html.night-mode .el-ace-msg-bubble .el-ace-cta i {
    /* !important so night-mode readability beats the inline white
       that ace.js pins for day-mode belt-and-braces. */
    color: var(--el-hero) !important;
}
html.night-mode .el-ace-msg-bubble .el-ace-cta {
    background: var(--el-accent);
}
html.night-mode .el-ace-msg-bubble .el-ace-cta:hover {
    background: #a4dffb;
    box-shadow: 0 6px 18px rgba(125, 211, 252, 0.35);
}

/* FAQ inline ask — same CTA pattern, slightly larger to match the
   inline panel's more generous type scale. */
.el-faq-ask-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 14px;
}
.el-faq-ask-cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 16px;
    border-radius: 999px;
    background: var(--el-green);
    color: var(--el-green-text);
    font-size: 0.86rem;
    font-weight: 800;
    text-decoration: none;
    border: 1px solid transparent;
    transition: transform 0.15s, box-shadow 0.2s, background 0.2s;
    line-height: 1.2;
}
.el-faq-ask-cta i { font-size: 1.02rem; }
.el-faq-ask-cta:hover {
    transform: translateY(-1px);
    background: #a6e800;
    box-shadow: 0 8px 22px rgba(188, 255, 0, 0.4);
}

/* Thinking bubble */
.el-ace-msg--thinking .el-ace-msg-bubble {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 14px 18px;
}
.el-ace-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--club-accent);
    animation: aceDot 1.2s ease-in-out infinite;
}
.el-ace-dot:nth-child(2) { animation-delay: 0.18s; }
.el-ace-dot:nth-child(3) { animation-delay: 0.36s; }
@keyframes aceDot {
    0%, 80%, 100% { transform: scale(0.55); opacity: 0.4; }
    40%           { transform: scale(1);    opacity: 1;   }
}
html.night-mode .el-ace-dot { background: var(--el-accent); }

/* Suggestion chips — above the input */
.el-ace-suggestions {
    display: flex;
    gap: 6px;
    padding: 10px 12px 4px;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    flex-wrap: nowrap;
    border-top: 1px solid rgba(2, 12, 146, 0.06);
    background: #ffffff;
}
.el-ace-suggestions::-webkit-scrollbar { display: none; }
html.night-mode .el-ace-suggestions {
    background: #0f1016;
    border-top-color: rgba(255, 255, 255, 0.06);
}
.el-ace-chip {
    flex-shrink: 0;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--el-surface);
    border: 1px solid var(--el-border);
    color: var(--el-text);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.18s, color 0.18s, border-color 0.18s;
}
.el-ace-chip:hover {
    background: var(--club-accent);
    color: var(--club-accent-text);
    border-color: var(--club-accent);
}
html.night-mode .el-ace-chip {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.1);
    color: var(--el-text);
}
html.night-mode .el-ace-chip:hover {
    background: var(--el-green);
    color: var(--el-green-text);
    border-color: var(--el-green);
}

/* Input form */
.el-ace-form {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    padding: 10px 12px 14px;
    background: #ffffff;
    border-top: 1px solid rgba(2, 12, 146, 0.06);
}
html.night-mode .el-ace-form {
    background: #0f1016;
    border-top-color: rgba(255, 255, 255, 0.06);
}
.el-ace-input {
    flex: 1;
    min-height: 74px;            /* ~3 rows */
    max-height: 180px;
    padding: 10px 14px;
    border-radius: 18px;
    border: 1px solid var(--el-border);
    background: var(--el-surface);
    color: var(--el-text);
    font-family: inherit;
    font-size: 0.92rem;
    line-height: 1.45;
    resize: none;
    outline: none;
    transition: border-color 0.2s, background 0.2s;
}
.el-ace-input:focus {
    border-color: var(--club-accent);
    background: #ffffff;
    box-shadow: 0 0 0 3px rgba(2, 12, 146, 0.08);
}
html.night-mode .el-ace-input {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.1);
    color: var(--el-text);
}
html.night-mode .el-ace-input:focus {
    border-color: var(--el-green);
    background: rgba(255, 255, 255, 0.06);
    box-shadow: 0 0 0 3px rgba(188, 255, 0, 0.14);
}

.el-ace-form {
    align-items: flex-end;   /* keep the circular send button aligned with the tall input's bottom */
}
.el-ace-send {
    flex-shrink: 0;
    width: 40px; height: 40px;
    border-radius: 50%;
    border: 0;
    background: var(--club-accent);
    color: var(--club-accent-text);
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: transform 0.15s, background 0.2s, box-shadow 0.25s;
}
.el-ace-send:hover:not([disabled]) {
    transform: translateY(-1px) scale(1.04);
    box-shadow: 0 6px 20px rgba(2, 12, 146, 0.3);
}
.el-ace-send[disabled] { opacity: 0.5; cursor: not-allowed; }
.el-ace-send i { font-size: 1.2rem; }
html.night-mode .el-ace-send {
    background: var(--el-accent);
    color: var(--el-hero);
}
html.night-mode .el-ace-send:hover:not([disabled]) {
    box-shadow: 0 6px 20px rgba(125, 211, 252, 0.35);
}

/* ── Resize handle (top-left corner — drag to grow) ────────────────
   Panel is anchored bottom-right, so dragging the top-left handle
   LEFT grows width, UP grows height. The visible corner shows three
   stacked diagonal bars (like a native OS resize grip) so it's
   discoverable without being loud. */
.el-ace-resize {
    position: absolute;
    top: 0; left: 0;
    width: 22px; height: 22px;
    cursor: nwse-resize;
    z-index: 5;
    background-image:
        linear-gradient(135deg, transparent 0, transparent 38%,
            rgba(255, 255, 255, 0.55) 38%, rgba(255, 255, 255, 0.55) 44%,
            transparent 44%, transparent 52%,
            rgba(255, 255, 255, 0.45) 52%, rgba(255, 255, 255, 0.45) 58%,
            transparent 58%, transparent 66%,
            rgba(255, 255, 255, 0.35) 66%, rgba(255, 255, 255, 0.35) 72%,
            transparent 72%);
    transition: opacity 0.2s;
    opacity: 0.7;
    touch-action: none;
}
.el-ace-resize:hover { opacity: 1; }
/* While actively dragging, disable pointer events on content so the
   user's pointer can't accidentally trigger other things. */
.el-ace-panel[data-resizing] .el-ace-log,
.el-ace-panel[data-resizing] .el-ace-form,
.el-ace-panel[data-resizing] .el-ace-suggestions {
    pointer-events: none;
    user-select: none;
}

/* ── Mobile: panel becomes a bottom-sheet ──────────────────────────── */
@media (max-width: 600px) {
    .el-ace-panel {
        bottom: 0;
        right: 0;
        left: 0;
        width: 100%;
        max-width: 100%;
        height: min(80vh, 620px);
        max-height: 85vh;
        border-radius: 18px 18px 0 0;
        transform: translateY(32px);
        transform-origin: bottom center;
    }
    .el-ace-panel.is-open {
        transform: translateY(0);
    }
    .el-ace-fab {
        bottom: 88px;
        /* Match the WhatsApp FAB's right offset (24px) — was set to
           16px which left the Ace button visibly out of column with
           the WhatsApp button stacked below it on narrow screens. */
        right: 24px;
    }
    /* Disable the corner resize on mobile — the bottom-sheet layout
       takes the full width so drag-resizing doesn't make sense. */
    .el-ace-resize { display: none; }
}

/* Never show the edit FAB when Ace panel is open (prevents overlap) */
.el-ace-panel.is-open ~ .el-edit-fab {
    opacity: 0;
    pointer-events: none;
}

/* ══ Night-mode overrides for the injected builder chrome ══════════
   The cart drawer, checkout modal, login modal and My Memberships
   drawer are injected into <body> by club-site.js using CSS vars
   (--club-bg / --club-text / --club-border / --club-card-bg) that
   only get their night values written when club-site.js's OWN
   setupNightMode fires. The Eldoraigne bespoke site uses its own
   toggle handler (eldoraigne.js) which deliberately skips that
   binding, so the drawers stayed in day colours. These scoped
   overrides paint them dark when html.night-mode is on. */
html.night-mode .cs-cart-drawer,
html.night-mode .cs-cart-backdrop + .cs-cart-drawer,
html.night-mode #cs-checkout-modal .cs-modal-panel,
html.night-mode #cs-login-modal    .cs-modal-panel,
html.night-mode .cs-mymem-drawer {
    background: #0a0d14;
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.08);
}
html.night-mode .cs-cart-header,
html.night-mode .cs-cart-footer,
html.night-mode .cs-mymem-header {
    border-color: rgba(255, 255, 255, 0.08);
}
html.night-mode .cs-cart-title,
html.night-mode .cs-cart-item-name,
html.night-mode .cs-cart-footer > *,
html.night-mode .cs-cart-empty,
html.night-mode .cs-mymem-title,
html.night-mode #cs-checkout-modal .cs-modal-title,
html.night-mode #cs-login-modal    .cs-modal-title {
    color: #ffffff;
}
html.night-mode .cs-cart-close-btn,
html.night-mode .cs-modal-close {
    color: rgba(255, 255, 255, 0.65);
}
html.night-mode .cs-cart-close-btn:hover,
html.night-mode .cs-modal-close:hover {
    color: #ffffff;
    background: rgba(255, 255, 255, 0.08);
}
html.night-mode .cs-cart-item {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.08);
}
html.night-mode .cs-cart-item-price,
html.night-mode .cs-cart-item-deposit {
    color: var(--el-accent);
}
html.night-mode .cs-cart-item-discount,
html.night-mode .cs-cart-item-sub {
    color: rgba(255, 255, 255, 0.55);
}
html.night-mode .cs-cart-backdrop,
html.night-mode .cs-modal-backdrop {
    background: rgba(0, 0, 0, 0.72);
}
/* Form inputs inside checkout + login modals */
html.night-mode #cs-checkout-modal input,
html.night-mode #cs-checkout-modal textarea,
html.night-mode #cs-checkout-modal select,
html.night-mode #cs-login-modal input {
    background: rgba(255, 255, 255, 0.04);
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.12);
}
html.night-mode #cs-checkout-modal input::placeholder,
html.night-mode #cs-login-modal input::placeholder {
    color: rgba(255, 255, 255, 0.4);
}

/* ══ Home testimonials section — white surface ════════════════════════
   3 quote cards under a "Why Our Members Love Eldoraigne" heading.
   Cards carry the same 4-layer navy idle glow / 5-layer bloom as the
   court + preview cards so the panel language stays consistent. */
.el-testimonials { background: #ffffff; }
html.night-mode .el-testimonials { background: #0d0f14; }

.el-testimonial-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 24px;
    margin-top: 40px;
}
@media (max-width: 900px) { .el-testimonial-grid { grid-template-columns: 1fr; } }

/* ── Mobile carousel — horizontal scroll-snap ──────────────────────
   On narrow screens the home-page preview grids (news/events,
   memberships) and the testimonials grid all flip from a CSS grid
   to a single-row flex container that scrolls horizontally with
   scroll-snap. One card centres at a time; the user swipes left/
   right to walk through them. NOT a loop — runs ends and stops, per
   user spec. Padding is calc((100vw - 86vw) / 2) on either side so
   the first / last card sits centred when the user reaches the
   end. Scrollbar hidden across browsers for a clean swipe surface. */
@media (max-width: 720px) {
    .el-preview-cards,
    .el-testimonial-grid,
    .el-news-grid {
        display: flex !important;
        flex-wrap: nowrap !important;
        grid-template-columns: none !important;       /* override grid above */
        gap: 16px;
        margin-top: 24px;
        /* Break out of .el-container's horizontal padding so the
           carousel really does span the full viewport width. */
        margin-inline: calc(-1 * var(--el-gutter));
        width: calc(100% + 2 * var(--el-gutter));
        overflow-x: auto !important;
        overflow-y: visible;
        scroll-snap-type: x proximity;
        scroll-padding-inline: calc((100vw - 86vw) / 2);
        padding-inline: calc((100vw - 86vw) / 2);
        padding-block: 8px;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        scroll-behavior: smooth;
        /* Explicitly let the browser handle horizontal pan + page scroll.
           Default `auto` would normally cover this, but Android Chrome
           sometimes ignores horizontal pan inside `overflow-x: clip`
           ancestors unless we declare it. */
        touch-action: pan-x pan-y;
        /* `position: relative` makes this its OWN scroll container. */
        position: relative;
    }
    .el-preview-cards::-webkit-scrollbar,
    .el-testimonial-grid::-webkit-scrollbar,
    .el-news-grid::-webkit-scrollbar { display: none; }
    .el-preview-cards > *,
    .el-testimonial-grid > *,
    .el-news-grid > * {
        flex: 0 0 86vw !important;
        max-width: 86vw !important;
        width: 86vw !important;
        scroll-snap-align: center;
        scroll-snap-stop: always;
    }
}

/* ── Carousel arrow buttons ────────────────────────────────────────
   Injected by eldoraigne.js as siblings of the carousel track (so
   they don't get recycled with the cards). Positioned absolutely at
   the left/right edge of the carousel row, vertically centered on
   the cards. Hidden on desktop where the layout is a plain CSS grid
   — JS toggles their `display`. */
.el-carousel-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px; height: 44px;
    border-radius: 50%;
    background: var(--el-hero);
    color: var(--el-text-inv);
    border: 0;
    display: none;            /* default — JS shows on mobile */
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 6px 20px rgba(2, 12, 146, 0.3);
    z-index: 5;
    transition: filter 0.18s, transform 0.18s, opacity 0.18s;
    -webkit-tap-highlight-color: transparent;
}
.el-carousel-arrow:hover {
    filter: brightness(1.12);
    transform: translateY(-50%) scale(1.06);
}
.el-carousel-arrow:active {
    transform: translateY(-50%) scale(0.95);
}
.el-carousel-arrow--prev { left: 8px; }
.el-carousel-arrow--next { right: 8px; }
.el-carousel-arrow .mdi {
    pointer-events: none;
    display: block;
}
@media (max-width: 720px) {
    /* Re-enable display via flex (JS sets style.display = '' which
       falls back to this rule rather than 'none'). */
    .el-carousel-arrow { display: flex; }
}

.el-testimonial {
    display: flex;
    flex-direction: column;
    gap: 16px;
    background: #ffffff;
    border-radius: var(--el-radius-lg);
    padding: 28px 26px 24px;
    box-shadow: var(--el-glow-idle);
    transition:
        box-shadow 0.35s var(--el-ease-soft),
        transform 0.35s var(--el-ease-soft);
}
.el-testimonial:hover {
    transform: translateY(-4px);
    box-shadow: var(--el-glow-hover);
}
html.night-mode .el-testimonial {
    background: #12141b;
}

.el-testimonial-quote {
    font-size: 2.6rem;
    color: rgba(2, 12, 146, 0.18);
    line-height: 0.6;
    margin-bottom: -4px;
}
html.night-mode .el-testimonial-quote { color: rgba(188, 255, 0, 0.3); }

.el-testimonial-body {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.65;
    color: var(--el-text);
    font-style: italic;
    flex-grow: 1;
}

.el-testimonial-footer {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-top: 14px;
    border-top: 1px solid var(--el-border);
}
.el-testimonial-avatar {
    width: 36px; height: 36px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: color-mix(in srgb, var(--club-accent) 12%, transparent);
    color: var(--club-accent);
    font-weight: 800;
    font-size: 0.95rem;
    flex-shrink: 0;
}
html.night-mode .el-testimonial-avatar {
    background: color-mix(in srgb, var(--el-green) 18%, transparent);
    color: var(--el-green);
}
.el-testimonial-name {
    font-weight: 800;
    color: var(--el-text);
    font-size: 0.92rem;
}
.el-testimonial-role {
    font-size: 0.8rem;
    color: var(--el-accent);
    font-weight: 600;
    margin-top: 2px;
}

/* ══ Ready to Play? — closing CTA on sky-blue surface ═══════════════════
   Centered oversized headline with two CTAs. Uses the same light-blue
   sky gradient as the Latest Stories / Weather strips so the page
   bookends as a unified "atmospheric blue" moment. */
.el-ready {
    background: linear-gradient(180deg, #e7eefa 0%, #dce6f5 100%);
    padding: clamp(64px, 10vw, 128px) 0;
    text-align: center;
    position: relative;
    overflow: hidden;
}
html.night-mode .el-ready {
    background: linear-gradient(180deg, #12141b 0%, #0d0f14 100%);
}

/* Soft accent bloom behind the headline for extra depth — navy on
   light bg so it sits as a gentle halo rather than the screaming
   sky bloom the navy-bg version needed. */
.el-ready::before {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 640px; height: 640px;
    transform: translate(-50%, -50%);
    background: radial-gradient(closest-side, rgba(2, 12, 146, 0.08), transparent 70%);
    pointer-events: none;
}
html.night-mode .el-ready::before {
    background: radial-gradient(closest-side, rgba(125, 211, 252, 0.18), transparent 70%);
}

.el-ready-inner {
    position: relative;
    max-width: 780px;
    margin: 0 auto;
    padding: 0 var(--el-gutter);
}
.el-ready-eyebrow {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--club-accent);
    opacity: 0.9;
    margin-bottom: 18px;
}
html.night-mode .el-ready-eyebrow { color: var(--el-accent); }
.el-ready-title {
    font-size: clamp(2.6rem, 6vw, 4.8rem);
    font-weight: 900;
    color: var(--club-accent);
    margin: 0 0 20px;
    letter-spacing: -0.02em;
    line-height: 1;
    text-shadow:
        0 8px 28px rgba(2, 12, 146, 0.22),
        0 2px 6px rgba(2, 12, 146, 0.18);
}
html.night-mode .el-ready-title {
    color: var(--el-accent);
    text-shadow:
        0 10px 32px rgba(0, 0, 0, 0.55),
        0 4px 12px rgba(0, 0, 0, 0.4),
        0 2px 4px rgba(0, 0, 0, 0.3);
}
/* Italic flourish keeps the sky-blue accent so it peeks out of the
   navy headline on light bg; in night mode the whole title is already
   sky blue so the italic just reads as a subtle serif flourish. */
.el-ready-title .el-italic {
    font-size: 1.5em;
    line-height: 0.92;
    color: var(--el-accent);
    /* Strong navy halo so the flourish reads with weight on the
       sky-blue surface even at 1.5× scale. */
    text-shadow:
        0 1px 0 rgba(2, 12, 146, 0.55),
        0 4px 12px rgba(2, 12, 146, 0.4),
        0 12px 30px rgba(2, 12, 146, 0.32);
}
html.night-mode .el-ready-title .el-italic {
    color: var(--el-accent);
}
.el-ready-sub {
    font-size: 1.05rem;
    color: var(--el-text-muted);
    line-height: 1.65;
    margin: 0 auto 32px;
    max-width: 620px;
}
html.night-mode .el-ready-sub { color: var(--el-text-inv-muted); }
.el-ready-ctas {
    display: flex;
    gap: 14px;
    justify-content: center;
    flex-wrap: wrap;
}
/* Outline CTA variant tuned for the navy surface (same look the hero
   already uses, scoped here so we don't need a hero wrapper). */
.el-btn--outline-light {
    background: transparent;
    color: var(--el-text-inv);
    border: 1.5px solid rgba(255, 255, 255, 0.4);
}
.el-btn--outline-light:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.7);
    transform: translateY(-2px);
}

/* ── Programs page ──────────────────────────────────────────────────── */
.el-programs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
    margin-top: 28px;
}
.el-program-card {
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
}
.el-program-cover {
    aspect-ratio: 16 / 9;
    background-color: rgba(0, 0, 0, 0.04);
    background-size: cover;
    background-position: center;
}
html.night-mode .el-program-cover { background-color: rgba(255, 255, 255, 0.04); }
.el-program-cover--empty {
    display: flex; align-items: center; justify-content: center;
    color: var(--el-text-muted);
    font-size: 3rem;
}
.el-program-body {
    padding: 20px 22px 22px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1;
}
.el-program-title {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--el-accent, #1a3a8a);
}
.el-program-tag {
    margin: 0;
    font-size: 0.92rem;
    opacity: 0.85;
}
.el-program-coach {
    font-size: 0.82rem;
    color: var(--el-text-muted);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.el-program-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 4px;
}
.el-program-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(var(--el-accent-rgb, 26,58,138), 0.12);
    color: var(--el-accent, #1a3a8a);
    font-size: 0.8rem;
    font-weight: 600;
}
.el-program-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
}
.el-program-chip {
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.05);
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--el-text-muted);
}
html.night-mode .el-program-chip { background: rgba(255, 255, 255, 0.07); }
.el-program-cta {
    margin-top: auto;
    padding-top: 8px;
    font-weight: 700;
    color: var(--el-accent, #1a3a8a);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ── Lost & Found page ─────────────────────────────────────────────── */
.el-lf-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
    margin-top: 28px;
}
.el-lf-card {
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
}
.el-lf-cover {
    aspect-ratio: 1 / 1;
    background-color: rgba(0, 0, 0, 0.04);
    background-size: cover;
    background-position: center;
}
html.night-mode .el-lf-cover { background-color: rgba(255, 255, 255, 0.04); }
.el-lf-cover--empty {
    display: flex; align-items: center; justify-content: center;
    color: var(--el-text-muted);
    font-size: 3rem;
}
.el-lf-body {
    padding: 18px 20px 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
}
.el-lf-pill {
    align-self: flex-start;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(245, 158, 11, 0.18);
    color: #b45309;
    font-size: 0.74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.el-lf-pill--claimed {
    background: rgba(34, 197, 94, 0.15);
    color: #16a34a;
}
.el-lf-title {
    margin: 4px 0 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--el-accent, #1a3a8a);
}
.el-lf-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 0.78rem;
    color: var(--el-text-muted);
    margin-top: 2px;
}
.el-lf-meta span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.el-lf-notes {
    margin: 4px 0 0;
    font-size: 0.88rem;
    line-height: 1.4;
    opacity: 0.85;
}
.el-lf-loc {
    margin-top: 4px;
    font-size: 0.82rem;
    color: var(--el-text-muted);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.el-lf-claimer {
    font-size: 0.82rem;
    color: #16a34a;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.el-lf-cta {
    margin-top: auto;
    padding-top: 8px;
    font-weight: 700;
    color: var(--el-accent, #1a3a8a);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ── Programs / Lost & Found detail mode ──────────────────────────── */
.el-back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--el-accent, #1a3a8a);
    font-weight: 600;
    text-decoration: none;
}
.el-back-link:hover { text-decoration: underline; }

/* When the host page is in detail mode (single .el-detail-row child),
   override the list-grid layout so the detail row gets the full
   container width. Without this, the parent's auto-fill columns
   crammed the row into ~1/3 width and the cover image overlapped
   the right column. */
.el-lf-grid:has(.el-detail-row),
.el-programs-grid:has(.el-detail-row) {
    display: block;
}

/* Two-column detail layout shared by /programs?id=N and /lost-found?id=N.
   Cover image lives in the left column with position: sticky so it
   follows the scroll until the right column ends — at which point it
   "lets go" naturally because there's no more parent height to stick
   to. Stacked layout on narrow viewports. */
.el-detail-row {
    display: grid;
    grid-template-columns: minmax(320px, 1fr) minmax(360px, 1.4fr);
    gap: 36px;
    align-items: start;
    width: 100%;
    margin: 0 auto;
}
@media (max-width: 900px) {
    .el-detail-row {
        grid-template-columns: 1fr;
        gap: 20px;
    }
}
.el-detail-cover-col {
    position: sticky;
    top: 96px;   /* clears the sticky el-nav header */
}
@media (max-width: 900px) {
    .el-detail-cover-col {
        position: static;
        top: auto;
    }
}
.el-detail-cover {
    width: 100%;
    aspect-ratio: 4 / 5;
    background-color: rgba(0, 0, 0, 0.04);
    background-size: cover;
    background-position: center;
    border-radius: var(--el-radius);
}
html.night-mode .el-detail-cover { background-color: rgba(255, 255, 255, 0.04); }
.el-detail-cover--empty {
    display: flex; align-items: center; justify-content: center;
    color: var(--el-text-muted);
    font-size: 4rem;
}
.el-detail-info-col { min-width: 0; }

/* Back-link sits BELOW the two-column row so the columns can stretch
   the full container width without competing for the top of the page. */
.el-back-link {
    margin-top: 24px;
    margin-bottom: 0;
}

/* Legacy aliases retained — older selectors map to the same look. */
.el-program-detail,
.el-lf-detail {
    max-width: none;
    margin: 0;
}
.el-program-detail-title,
.el-lf-detail-title {
    margin: 0 0 8px;
    font-size: 2rem;
    color: var(--el-accent, #1a3a8a);
}
.el-program-detail-tag,
.el-lf-detail-notes {
    font-size: 1rem;
    opacity: 0.85;
    margin: 0 0 16px;
}
.el-program-detail-meta,
.el-lf-detail-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 16px 0 24px;
    font-size: 0.92rem;
}
.el-program-detail-meta span,
.el-lf-detail-meta span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.el-program-section-block { margin: 18px 0; }
.el-program-section-title {
    margin: 0 0 6px;
    font-size: 1.1rem;
    color: var(--el-accent, #1a3a8a);
}
/* Section body — preserve newlines from the source content so AI-written
   write-ups with `\n\n` paragraph breaks + emoji-prefixed sub-headings
   render as the author wrote them (instead of collapsing into a single
   wall of text). `pre-line` keeps `\n` as a hard break, while still
   honouring any HTML tags the editor might paste. Long-form copy gets a
   tiny bit more breathing room than the default leading too. */
.el-program-section-body {
    line-height: 1.6;
    white-space: pre-line;
    word-wrap: break-word;
}
/* Tighten leading inside any block-level child the editor may add (p, ul,
   etc.) so a paragraph followed by `pre-line` `\n\n` doesn't double-space.
   Mostly defensive — current write-ups are plain text. */
.el-program-section-body p { margin: 0 0 0.6em; }
.el-program-section-body p:last-child { margin-bottom: 0; }
.el-program-section-body ul,
.el-program-section-body ol { margin: 0.5em 0 0.8em 1.2em; padding: 0; }

.el-program-detail-form { margin-top: 28px; }

/* ── L&F claim block (member one-tap or guest form) ───────────────── */
.el-lf-claim-block {
    margin-top: 24px;
    padding: 24px;
    border-radius: var(--el-radius);
    border: 1px solid var(--el-border);
    background: rgba(var(--el-accent-rgb, 26,58,138), 0.05);
}
html.night-mode .el-lf-claim-block {
    background: rgba(255, 255, 255, 0.04);
}
.el-lf-claim-block h3 {
    margin: 0 0 8px;
    color: var(--el-accent, #1a3a8a);
}
.el-lf-claim-block p {
    margin: 0 0 16px;
    opacity: 0.85;
}
.el-lf-claim-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-bottom: 16px;
}
@media (max-width: 600px) {
    .el-lf-claim-grid { grid-template-columns: 1fr; }
}
.el-lf-claim-grid label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.85rem;
    font-weight: 600;
}
.el-input {
    width: 100%;
    padding: 9px 12px;
    border-radius: 10px;
    border: 1px solid rgba(0, 0, 0, 0.15);
    background: #fff;
    color: inherit;
    font: inherit;
    font-weight: 400;
}
html.night-mode .el-input {
    background: rgba(0, 0, 0, 0.35);
    border-color: rgba(255, 255, 255, 0.18);
    color: #fff;
}
.el-input:focus {
    outline: 2px solid var(--el-accent, #1a3a8a);
    outline-offset: 1px;
}

.el-lf-claim-status {
    min-height: 1.4em;
    margin: 12px 0;
    font-size: 0.92rem;
}
.el-lf-claim-status--success { color: #16a34a; font-weight: 600; }
.el-lf-claim-status--error   { color: #dc2626; font-weight: 600; }
.el-lf-claim-status--info    { color: var(--el-text-muted); }

.el-lf-claimed-banner {
    margin-top: 24px;
    padding: 16px 20px;
    border-radius: var(--el-radius);
    background: rgba(34, 197, 94, 0.12);
    color: #16a34a;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-weight: 600;
}


/* ═══════════════════════════════════════════════════════════════════
   Clubhouse Rentals — public rate card (Phase 1, 2026-08-10)
   Plan: .claude/plans/clubhouse-rentals.md
   Rendered inside the "Rates & add-ons" accordion on facilities.html
   by the IIFE at the bottom of facilities.js.
   ═══════════════════════════════════════════════════════════════════ */

.el-clubhouse-rates {
    color: var(--el-text);
}
.el-clubhouse-rates--loading .el-muted { opacity: 0.7; }
.el-clubhouse-rates--fallback {
    /* Static-fallback state — soft warning tone so we know when the
       endpoint failed but nothing looks broken to the visitor. */
    opacity: 0.95;
}

.el-rate-table {
    display: grid;
    grid-template-columns: 1.5fr 1fr 1fr;
    gap: 8px 12px;
    margin: 14px 0 20px;
    padding: 12px 14px;
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 12px;
}
/* Single-side variant — logged-in members see member rates only, public
   sees non-member only. Two columns (Slot | Price) instead of three
   (Slot | Member | Non-member). Operator flag 2026-08-11: don't show
   the split when the viewer's tier is already resolved. */
.el-rate-table--single {
    grid-template-columns: 1.5fr 1fr;
}
.el-rate-row {
    display: contents;
}
.el-rate-row--head > span {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
    padding-bottom: 4px;
    border-bottom: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
}
.el-rate-row > span {
    font-size: 0.92rem;
    line-height: 1.4;
    align-self: center;
}
.el-rate-cell {
    font-weight: 700;
    font-size: 1.02rem;
    color: var(--el-text);
    white-space: nowrap;
}
.el-rate-row > span:first-child .el-muted {
    display: inline-block;
    font-size: 0.72rem;
    margin-top: 2px;
}

.el-rate-subhead {
    margin: 18px 0 8px;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.6));
}
.el-rate-addons {
    padding-left: 20px;
    margin: 0 0 16px;
}
.el-rate-addons li {
    margin-bottom: 6px;
    line-height: 1.5;
}
.el-rate-deposit {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 10px;
    font-size: 0.9rem;
}
.el-rate-deposit .mdi {
    color: var(--el-accent, #16a34a);
    font-size: 1.15rem;
    flex-shrink: 0;
}

@media (max-width: 640px) {
    .el-rate-table {
        grid-template-columns: 1fr 1fr;
        gap: 6px 10px;
    }
    /* Stack the slot label + rates as three rows per slot on narrow screens */
    .el-rate-row > span:first-child {
        grid-column: 1 / -1;
        padding-bottom: 2px;
    }
    .el-rate-row--head > span:first-child {
        display: none;   /* header slot column hidden — rates use own row */
    }
}


/* ═══════════════════════════════════════════════════════════════════
   Venue Hire — inline enquiry form (Phase 2B, 2026-08-11)
   Rewritten from the fullpage modal in Phase 2. Form renders inline
   into #clubhouse-enquire-form via venue.js. Availability strip below
   the form expands + smooth-scrolls into view when the operator taps
   the "Check availability" button. Every .el-clubhouse-form / -field
   / -fieldset / -quote / -identity class from the original modal
   carries forward untouched.
   ═══════════════════════════════════════════════════════════════════ */

.el-venue-quote-wrap {
    margin-top: 24px;
    padding: 20px 22px 22px;
    background: var(--el-bg-card, rgba(255, 255, 255, 0.55));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 14px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
:root.night-mode .el-venue-quote-wrap {
    background: rgba(255, 255, 255, 0.03);
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
.el-venue-form-head {
    margin: 0 0 16px 0;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
}
.el-venue-form-head h3 {
    margin: 0 0 4px 0;
    font-family: var(--el-font-display, 'Cormorant Garamond', serif);
    font-size: 1.5rem;
    line-height: 1.15;
    color: var(--el-text);
}
.el-venue-form-head p {
    margin: 0;
    font-size: 0.85rem;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.65));
}
.el-venue-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: flex-end;
    align-items: center;
    margin-top: 4px;
}
@media (max-width: 500px) {
    .el-venue-actions {
        flex-direction: column-reverse;
        align-items: stretch;
    }
    .el-venue-actions .el-btn { width: 100%; justify-content: center; }
}

/* Terms-gate hint pill — appears above the Add-to-cart button when the
   T&Cs box is still unticked. The button itself renders disabled, this
   pill answers "why?" without pushing the user to guess. Auto-hides
   the moment the checkbox is ticked. */
.el-venue-terms-hint {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    background: rgba(234, 179, 8, 0.10);
    border: 1px solid rgba(234, 179, 8, 0.28);
    border-radius: 8px;
    font-size: 0.82rem;
    color: rgb(133, 77, 14);
    margin-top: 4px;
}
.el-venue-terms-hint .mdi {
    font-size: 1rem;
    flex-shrink: 0;
}
:root.night-mode .el-venue-terms-hint {
    background: rgba(234, 179, 8, 0.15);
    border-color: rgba(234, 179, 8, 0.35);
    color: rgb(250, 204, 21);
}
/* Disabled state for the CTA — softer visual than the browser default
   so the button reads as "waiting" rather than "broken". */
.el-clubhouse-cta[disabled],
.el-clubhouse-cta:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    filter: grayscale(0.3);
}

.el-venue-success {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 12px;
    padding: 16px 4px 4px;
}
.el-venue-success h3 {
    margin: 0;
    font-family: var(--el-font-display, 'Cormorant Garamond', serif);
    font-size: 1.6rem;
}

/* ── Availability strip — sits below the form. Collapsed by default
      (grid-template-rows: 0fr → 1fr trick so max-height animates cleanly
      whatever the child height turns out to be). Smooth-scroll target
      is the wrapper element itself, so scrollIntoView lands the head
      of the strip at the viewport centre. ── */
.el-venue-availability {
    margin-top: 16px;
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.28s ease;
}
.el-venue-availability--open {
    grid-template-rows: 1fr;
}
.el-venue-availability-inner {
    overflow: hidden;
    padding: 0 4px;
}
.el-venue-availability--open .el-venue-availability-inner {
    padding: 16px 18px;
    background: var(--el-bg-card, rgba(255, 255, 255, 0.55));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 12px;
}
:root.night-mode .el-venue-availability--open .el-venue-availability-inner {
    background: rgba(255, 255, 255, 0.03);
    border-color: rgba(255, 255, 255, 0.08);
}
.el-venue-availability-head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.7));
    font-size: 0.9rem;
}
.el-venue-availability-head .mdi {
    font-size: 1.4rem;
    flex-shrink: 0;
    margin-top: 1px;
}
.el-venue-availability-head--free { color: rgb(22, 130, 74); }
.el-venue-availability-head--free .mdi { color: rgb(22, 163, 74); }
.el-venue-availability-head--busy { color: rgb(194, 65, 12); }
.el-venue-availability-head--busy .mdi { color: rgb(234, 88, 12); }
.el-venue-availability-title {
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1.25;
    color: inherit;
}
.el-venue-availability-sub {
    margin-top: 2px;
    font-size: 0.8rem;
    opacity: 0.85;
}
.el-venue-availability-list {
    list-style: none;
    padding: 0;
    margin: 12px 0 0 34px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.el-venue-availability-list li {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 12px;
    background: rgba(234, 88, 12, 0.08);
    border: 1px solid rgba(234, 88, 12, 0.18);
    border-radius: 8px;
    font-size: 0.85rem;
}
.el-venue-avail-time { font-weight: 700; color: rgb(154, 52, 18); font-variant-numeric: tabular-nums; }
.el-venue-avail-type { color: var(--el-text-muted, rgba(0, 0, 0, 0.6)); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; }

/* ═══════════════════════════════════════════════════════════════════
   Clubhouse rental enquiry modal (Phase 2, 2026-08-10)
   Plan: .claude/plans/clubhouse-rentals.md
   Fullpage on mobile, centered on desktop. Injected by the IIFE at
   the bottom of facilities.js into #el-clubhouse-modal.
   ═══════════════════════════════════════════════════════════════════ */

.el-clubhouse-modal-mount {
    position: fixed; inset: 0;
    z-index: 9500;
    display: none;
}
.el-clubhouse-modal-mount:not([hidden]) {
    display: block;
}
.el-clubhouse-modal-scrim {
    position: absolute; inset: 0;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    cursor: pointer;
    animation: elClubhouseFadeIn 0.15s ease-out;
}
.el-clubhouse-modal-panel {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    max-width: 640px;
    width: calc(100% - 24px);
    max-height: calc(100vh - 24px);
    max-height: calc(100dvh - 24px);
    overflow-y: auto;
    background: var(--el-bg-page, #ffffff);
    color: var(--el-text);
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 16px;
    box-shadow: 0 40px 80px -20px rgba(0, 0, 0, 0.45), 0 8px 24px -8px rgba(0, 0, 0, 0.3);
    padding: 22px 22px 18px;
    animation: elClubhousePopIn 0.18s ease-out;
}
.el-clubhouse-modal-panel--success {
    text-align: center;
}
@media (max-width: 640px) {
    .el-clubhouse-modal-panel {
        left: 0; top: 0; transform: none;
        width: 100%;
        height: 100%; max-height: 100%;
        border-radius: 0;
        padding: 18px 16px 100px;   /* extra bottom padding for iOS home indicator */
    }
}
@keyframes elClubhouseFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes elClubhousePopIn {
    from { opacity: 0; transform: translate(-50%, -46%); }
    to   { opacity: 1; transform: translate(-50%, -50%); }
}
@media (max-width: 640px) {
    @keyframes elClubhousePopIn {
        from { opacity: 0; transform: translateY(20px); }
        to   { opacity: 1; transform: translateY(0); }
    }
}
.el-clubhouse-modal-x {
    position: sticky;
    float: right;
    top: 4px;
    background: transparent;
    border: none;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    padding: 4px;
    margin: -6px -6px 0 0;
}
.el-clubhouse-modal-x:hover {
    color: var(--el-text);
}
.el-clubhouse-modal-head {
    margin-bottom: 18px;
    padding-right: 32px;   /* avoid overlap with close button */
}
.el-clubhouse-modal-head h2 {
    margin: 0 0 6px;
    font-size: 1.35rem;
    font-weight: 700;
}
.el-clubhouse-modal-head p {
    margin: 0;
    font-size: 0.88rem;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.6));
}

/* ── Form body ─────────────────────────────────────────────────── */
.el-clubhouse-form {
    display: flex;
    flex-direction: column;
    gap: 18px;
}
.el-clubhouse-identity {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 10px;
}
.el-clubhouse-identity--member {
    background: rgba(22, 163, 74, 0.10);
    border-color: rgba(22, 163, 74, 0.25);
}
.el-clubhouse-identity .mdi {
    font-size: 1.4rem;
    color: var(--el-accent, #16a34a);
    flex-shrink: 0;
}
.el-clubhouse-identity-name {
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1.2;
}
.el-clubhouse-identity-sub {
    font-size: 0.75rem;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.6));
    margin-top: 2px;
}
.el-clubhouse-fieldset {
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 10px;
    padding: 12px 14px 14px;
    margin: 0;
}
.el-clubhouse-fieldset legend {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
    padding: 0 6px;
}
.el-clubhouse-fieldset > *:not(:last-child) {
    margin-bottom: 10px;
}
.el-clubhouse-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.el-clubhouse-field > span {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.7));
}
.el-clubhouse-field input,
.el-clubhouse-field select,
.el-clubhouse-field textarea {
    background: var(--el-bg-page, #ffffff);
    color: var(--el-text);
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.15));
    border-radius: 8px;
    padding: 9px 11px;
    font-family: inherit;
    font-size: 0.92rem;
    line-height: 1.35;
    width: 100%;
    box-sizing: border-box;
    transition: border-color 0.12s;
}
.el-clubhouse-field input:focus,
.el-clubhouse-field select:focus,
.el-clubhouse-field textarea:focus {
    outline: none;
    border-color: var(--el-accent, #16a34a);
}
.el-clubhouse-field textarea {
    resize: vertical;
    min-height: 60px;
}
.el-clubhouse-grid {
    display: grid;
    gap: 10px;
}
.el-clubhouse-grid--2 {
    grid-template-columns: repeat(2, 1fr);
}
.el-clubhouse-grid--3 {
    grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 500px) {
    .el-clubhouse-grid--2,
    .el-clubhouse-grid--3 {
        grid-template-columns: 1fr;
    }
}
.el-clubhouse-avail {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 8px;
    font-size: 0.82rem;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.65));
}
.el-clubhouse-avail .mdi {
    font-size: 1.05rem;
    flex-shrink: 0;
}
.el-clubhouse-avail--free {
    background: rgba(22, 163, 74, 0.10);
    border-color: rgba(22, 163, 74, 0.25);
    color: rgb(22, 163, 74);
}
.el-clubhouse-avail--busy {
    background: rgba(234, 88, 12, 0.10);
    border-color: rgba(234, 88, 12, 0.25);
    color: rgb(194, 65, 12);
}

/* Checkbox rows for add-ons */
.el-clubhouse-check {
    display: grid;
    grid-template-columns: 22px 1fr;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 8px;
    cursor: pointer;
    transition: background 0.12s;
}
.el-clubhouse-check:hover {
    background: var(--el-bg-card-hover, rgba(0, 0, 0, 0.05));
}
.el-clubhouse-check--with-input {
    grid-template-columns: 22px 1fr 80px;
}
/* Paid extras (2026-08-12) — priced row with cost chip on the right so
   renter sees what they're opting into. Same base shape as free rows;
   third grid column reserves space for the chip. */
.el-clubhouse-check--paid {
    grid-template-columns: 22px 1fr auto;
}
.el-clubhouse-extra-price {
    font-weight: 600;
    font-size: 0.88rem;
    color: var(--el-text, #111);
    background: var(--el-bg-card-hover, rgba(0, 0, 0, 0.06));
    padding: 4px 10px;
    border-radius: 999px;
    white-space: nowrap;
}
.el-clubhouse-check input[type="checkbox"] {
    accent-color: var(--el-accent, #16a34a);
    width: 18px; height: 18px;
    cursor: pointer;
}
.el-clubhouse-check > span {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 0.88rem;
}
.el-clubhouse-check > span .el-muted {
    font-size: 0.72rem;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
}
.el-clubhouse-check input[type="number"] {
    background: var(--el-bg-page, #ffffff);
    color: var(--el-text);
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.15));
    border-radius: 6px;
    padding: 6px 8px;
    font-family: inherit;
    font-size: 0.88rem;
    width: 100%;
    box-sizing: border-box;
}
.el-clubhouse-check input[type="number"]:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* Court time range sub-panel — appears below the Court hire check row
   when the box is ticked. Lets renters book courts for a subset of
   the event window (2026-08-11 operator flag). Indented + subtly
   tinted so it visually belongs to the parent row without stealing
   focus from the main add-ons list. */
.el-clubhouse-court-range {
    margin: -4px 0 0 22px;      /* pull under the parent tile + align with content */
    padding: 10px 12px 12px;
    background: var(--el-bg-card, rgba(0, 0, 0, 0.04));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.10));
    border-radius: 0 0 8px 8px;
    border-top: none;
}
.el-clubhouse-court-range[hidden] { display: none; }
.el-clubhouse-court-range-label {
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.65));
    margin-bottom: 8px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.el-clubhouse-court-range-label .el-muted {
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
}

/* Terms tickbox */
.el-clubhouse-terms {
    display: grid;
    grid-template-columns: 22px 1fr;
    align-items: start;
    gap: 10px;
    font-size: 0.85rem;
    line-height: 1.45;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.7));
    padding: 8px 4px;
}
.el-clubhouse-terms input[type="checkbox"] {
    accent-color: var(--el-accent, #16a34a);
    width: 18px; height: 18px;
    margin-top: 1px;
    cursor: pointer;
}
.el-clubhouse-terms a {
    color: var(--el-accent, #16a34a);
    text-decoration: underline;
}

/* Actions bar */
.el-clubhouse-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding-top: 6px;
    border-top: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
}
@media (max-width: 500px) {
    .el-clubhouse-actions {
        flex-direction: column-reverse;
    }
    .el-clubhouse-actions .el-btn {
        width: 100%;
    }
}

/* Error banner */
.el-clubhouse-error {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: rgba(220, 38, 38, 0.10);
    border: 1px solid rgba(220, 38, 38, 0.25);
    color: rgb(185, 28, 28);
    border-radius: 8px;
    font-size: 0.88rem;
}
.el-clubhouse-error .mdi {
    font-size: 1.1rem;
    flex-shrink: 0;
}

/* ── Success screen ─────────────────────────────────────────────── */
.el-clubhouse-success {
    padding: 20px 8px 8px;
}
.el-clubhouse-success-icon {
    font-size: 3.5rem;
    color: var(--el-accent, #16a34a);
    line-height: 1;
    margin-bottom: 14px;
}
.el-clubhouse-success h2 {
    margin: 0 0 10px;
    font-size: 1.4rem;
    font-weight: 700;
}
.el-clubhouse-success p {
    margin: 0 0 16px;
    font-size: 0.95rem;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.7));
    line-height: 1.5;
}
.el-clubhouse-success-total {
    padding: 12px 14px;
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border-radius: 10px;
    margin-bottom: 18px;
    font-size: 0.95rem;
}
.el-clubhouse-success-total .el-muted {
    display: block;
    font-size: 0.78rem;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.6));
    margin-top: 4px;
}

/* Night-mode tweaks — soft-neutral shadows, deeper card contrast */
html.night-mode .el-clubhouse-modal-panel {
    background: var(--el-bg-elev, #1a1d24);
    box-shadow: 0 40px 80px -20px rgba(0, 0, 0, 0.7), 0 8px 24px -8px rgba(0, 0, 0, 0.5);
}
html.night-mode .el-clubhouse-field input,
html.night-mode .el-clubhouse-field select,
html.night-mode .el-clubhouse-field textarea,
html.night-mode .el-clubhouse-check input[type="number"] {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.12);
    color: var(--el-text);
}


/* ═══════════════════════════════════════════════════════════════════
   Clubhouse rentals — live quote panel + Request-quote CTA (2026-08-10)
   Mirrors the "What will you pay?" pricing calculator on the Mzansi
   Court marketing site (screenshot reference — running total + big
   coloured CTA). Updates live as the form is filled.
   ═══════════════════════════════════════════════════════════════════ */

.el-clubhouse-quote {
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.10));
    border-radius: 12px;
    padding: 14px 16px;
    margin: 8px 0 4px;
}
.el-clubhouse-quote-head {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
    margin-bottom: 10px;
}
.el-clubhouse-quote-lines {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 10px;
}
.el-clubhouse-quote-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 0.88rem;
    color: var(--el-text);
    line-height: 1.35;
}
.el-clubhouse-quote-row > span:last-child {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--el-text);
    font-weight: 500;
}
.el-clubhouse-quote-row--sub {
    padding-top: 6px;
    border-top: 1px dashed var(--el-border, rgba(0, 0, 0, 0.12));
    font-weight: 600;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.7));
}
.el-clubhouse-quote-row--sub > span:last-child {
    font-weight: 600;
}
.el-clubhouse-quote-chip {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(22, 163, 74, 0.14);
    color: rgb(22, 163, 74);
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    vertical-align: middle;
}
.el-clubhouse-quote-total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding-top: 12px;
    border-top: 2px solid var(--el-accent, #16a34a);
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--el-text);
}
.el-clubhouse-quote-total > span:last-child {
    color: var(--el-accent, #16a34a);
    font-size: 1.35rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.el-clubhouse-quote-total .el-muted {
    display: block;
    font-size: 0.68rem;
    font-weight: 500;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
    text-transform: none;
    letter-spacing: 0;
    margin-top: 2px;
}

/* Request-quote CTA — bigger + coloured like the pricing page ADD TO CART. */
.el-clubhouse-cta {
    min-width: 200px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 12px 24px;
}
@media (max-width: 500px) {
    .el-clubhouse-cta { width: 100%; }
}

/* Night-mode overrides — the accent tint stays green but background lifts. */
html.night-mode .el-clubhouse-quote {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.10);
}
html.night-mode .el-clubhouse-quote-row--sub {
    border-top-color: rgba(255, 255, 255, 0.14);
}


/* Cart-entry breakdown on the enquiry success screen (2026-08-10).
   Mirrors the live-quote panel layout so the renter sees the same
   line-items after submit that they saw pre-submit. */
.el-clubhouse-cart-entry {
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.10));
    border-radius: 12px;
    padding: 14px 16px;
    margin: 10px 0 18px;
    text-align: left;
}
/* Inside the success card, the flex parent uses align-items: center
   which sizes children to their intrinsic width. Opt out for the
   cart-entry so it fills the available width (operator flag 2026-08-11
   — the narrow card looked squeezed inside the wide success surface). */
.el-venue-success .el-clubhouse-cart-entry {
    align-self: stretch;
    width: 100%;
    max-width: none;
    box-sizing: border-box;
}
.el-clubhouse-cart-head {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
    margin-bottom: 10px;
    text-align: center;
}
.el-clubhouse-cart-entry .el-clubhouse-quote-lines,
.el-clubhouse-cart-entry .el-clubhouse-quote-total {
    /* Inherit the live-quote styling — same visual shape as pre-submit. */
}

/* ═══════════════════════════════════════════════════════════════════
   Coaching Agreement — public signup form (2026-08-12)
   Templated club-site page at /coaching-agreement. Mount = #ca-mount.
   Uses .el-btn + .ca-* namespace so it doesn't collide with cs-* /
   el-clubhouse-* rules.
   ═══════════════════════════════════════════════════════════════════ */

.ca-mount { min-height: 200px; }
.ca-loading, .ca-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 48px 20px;
    text-align: center;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.6));
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 16px;
}
.ca-loading .mdi, .ca-empty .mdi { font-size: 2.4rem; opacity: 0.7; }
.ca-empty h3 { margin: 0; font-family: var(--el-font-display, 'Cormorant Garamond', serif); font-size: 1.5rem; }
.ca-empty p { margin: 0; max-width: 480px; font-size: 0.92rem; line-height: 1.5; }
.ca-empty--error { border-color: rgba(234, 88, 12, 0.35); background: rgba(234, 88, 12, 0.06); color: rgb(154, 52, 18); }

.ca-card {
    background: var(--el-bg-card, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.08));
    border-radius: 16px;
    padding: 28px 26px 30px;
    max-width: 780px;
    margin: 0 auto;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}
:root.night-mode .ca-card {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}
.ca-card-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 20px; flex-wrap: wrap;
    padding-bottom: 14px; margin-bottom: 16px;
    border-bottom: 1px solid var(--el-border, rgba(0, 0, 0, 0.10));
}
.ca-eyebrow {
    font-size: 0.75rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--el-text-muted, rgba(0, 0, 0, 0.6));
    margin-bottom: 4px;
}
.ca-title {
    font-family: var(--el-font-display, 'Cormorant Garamond', serif);
    font-size: 2rem; line-height: 1.1; margin: 0; color: var(--el-text);
}
.ca-fee-chip {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 6px 12px;
    background: rgba(2, 12, 146, 0.10);
    border: 1px solid rgba(2, 12, 146, 0.25);
    border-radius: 999px;
    font-size: 0.82rem; font-weight: 600; color: var(--el-text);
    white-space: nowrap;
}

.ca-body {
    margin-bottom: 20px;
    font-size: 0.92rem; line-height: 1.6; color: var(--el-text);
}
.ca-body p { margin: 0 0 10px 0; }
.ca-body ul, .ca-body ol { padding-left: 22px; margin: 6px 0 12px 0; }
.ca-body li { margin: 4px 0; }
.ca-body strong { color: var(--el-text); }
.ca-body a { color: var(--el-accent, #020c92); text-decoration: underline; }
.ca-body--payment {
    background: rgba(2, 12, 146, 0.05);
    border-left: 3px solid var(--el-accent, #020c92);
    padding: 12px 16px;
    border-radius: 8px;
}

.ca-form {
    display: flex; flex-direction: column; gap: 20px;
    margin-top: 8px;
    padding-top: 20px;
    border-top: 1px solid var(--el-border, rgba(0, 0, 0, 0.10));
}
.ca-fieldset {
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.10));
    border-radius: 12px;
    padding: 14px 16px 16px;
    margin: 0;
}
.ca-fieldset legend {
    font-size: 0.72rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--el-text-muted, rgba(0, 0, 0, 0.55));
    padding: 0 6px;
}
.ca-fieldset--sig { border-color: var(--el-accent, #020c92); background: rgba(2, 12, 146, 0.03); }
:root.night-mode .ca-fieldset--sig { background: rgba(2, 12, 146, 0.15); }

.ca-grid { display: grid; gap: 12px; }
.ca-grid--2 { grid-template-columns: repeat(2, 1fr); }
.ca-grid--3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 640px) {
    .ca-grid--2, .ca-grid--3 { grid-template-columns: 1fr; }
}
.ca-field { display: flex; flex-direction: column; gap: 5px; }
.ca-field > span { font-size: 0.78rem; font-weight: 600; color: var(--el-text-muted, rgba(0, 0, 0, 0.7)); }
.ca-field input, .ca-field select {
    background: var(--el-bg-page, #ffffff);
    color: var(--el-text);
    border: 1px solid var(--el-border, rgba(0, 0, 0, 0.15));
    border-radius: 8px;
    padding: 9px 11px;
    font-family: inherit; font-size: 0.92rem; line-height: 1.35;
    width: 100%; box-sizing: border-box;
    transition: border-color 0.12s;
}
.ca-field input:focus, .ca-field select:focus {
    outline: none; border-color: var(--el-accent, #020c92);
}
.ca-field--sig input {
    font-family: 'Cormorant Garamond', serif;
    font-size: 1.4rem !important; font-style: italic; letter-spacing: 0.02em;
}
.ca-sig-copy {
    font-size: 0.85rem; line-height: 1.5; margin: 0 0 12px 0;
    color: var(--el-text-muted, rgba(0, 0, 0, 0.7));
}
.ca-check {
    display: grid; grid-template-columns: 22px 1fr; align-items: center;
    gap: 10px; margin-top: 12px;
    font-size: 0.88rem; cursor: pointer;
}
.ca-check input[type="checkbox"] {
    accent-color: var(--el-accent, #020c92);
    width: 18px; height: 18px; cursor: pointer;
}

.ca-error {
    padding: 10px 14px;
    background: rgba(220, 38, 38, 0.08);
    border: 1px solid rgba(220, 38, 38, 0.3);
    color: rgb(153, 27, 27);
    border-radius: 8px; font-size: 0.88rem;
}
.ca-actions {
    display: flex; justify-content: flex-end;
    padding-top: 4px;
}
@media (max-width: 500px) {
    .ca-actions { justify-content: stretch; }
    .ca-actions .el-btn { width: 100%; justify-content: center; }
}

.ca-card--success { text-align: center; }
.ca-success-icon {
    font-size: 3rem; color: rgb(22, 163, 74); margin-bottom: 8px;
}
.ca-card--success h2 {
    font-family: var(--el-font-display, 'Cormorant Garamond', serif);
    font-size: 1.8rem; margin: 0 0 8px 0;
}
.ca-muted { color: var(--el-text-muted, rgba(0, 0, 0, 0.55)); font-size: 0.82rem; }


/* ═══════════════════════════════════════════════════════════════════
   Signed-in "Your rentals" strip — venue page (2026-08-13)
   ═══════════════════════════════════════════════════════════════════ */
.el-venue-my-rentals { margin: 0 0 20px 0; }
.el-venue-my-rentals-inner {
    background: var(--el-surface, rgba(255,255,255,0.98));
    border: 1px solid var(--el-border, rgba(0,0,0,0.08));
    border-radius: 12px;
    padding: 14px 16px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.el-venue-my-rentals-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 10px;
}
.el-venue-my-rentals-head h3 {
    margin: 0; font-size: 0.95rem; font-weight: 700;
    display: flex; align-items: center; gap: 6px;
    color: var(--el-text, rgb(15, 23, 42));
}
.el-venue-my-rentals-head h3 .mdi { color: var(--el-accent, rgb(37, 99, 235)); }
.el-venue-my-rentals-more {
    font-size: 0.82rem; text-decoration: none;
    color: var(--el-accent, rgb(37, 99, 235));
    display: flex; align-items: center; gap: 2px;
}
.el-venue-my-rentals-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.el-venue-my-rental-row {
    border: 1px solid var(--el-border, rgba(0,0,0,0.06));
    border-radius: 10px; overflow: hidden;
    background: var(--el-bg, rgba(0,0,0,0.02));
}
.el-venue-my-rental-head {
    display: grid;
    grid-template-columns: auto 1fr auto auto 20px;
    gap: 10px; align-items: center;
    width: 100%; padding: 10px 12px;
    background: transparent; border: 0; cursor: pointer;
    text-align: left; font-size: 0.88rem;
    color: var(--el-text, rgb(15, 23, 42));
}
.el-venue-my-rental-head:hover { background: rgba(0,0,0,0.03); }
.el-venue-my-rental-date { font-weight: 600; white-space: nowrap; }
.el-venue-my-rental-title {
    color: var(--el-text-muted, rgba(0,0,0,0.6));
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.el-venue-my-rental-status {
    font-size: 0.72rem; font-weight: 700;
    padding: 3px 9px; border-radius: 999px;
    text-transform: uppercase; letter-spacing: 0.04em;
    background: rgba(100, 116, 139, 0.15); color: rgb(51, 65, 85);
}
.el-venue-my-rental-status.is-draft    { background: rgba(148, 163, 184, 0.2); color: rgb(71, 85, 105); }
.el-venue-my-rental-status.is-pending  { background: rgba(234, 179, 8, 0.18);   color: rgb(161, 98, 7); }
.el-venue-my-rental-status.is-approved { background: rgba(37, 99, 235, 0.18);   color: rgb(29, 78, 216); }
.el-venue-my-rental-status.is-paid     { background: rgba(22, 163, 74, 0.18);   color: rgb(21, 128, 61); }
.el-venue-my-rental-status.is-cancel   { background: rgba(239, 68, 68, 0.18);   color: rgb(153, 27, 27); }
.el-venue-my-rental-total {
    font-weight: 700; color: var(--el-text, rgb(15, 23, 42));
    white-space: nowrap; font-variant-numeric: tabular-nums;
}
.el-venue-my-rental-chevron {
    color: var(--el-text-muted, rgba(0,0,0,0.4));
    transition: transform 0.18s ease;
}
.el-venue-my-rental-body {
    padding: 8px 12px 12px 12px;
    border-top: 1px dashed var(--el-border, rgba(0,0,0,0.08));
    display: grid; gap: 10px;
}
.el-venue-my-rental-meta {
    display: flex; flex-wrap: wrap; gap: 12px;
    font-size: 0.82rem; color: var(--el-text-muted, rgba(0,0,0,0.6));
}
.el-venue-my-rental-meta strong {
    color: var(--el-text, rgb(15, 23, 42));
    margin-right: 4px;
}
.el-venue-my-rental-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.el-venue-my-rental-actions .el-btn { font-size: 0.82rem; padding: 6px 12px; }

/* Cancellation-deadline footnote in the live quote breakdown */
.el-clubhouse-quote-row--footnote {
    font-size: 0.78rem !important;
    color: var(--el-text-muted, rgba(0,0,0,0.6)) !important;
    font-style: italic;
    border-top: 1px dashed var(--el-border, rgba(0,0,0,0.1));
    margin-top: 4px; padding-top: 6px;
}
.el-clubhouse-quote-row--footnote .mdi {
    color: var(--el-warn, rgb(194, 65, 12));
    margin-right: 4px;
}
.el-clubhouse-quote-row--footnote strong {
    color: var(--el-text, rgb(15, 23, 42));
    font-style: normal;
}

/* Success card Pay Now action row */
.el-clubhouse-success-actions {
    display: flex; justify-content: center;
    margin: 12px 0 4px 0;
}

/* Night mode adaptations for rentals strip */
:root.night-mode .el-venue-my-rentals-inner {
    background: rgba(255,255,255,0.04);
    border-color: rgba(255,255,255,0.08);
}
:root.night-mode .el-venue-my-rental-row { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.06); }
:root.night-mode .el-venue-my-rental-head { color: rgba(255,255,255,0.9); }
:root.night-mode .el-venue-my-rental-head:hover { background: rgba(255,255,255,0.04); }
:root.night-mode .el-venue-my-rental-title { color: rgba(255,255,255,0.55); }
:root.night-mode .el-venue-my-rental-total { color: rgba(255,255,255,0.9); }
:root.night-mode .el-venue-my-rentals-head h3 { color: rgba(255,255,255,0.92); }

/* Mobile — collapse head grid to two rows */
@media (max-width: 640px) {
    .el-venue-my-rental-head {
        grid-template-columns: auto 1fr 20px;
        grid-template-areas:
            'date title chevron'
            'status . total';
        row-gap: 6px;
    }
    .el-venue-my-rental-date   { grid-area: date; }
    .el-venue-my-rental-title  { grid-area: title; }
    .el-venue-my-rental-status { grid-area: status; justify-self: start; }
    .el-venue-my-rental-total  { grid-area: total; justify-self: end; }
    .el-venue-my-rental-chevron { grid-area: chevron; }
}
