/* ── base.css ──────────────────────────────────────────────────*/

  :root {
    /* Fixed nav-bar navy — deliberately NOT overridden in [data-theme="dark"].
       Still the token for every GENERAL app accent usage (buttons, active
       pills/tabs, toggles, badges — see the --nav-navy audit) and for the
       two borderline chrome cases deliberately deferred (club-switcher role
       pill, profile-card-head). Header/nav-bar chrome itself now reads
       --brand-primary instead — see that token's own comment below. */
    --nav-navy: #1a2744;
    /* Per-club header/nav-bar chrome colour — css/shared.css's `nav`,
       `#nav-drawer`, and the active-tab pill (--nav-active-bg below) read
       this instead of --nav-navy. Defaults to the exact same value so an
       unbranded club's nav is pixel-identical to today. Overridden as an
       inline style on <html> at boot by js/auth.js's initClubApp() when
       clubs.primary_color is set — see that function's comment for why this
       is the first runtime-set root-level custom property in the codebase
       (js/branding.js's own --nav-navy override is a different, narrower
       pattern: scoped to its live-preview wrapper element, not the root). */
    --brand-primary: #1a2744;
    /* Nav text colour — computed at boot from --brand-primary via
       js/branding.js's computeNavTextColor() (white vs dark, by luminance),
       so the real nav and the branding editor's preview can never disagree.
       Default white matches today's fixed-navy nav exactly. */
    --nav-text: #ffffff;
    /* Nav's active-tab pill background — today a fixed white-overlay-on-navy
       look; computed at boot from --brand-primary via js/branding.js's
       computeNavActiveBackground() once a club picks its own primary colour,
       since "add a translucent white overlay" only reads as *lighter* when
       the background underneath is dark. Default reproduces today's
       rgba(255,255,255,0.15)-on-#1a2744 look exactly (composited value —
       see that function's comment). */
    --nav-active-bg: rgba(255,255,255,0.15);
    --navy-dark: #1a2744;
    --navy-mid: #243660;
    --navy-light: #e8edf5;
    --m1: #3b82f6; --m1-bg: #dbeafe; --m1-text: #1e3a5f;
    --m2: #7c3aed; --m2-bg: #ede9fe; --m2-text: #3b1c6e;
    --m3: #16a34a; --m3-bg: #dcfce7; --m3-text: #14532d;
    --w1: #db2777; --w1-bg: #fce7f3; --w1-text: #831843;
    --w2: #ea580c; --w2-bg: #ffedd5; --w2-text: #7c2d12;
    --w3: #0891b2; --w3-bg: #cffafe; --w3-text: #164e63;
    --mix: #ca8a04; --mix-bg: #fef9c3; --mix-text: #713f12;
    --notif-urgent: #dc2626;
    --notif-info: #2563eb;
    --bg: #f7f6f3;
    --surface: #ffffff;
    --border: rgba(0,0,0,0.09);
    --border-strong: rgba(0,0,0,0.15);
    --text: #1a1a1a;
    --text-secondary: #666;
    --text-tertiary: #999;
    --radius: 12px;
    --radius-sm: 8px;
    /* iOS-style spring/bounce curve for modal/panel OPEN animations only —
       close animations deliberately use a plain ease-out (no overshoot),
       matching iOS's own asymmetric open/close feel.
       The 2nd value (y1) controls overshoot strength. 1.56 (peak ~9.8% past
       the resting value) read as an obvious, exaggerated bounce and made the
       overshoot-past-resting-position gap at the edge of slide-out panels
       clearly visible. 1.1 (peak ~0.24% past resting) keeps a natural,
       responsive settle without reading as "bouncy", and shrinks that gap to
       a sub-2px sliver on even the largest panel in the app (#roster-panel,
       full viewport height) — below the threshold of visibility. */
    --spring-ease: cubic-bezier(0.32, 1.1, 0.68, 1);
  }

  [data-theme="dark"] {
    --navy-dark: #4a6da3;
    --navy-mid: #6689bb;
    --navy-light: #262d3d;
    --m1: #3b82f6; --m1-bg: rgba(59,130,246,0.18); --m1-text: #93c5fd;
    --m2: #7c3aed; --m2-bg: rgba(124,58,237,0.18); --m2-text: #c4b5fd;
    --m3: #16a34a; --m3-bg: rgba(22,163,74,0.18); --m3-text: #86efac;
    --w1: #db2777; --w1-bg: rgba(219,39,119,0.18); --w1-text: #f9a8d4;
    --w2: #ea580c; --w2-bg: rgba(234,88,12,0.18); --w2-text: #fdba74;
    --w3: #0891b2; --w3-bg: rgba(8,145,178,0.18); --w3-text: #67e8f9;
    --mix: #ca8a04; --mix-bg: rgba(202,138,4,0.18); --mix-text: #fde047;
    --notif-urgent: #f87171;
    --notif-info: #60a5fa;
    --bg: #1f1e1d;
    --surface: #302e2b;
    --border: rgba(255,255,255,0.09);
    --border-strong: rgba(255,255,255,0.16);
    --text: #ece9e5;
    --text-secondary: #b0aaa1;
    --text-tertiary: #8a8479;
  }

  * { box-sizing: border-box; margin: 0; padding: 0; }
  input, select, textarea { font-size: 16px; }
  html {
    overflow-x: hidden;
  }
  body {
    font-family: 'DM Sans', sans-serif;
    background: var(--bg);
    color: var(--text);
    min-height: 100vh;
    overflow-x: hidden;
    width: 100%;
  }

  @supports (padding-bottom: env(safe-area-inset-bottom)) {
    body { padding-bottom: env(safe-area-inset-bottom, 0px); }
    #sticky-header { padding-top: env(safe-area-inset-top, 0px); }
  }

