/* =========================================================================
   GLOBAL STYLES
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;600;700&display=swap');

/* =========================================================================
   DESIGN TOKENS
   Every colour, radius, shadow and type step lives here. Component classes
   below reference these and never hardcode a value — change a token once and
   it moves everywhere. Inline styles in main.js/modules are being migrated
   onto these classes screen by screen; until then the two coexist.
   ========================================================================= */
:root {
  /* Canvas & surfaces — cool light grey (the original app's canvas) */
  --canvas:        #EEF1F5;
  --surface:       #FFFFFF;
  --surface-sunk:  #E5EAF0;

  /* Ink */
  --ink:           #0F172A;   /* primary headings, body */
  --ink-muted:     #64748B;   /* secondary text, metadata, timestamps */
  --ink-faint:     #94A3B8;   /* placeholder, disabled */

  /* Primary — near-black ink for primary actions (buttons, FAB, CTAs) */
  --primary:       #16181D;
  --primary-hover: #2A2D34;
  --primary-ink:   #FFFFFF;

  /* Accent — deep ocean blue, pulled from the blue end of the Withe mark.
     Reserved for ACTIVE states and identity only — never buttons. */
  --accent:        #0B72CE;
  --accent-strong: #0A5FAE;   /* accent as text on white: meets contrast */
  --accent-wash:   #E7F1FB;   /* tinted fills behind accent content */
  --accent-ink:    #FFFFFF;   /* text on an accent fill */

  /* Semantic — separate from the accent, never used decoratively */
  --good:          #15803D;
  --good-wash:     #E8F5EC;
  --warn:          #B45309;
  --warn-wash:     #FBF1E3;
  --bad:           #BE123C;
  --bad-wash:      #FCEBF0;

  /* Hairlines & shadow — borders do the work, not drop shadows */
  --hairline:      rgba(0, 0, 0, 0.05);
  --hairline-firm: rgba(0, 0, 0, 0.09);
  --shadow-micro:  0 1px 3px rgba(0, 0, 0, 0.04);
  --shadow-lift:   0 6px 20px -8px rgba(15, 23, 42, 0.18);

  /* Frosted glass */
  --frost-bg:      rgba(255, 255, 255, 0.85);
  --frost-canvas:  rgba(238, 241, 245, 0.86);   /* frost tinted to the grey canvas */
  --frost-blur:    blur(12px) saturate(160%);
  --frost-edge:    1px solid rgba(0, 0, 0, 0.06);

  /* Tinted fills for chips and badges */
  --tint:          rgba(0, 0, 0, 0.04);
  --tint-firm:     rgba(0, 0, 0, 0.07);

  /* Radii */
  --r-card:        15px;
  --r-control:     10px;
  --r-pill:        9999px;

  /* Type — Quicksand ships 300–700 only; weight-800 requests resolve to 700 */
  --font-sans: 'Quicksand', ui-sans-serif, system-ui,
               -apple-system, 'SF Pro Text', 'Segoe UI', sans-serif;

  /* Spacing rhythm */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;
  --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;

  /* Shell metrics — shared by CSS and the responsive shell */
  --tabbar-h: 62px;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--canvas);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--accent);
  color: var(--accent-ink);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background: #CDD6E0;
  border-radius: 8px;
  border: 2px solid var(--canvas);
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* =========================================================================
   TYPE ROLES
   ========================================================================= */
.w-title {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink);
  text-wrap: balance;
  margin: 0;
}

.w-heading {
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.3;
  color: var(--ink);
  margin: 0;
}

.w-meta {
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ink-muted);
}

.w-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: var(--r-pill);
  background: var(--tint);
  color: var(--ink-muted);
  white-space: nowrap;
}

.w-badge.is-good { background: var(--good-wash); color: var(--good); }
.w-badge.is-warn { background: var(--warn-wash); color: var(--warn); }
.w-badge.is-bad  { background: var(--bad-wash);  color: var(--bad); }
.w-badge.is-accent { background: var(--accent-wash); color: var(--accent-strong); }

/* =========================================================================
   CARDS
   A card is a 3-part horizontal flow:
     left   visual anchor (date badge, avatar, boat marker)
     center title + metadata, takes the slack
     right  status tag or quick action
   ========================================================================= */
.w-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-micro);
  padding: var(--sp-4);
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}

.w-card + .w-card { margin-top: var(--sp-3); }

.w-card.is-tappable { cursor: pointer; }
.w-card.is-tappable:hover { border-color: var(--hairline-firm); }
.w-card.is-tappable:active { transform: scale(0.99); }

.w-card.is-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), var(--shadow-micro);
}

.w-card-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.w-card-body {
  flex: 1;
  min-width: 0;              /* lets long titles ellipsis instead of pushing */
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.w-card-body .w-heading,
.w-card-body .w-meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.w-card-aside {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

/* Left visual anchor — the date block on a rota or session card */
.w-anchor {
  flex-shrink: 0;
  width: 46px;
  min-height: 46px;
  border-radius: 12px;
  background: var(--surface-sunk);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.05;
  padding: 6px 4px;
}

.w-anchor-top {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ink-muted);
}

.w-anchor-main {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.w-anchor.is-accent { background: var(--accent-wash); }
.w-anchor.is-accent .w-anchor-main { color: var(--accent-strong); }

/* =========================================================================
   FROSTED SURFACES — headers and anything sticky
   ========================================================================= */
.w-frost {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--frost-bg);
  backdrop-filter: var(--frost-blur);
  -webkit-backdrop-filter: var(--frost-blur);
  border-bottom: var(--frost-edge);
}

.w-frost.is-bottom {
  top: auto;
  bottom: 0;
  border-bottom: none;
  border-top: var(--frost-edge);
}

/* Safari/Firefox without backdrop-filter get an opaque surface instead of
   an unreadable translucent one. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .w-frost { background: rgba(255, 255, 255, 0.97); }
}

/* =========================================================================
   TABS, CHIPS & FILTERS
   ========================================================================= */
.w-tabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding: 6px 0;
}
.w-tabs::-webkit-scrollbar { display: none; }

.w-tab {
  flex: 0 0 auto;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  padding: 8px 15px;
  border: none;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease;
}

.w-tab:hover { background: var(--tint); color: var(--ink); }

.w-tab.is-active {
  background: var(--surface);
  color: var(--ink);
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.07);
}

/* Filter pills (.w-tabs.w-filter): same look as the nav pills — only the
   SELECTED option wears the white pill with a shadow (the base .w-tab.is-active
   above); the rest read as plain text. */

/* Filter trigger: compact pill with a caret */
.w-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 7px 12px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--tint);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease;
}

.w-chip:hover { background: var(--tint-firm); }
.w-chip:active { transform: scale(0.98); }

.w-chip.is-active {
  background: var(--accent-wash);
  color: var(--accent-strong);
  font-weight: 600;
}

.w-chip::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
  border-top: 4px solid currentColor;
  opacity: 0.55;
}

.w-chip.no-caret::after { display: none; }

/* =========================================================================
   BUTTONS & FAB
   Buttons are deliberately NOT pill-shaped — pills mean navigation/filters;
   buttons get the squarer control radius and a consistent height.
   ========================================================================= */
.w-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  height: 38px;
  padding: 0 18px;
  border-radius: var(--r-control);
  border: 1px solid var(--hairline-firm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.12s ease, background 0.15s ease, border-color 0.15s ease;
}

.w-btn:hover { background: var(--surface-sunk); }
/* Club read-only (billing past_due / cancelled): grey out actions. Pragmatic
   v1 — dataService.readOnly is the real guard; this is the visual cue. */
[data-readonly] button.w-btn, [data-readonly] .w-btn { pointer-events: none; opacity: .55; }
/* Small, non-blocking club status banner above the top bar (trial / past due) */
.w-club-banner { padding: 6px 16px; font-size: 12px; font-weight: 600; text-align: center; color: var(--warn); background: var(--warn-wash); border-bottom: 1px solid var(--hairline-firm); }
.w-btn:active { transform: scale(0.98); }

.w-btn.is-primary {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--primary-ink);
}
.w-btn.is-primary:hover { background: var(--primary-hover); }

.w-btn.is-quiet {
  background: transparent;
  border-color: transparent;
  color: var(--ink-muted);
}
.w-btn.is-quiet:hover { background: var(--tint); color: var(--ink); }

.w-btn.is-danger {
  background: var(--bad);
  border-color: var(--bad);
  color: #FFFFFF;
}
.w-btn.is-danger:hover { background: #A50F34; }

.w-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

/* Compact button — toolbar actions that must stay one line high */
.w-btn.is-sm {
  height: 31px;
  padding: 0 13px;
  font-size: 12.5px;
  gap: 5px;
}

.w-fab {
  position: fixed;
  right: 18px;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  width: 54px;
  height: 54px;
  border-radius: var(--r-pill);
  border: none;
  background: var(--primary);
  color: var(--primary-ink);
  font-size: 26px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-lift);
  cursor: pointer;
  z-index: 60;
  transition: transform 0.12s ease, background 0.15s ease;
}

.w-fab:hover { background: var(--primary-hover); }
.w-fab:active { transform: scale(0.94); }

@media (prefers-reduced-motion: reduce) {
  .w-card, .w-btn, .w-chip, .w-fab, .w-tab { transition: none; }
  .w-card.is-tappable:active,
  .w-btn:active, .w-chip:active, .w-fab:active { transform: none; }
}

/* =========================================================================
   PAGE-ENTRY ANIMATION
   main.js puts .stage-enter on #module-stage on NAVIGATION only (then removes
   it), so each page's top-level components rise in with a subtle stagger —
   data re-renders mid-task never replay it.
   ========================================================================= */
@keyframes w-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.stage-enter .animate-fade-in > * {
  animation: w-rise 0.38s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
.stage-enter .animate-fade-in > *:nth-child(2) { animation-delay: 0.05s; }
.stage-enter .animate-fade-in > *:nth-child(3) { animation-delay: 0.10s; }
.stage-enter .animate-fade-in > *:nth-child(4) { animation-delay: 0.15s; }
.stage-enter .animate-fade-in > *:nth-child(5) { animation-delay: 0.20s; }
.stage-enter .animate-fade-in > *:nth-child(n+6) { animation-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  .stage-enter .animate-fade-in > * { animation: none; }
}

/* =========================================================================
   ATOMIC UTILITIES (used throughout the existing inline markup — keep)
   ========================================================================= */
.fx { display: flex; }
.col { display: flex; flex-direction: column; }
.grid { display: grid; }
.ac { align-items: center; }
.jc { justify-content: center; }
.jb { justify-content: space-between; }
.f1 { flex: 1; }
.noshrink { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
.fw5 { font-weight: 500; }
.fw6 { font-weight: 600; }
.fw7 { font-weight: 700; }
.fw8 { font-weight: 800; }
.fs11 { font-size: 11px; }
.fs12 { font-size: 12px; }
.fs13 { font-size: 13px; }
.fs14 { font-size: 14px; }
.fs15 { font-size: 15px; }
.fs16 { font-size: 16px; }
.fs20 { font-size: 20px; }
.fs22 { font-size: 22px; }
.tc { text-align: center; }
.nowrap { white-space: nowrap; }
.gap8 { gap: 8px; }
.gap10 { gap: 10px; }
.gap12 { gap: 12px; }
.gap16 { gap: 16px; }
.gap24 { gap: 24px; }
.m0 { margin: 0; }
.mt8 { margin-top: 8px; }
.mt12 { margin-top: 12px; }
.mt16 { margin-top: 16px; }
.mb8 { margin-bottom: 8px; }
.mb12 { margin-bottom: 12px; }
.mb16 { margin-bottom: 16px; }
.posrel { position: relative; }
.posabs { position: absolute; }
.round { border-radius: 50%; }
.ohide { overflow: hidden; }
.bbox { box-sizing: border-box; }
.pointer { cursor: pointer; }
.w100 { width: 100%; }
.b0 { border: none; }

/* =========================================================================
   SCREENS (mobile content fallbacks for unmigrated modules)
   ========================================================================= */
/* Admin → Members: table on desktop, cards on mobile (the 7-column table
   cannot fit a phone and its actions column was clipped off-screen). */
.w-members-cards { display: none; }

@media (max-width: 880px) {
  body { overflow-x: hidden; }
  .w-members-tablewrap { display: none; }
  .w-members-cards { display: flex; flex-direction: column; gap: 10px; }
  /* Inputs under 16px make mobile browsers auto-zoom on focus — the page then
     stays zoomed, which broke fixed-position overlays like the intro tour. */
  input, select, textarea { font-size: 16px !important; }
  [style*="grid-template-columns"]:not([style*="auto-fill"]):not([style*="auto-fit"]) { grid-template-columns: 1fr !important; }
  [style*="width: 530px"], [style*="width:530px"] { width: 100% !important; }
  h1:not(.w-page-title) { font-size: 22px !important; }
  .w-title { font-size: 24px; }

  /* Page-header rows: keep the title on its own line and stack whatever sat
     beside it (date pickers, filters, actions) underneath. */
  div[style*="space-between"]:has(> div > .w-page-title),
  div[style*="space-between"]:has(> .w-page-title) { display: block !important; }
  div[style*="space-between"]:has(> div > .w-page-title) > * + *,
  div[style*="space-between"]:has(> .w-page-title) > * + * { margin-top: 12px; flex-wrap: wrap; row-gap: 8px; }
  div[style*="space-between"]:has(.w-page-title) select { max-width: 100%; }
  /* Pill rows never wrap — they stay on one line and scroll sideways, even
     when the header-stacking rule above tries to set flex-wrap on them. */
  .w-tabs { flex-wrap: nowrap !important; max-width: 100%; min-width: 0; }

  /* Create Rota → Session Boards: Publish goes underneath the title */
  .w-boards-head { display: block !important; }
  .w-boards-head .w-btn { margin-top: 10px; width: 100%; }

  /* V9: boat cards on a phone — at most TWO side by side, then wrap.
     The gym (indoor) card always takes the full width. */
  .w-boat-row { flex-wrap: wrap; }
  .w-boat-card { flex: 1 1 calc(50% - 5px) !important; max-width: calc(50% - 5px); }
  .w-boat-card.is-gym { flex-basis: 100% !important; max-width: 100%; }
}

@media print {
  body * { visibility: hidden !important; }
  #coxcard-print, #coxcard-print * { visibility: visible !important; -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  #coxcard-print { position: fixed !important; left: 0 !important; top: 0 !important; right: 0 !important; margin: 0 auto !important; width: 100% !important; max-width: 700px !important; box-shadow: none !important; }
  @page { margin: 12mm; }
}

/* =========================================================================
   APP SHELL — ink sidebar on desktop, floating ink dock on mobile.
   Both render from the same nav config in main.js; only the shell forks
   at 880px.
   ========================================================================= */
.app-shell {
  display: flex;
  min-height: 100vh;
  background: var(--canvas);
}

/* --- Ink sidebar (desktop) --- */
.w-sidebar {
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;
  width: 232px;
  background: var(--primary);
  z-index: 100;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.w-sidebar-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 22px 20px 18px;
}
.w-sidebar-brand .name { font-size: 16px; font-weight: 700; color: #fff; line-height: 1.2; }
.w-sidebar-brand .sub  { font-size: 10px; font-weight: 600; color: rgba(255, 255, 255, 0.4); }

.w-sidebar-nav { padding: 6px 12px 0; }

.w-nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 14px;
  margin-bottom: 2px;
  border: none;
  border-radius: 12px;
  background: transparent;
  color: #9BA3AF;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.w-nav-item:hover { background: rgba(255, 255, 255, 0.06); color: #fff; }
.w-nav-item.is-active { background: rgba(255, 255, 255, 0.1); color: #fff; font-weight: 700; }
.w-nav-ic { width: 20px; height: 20px; flex-shrink: 0; }
.w-nav-item.is-active .w-nav-ic { color: #4DA3E8; }

/* Help & guides pinned to the bottom of the sidebar, above the build line */
.w-sidebar-help {
  margin-top: auto;
  padding: 6px 12px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
.w-sidebar-help .w-nav-item { text-decoration: none; }

.w-sidebar-foot {
  padding: 12px 20px 18px;
  font-size: 11.5px;
  color: rgba(255, 255, 255, 0.35);
  line-height: 1.4;
}

/* Copyright line: sidebar foot (desktop), More sheet (mobile), sign-in card */
.w-copyright {
  font-size: 11px;
  line-height: 1.4;
  color: var(--ink-muted);
}
.w-sidebar-foot .w-copyright { margin-top: 4px; color: inherit; }
.w-sheet .w-copyright { text-align: center; padding-top: 12px; }

/* --- Stage & top bar --- */
.w-stage {
  margin-left: 232px;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-width: 0;
}

/* Two rows, always: the account row (bell, season, name, avatar) sits ABOVE
   the subtab pills, so the pills can take the full width and the bell and
   avatar never fight them for space on a phone. */
.w-topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 2px 12px;
  padding: 8px 28px 6px;
  background: var(--frost-canvas);
  backdrop-filter: var(--frost-blur);
  -webkit-backdrop-filter: var(--frost-blur);
}
.w-topbar .w-tabs { flex: 1 1 100%; min-width: 0; }

.w-topbar-right {
  order: -1;
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
}

.w-userblock { display: flex; align-items: center; gap: 10px; }
.w-usermeta { text-align: right; line-height: 1.2; }
.w-usermeta .who { font-size: 13px; font-weight: 700; color: var(--ink); }
.w-roleselect {
  font-size: 11px;
  color: var(--ink-muted);
  border: none;
  background: transparent;
  cursor: pointer;
  font-family: inherit;
  padding: 0;
}
.w-avatar {
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pill);
  /* Same identity gradient as the Rower Profile avatar */
  background: linear-gradient(135deg, #27C0A8, #0B72CE);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  letter-spacing: .02em;
  flex-shrink: 0;
}

.w-main {
  padding: 26px 32px;
  flex: 1;
}

/* --- Floating ink dock (mobile) --- */
.w-dock {
  position: fixed;
  left: 14px;
  right: 14px;
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  z-index: 90;
  display: none;
  justify-content: space-around;
  padding: 9px 6px;
  background: var(--primary);
  border-radius: var(--r-pill);
  box-shadow: 0 8px 26px -6px rgba(15, 23, 42, 0.45);
}

.w-dock-item {
  border: none;
  background: transparent;
  text-align: center;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 600;
  color: #9BA3AF;
  cursor: pointer;
  line-height: 1.2;
  padding: 2px 8px;
}
.w-dock-item svg { display: block; margin: 0 auto 2px; width: 19px; height: 19px; }
.w-dock-item.is-active { color: #fff; font-weight: 700; }
.w-dock-item.is-active svg { color: #4DA3E8; }

/* --- "More" sheet (mobile) --- */
.w-sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 95;
  background: rgba(15, 23, 42, 0.4);
}

.w-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 96;
  background: var(--surface);
  border-radius: 20px 20px 0 0;
  padding: 10px 16px calc(20px + env(safe-area-inset-bottom, 0px));
  box-shadow: var(--shadow-lift);
}

.w-sheet-grab {
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--hairline-firm);
  margin: 0 auto 12px;
}

.w-sheet-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 14px;
  border: none;
  border-radius: 12px;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 14.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.w-sheet-item:active { background: var(--tint); }
.w-sheet-item.is-active { background: var(--accent-wash); color: var(--accent-strong); }
.w-sheet-item .w-nav-ic { color: var(--ink-muted); }
.w-sheet-item.is-active .w-nav-ic { color: var(--accent-strong); }

/* Bottom row of the More sheet: Sign out on the left, round help icon on the right */
.w-sheet-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.w-sheet-foot .w-sheet-item { flex: 1; width: auto; }
.w-sheet-help {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  margin-right: 6px;
  border-radius: var(--r-pill);
  background: var(--tint);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}
.w-sheet-help svg { width: 22px; height: 22px; }
.w-sheet-help:active { background: var(--tint-firm); }

.w-sheet-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border-top: 1px solid var(--hairline);
  margin-top: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-muted);
}

/* --- Page headers --- */
.w-page-eyebrow {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted);
  margin-bottom: 2px;
}

.w-page-title {
  margin: 0;
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink);
  text-wrap: balance;
}

/* --- Active-indicator glide ---
   The shell re-renders on navigation, so the active pill can't CSS-transition;
   instead the View Transitions API morphs it between renders. Only the named
   indicators animate — the root crossfade is disabled so content still
   switches instantly. */
.w-tab.is-active      { view-transition-name: active-pill; }
.w-nav-item.is-active { view-transition-name: active-nav; }
.w-dock-item.is-active { view-transition-name: active-dock; }
/* In-page filter rows reuse the .w-tab look; their active pill must NOT share
   the nav's `active-pill` name (duplicate names abort every view transition on
   the page). Each filter group instead gets its OWN unique name inline (set by
   filterPills() in src/js/pills.js) so its black pill glides too; this rule is
   the fallback for any filter row without one. */
.w-tabs.w-filter .w-tab.is-active {
  view-transition-name: none;
  view-transition-class: w-filter-pill;
}

::view-transition-old(root),
::view-transition-new(root) { animation: none; }

/* The sticky top bar and floating dock are lifted as their own layers and
   stacked ABOVE any content layer (e.g. a gliding filter pill), so page
   content can never paint over the navigation during a transition. Their
   own active pills sit higher still. */
.w-topbar { view-transition-name: w-topbar; }
.w-dock   { view-transition-name: w-dock; }
::view-transition-group(w-topbar),
::view-transition-group(w-dock) { z-index: 60; }
/* A lifted layer can't re-run backdrop-filter, and the top bar's frost is
   translucent — without an opaque backing the page title shows through it
   during the transition (the mobile "title over the nav pills" glitch). */
::view-transition-group(w-topbar) { background: var(--canvas); }
::view-transition-group(active-pill),
::view-transition-group(active-nav),
::view-transition-group(active-dock) { z-index: 70; }

/* Filter-change transitions (html.vt-chrome-static, set by rerenderT): the
   chrome doesn't move, so its pills are left OUT of the overlay — a lifted
   layer ignores its row's overflow clipping, letting a clipped nav pill
   momentarily paint over the avatar. The filter pills' own inline
   view-transition-name overrides these, so they still glide. */
html.vt-chrome-static .w-tab.is-active { view-transition-name: none; }
html.vt-chrome-static .w-nav-item.is-active { view-transition-name: none; }
html.vt-chrome-static .w-dock-item.is-active { view-transition-name: none; }

::view-transition-group(active-pill),
::view-transition-group(active-nav),
::view-transition-group(active-dock) {
  animation-duration: 0.28s;
  animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1);
}

/* Separate rule: browsers without view-transition-class support would drop a
   combined selector list entirely, killing the nav timings above. */
::view-transition-group(.w-filter-pill) {
  animation-duration: 0.28s;
  animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1);
}

/* Subtab labels: full name on desktop, shortLabel on mobile */
.w-lbl-short { display: none; }

/* --- The fork --- */
@media (max-width: 880px) {
  .w-sidebar { display: none; }
  .w-lbl-full { display: none; }
  .w-lbl-short { display: inline; }

  /* The BODY never scrolls on mobile — the stage is the scroller. If the body
     scrolls, iOS resizes the layout viewport as its toolbars collapse and the
     fixed dock rides down with it, ending up partly off-screen. With an inner
     scroller the viewport never moves, so the dock is always fully visible. */
  html, body { height: 100%; overflow: hidden; }
  .app-shell { height: 100vh; height: 100dvh; min-height: 0; }
  .w-stage {
    min-height: 0;
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
  }

  /* Mobile page titles run BIGGER than desktop, Spond-style (see mockups) */
  .w-page-title { font-size: 34px; }

  /* Context-aware subtabs: arriving via a dock item narrows My Profile's
     pill bar to that context (desktop always shows all three). */
  .dock-ctx-availability .w-tab[data-tab="myprofile"] { display: none; }
  .dock-ctx-profile .w-tab[data-tab="availability"],
  .dock-ctx-profile .w-tab[data-tab="race-availability"] { display: none; }
  .w-stage { margin-left: 0; }
  .w-topbar { padding: 10px 14px; }
  .w-topbar .w-season { display: none; }
  .w-usermeta { display: none; }
  .w-dock { display: flex; }
  .w-main { padding: 18px 13px calc(84px + env(safe-area-inset-bottom, 0px)); }
  .w-fab { bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
}

/* =========================================================================
   DIALOGS — branded replacements for alert / confirm / prompt (src/js/dialog.js)
   ========================================================================= */
.w-dialog-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(15, 23, 42, 0.34);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: w-dialog-fade 0.16s ease;
}

.w-dialog {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--hairline-firm);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-lift);
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  animation: w-dialog-pop 0.18s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

.w-dialog-brand {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--hairline);
}
.w-dialog-brand img { width: 24px; height: auto; display: block; }
.w-dialog-brand span {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent-strong);
}

.w-dialog-msg {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink);
  white-space: pre-line;          /* messages use \n for lists */
  overflow-wrap: anywhere;
  max-height: 55vh;
  overflow-y: auto;
}

.w-dialog-input {
  width: 100%;
  margin-top: var(--sp-4);
  padding: 10px 12px;
  border: 1px solid var(--hairline-firm);
  border-radius: var(--r-control);
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--surface);
}

.w-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
}

@keyframes w-dialog-fade { from { opacity: 0; } }
@keyframes w-dialog-pop  { from { opacity: 0; transform: scale(0.94) translateY(8px); } }

@media (prefers-reduced-motion: reduce) {
  .w-dialog-overlay, .w-dialog { animation: none; }
}

/* =========================================================================
   SELECTS — modern rounded dropdowns
   The closed buttons are still mostly inline-styled per screen; this layer
   owns the OPEN picker via customizable <select> (Chromium 135+). Browsers
   without ::picker(select) support keep their native picker untouched.
   ========================================================================= */
select {
  font-family: inherit;
  cursor: pointer;
  accent-color: var(--accent);
}

/* Legacy form controls (log/create-session modals) never got a class def */
.form-control {
  box-sizing: border-box;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--hairline-firm);
  border-radius: var(--r-control);
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--surface);
}

@supports selector(::picker(select)) {
  select:not([multiple]):not([size]),
  select:not([multiple]):not([size])::picker(select) {
    appearance: base-select;
  }

  /* The open panel: rounded card floating just below the button */
  ::picker(select) {
    margin-block: 5px;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--hairline-firm);
    border-radius: 14px;
    box-shadow: var(--shadow-lift);
    opacity: 1;
    transition: opacity 0.14s ease, transform 0.14s ease,
                overlay 0.14s ease allow-discrete, display 0.14s ease allow-discrete;
  }
  @starting-style {
    ::picker(select) { opacity: 0; transform: translateY(-5px); }
  }

  select option {
    padding: 9px 12px;
    border-radius: 9px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--ink);
    cursor: pointer;
  }
  select option:hover,
  select option:focus-visible { background: var(--tint-firm); }
  select option:checked {
    background: var(--accent-wash);
    color: var(--accent-strong);
    font-weight: 600;
  }
  select option::checkmark { color: var(--accent-strong); }

  select optgroup { font-size: 12px; color: var(--ink-muted); }

  /* Chevron replaces the native arrow; flips while open */
  select::picker-icon {
    color: var(--ink-muted);
    transition: rotate 0.14s ease;
  }
  select:open::picker-icon { rotate: 180deg; }

  @media (prefers-reduced-motion: reduce) {
    ::picker(select), select::picker-icon { transition: none; }
  }
}

/* ── Switch (V10 notifications card) ─────────────────────────────── */
.w-switch { position: relative; display: inline-block; width: 44px; height: 26px; flex-shrink: 0; }
.w-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.w-switch span { position: absolute; inset: 0; border-radius: 26px; background: #CBD2DB; cursor: pointer; transition: background .2s; }
.w-switch span::before { content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: transform .2s; }
.w-switch input:checked + span { background: var(--good); }
.w-switch input:checked + span::before { transform: translateX(18px); }
.w-switch input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }
.w-switch input:disabled + span { opacity: .45; cursor: not-allowed; }
/* ── Notifications: bell + inbox (V10) ───────────────────────────── */
.w-bell { position: relative; width: 36px; height: 36px; border: none; border-radius: 50%; background: none; color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.w-bell svg { width: 20px; height: 20px; }
.w-bell:hover { background: var(--tint-firm); }
.w-bell-badge { position: absolute; top: 3px; right: 2px; min-width: 17px; height: 17px; padding: 0 5px; border-radius: 9px; background: var(--bad); color: #fff; font-size: 11px; font-weight: 700; line-height: 17px; text-align: center; box-sizing: border-box; }
.w-notif-list { display: grid; gap: 10px; max-width: 720px; }
.w-notif-wrap { position: relative; border-radius: 14px; overflow: hidden; max-height: 400px; }
.w-notif-under { position: absolute; inset: 0; display: flex; align-items: center; justify-content: flex-end; padding-right: 22px; background: var(--bad); color: #fff; font-size: 13px; font-weight: 700; opacity: .85; }
.w-notif-wrap.will-delete .w-notif-under { opacity: 1; }
.w-notif { position: relative; display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px 14px 14px; background: #fff; border: 1px solid var(--hairline-firm); border-radius: 14px; cursor: pointer; touch-action: pan-y; will-change: transform; }
.w-notif:hover { background: #FBFCFD; }
.w-notif-dot { width: 8px; height: 8px; margin-top: 7px; border-radius: 50%; background: transparent; flex-shrink: 0; }
.w-notif.is-new .w-notif-dot { background: var(--primary); }
.w-notif-main { flex: 1; min-width: 0; }
.w-notif-title { font-size: 15px; font-weight: 700; color: var(--ink); line-height: 1.3; }
.w-notif.is-new .w-notif-title { font-weight: 800; }
.w-notif-body { font-size: 13.5px; color: var(--ink); line-height: 1.45; margin-top: 4px; white-space: pre-line; }
.w-notif-time { font-size: 12px; color: var(--ink-muted); margin-top: 6px; }
.w-notif-x { width: 30px; height: 30px; margin: -6px -8px 0 0; border: none; border-radius: 50%; background: none; color: var(--ink-muted); font-size: 20px; line-height: 30px; cursor: pointer; flex-shrink: 0; }
.w-notif-x:hover { background: var(--tint-firm); color: var(--ink); }
@media (max-width: 880px) {
  .w-topbar .w-bell { width: 34px; height: 34px; }
  .w-notif-x { display: none; }   /* swipe left instead */
}
/* ── Avatar picture (V10 Google photo) — sits over the initials; if the image
   fails to load it removes itself and the initials show through. */
.w-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.w-avatar-lg { width: 100px; height: 100px; margin: 0 auto 16px; font-family: 'Quicksand', sans-serif; font-size: 32px; font-weight: 800; border-radius: 50%; }

/* ── Live-session takeover (interval runner / manual recording) ──
   While the timer runs the ink panel covers the WHOLE viewport — over the
   top bar, sub-tabs, sidebar and bottom dock — so the cox gets every pixel.
   Sits under dialogs (z 200) so an alert can still surface. Inline padding /
   radius / margin on the panel are overridden here. */
.w-session-full {
  position: fixed;
  inset: 0;
  z-index: 150;
  margin: 0 !important;
  border-radius: 0 !important;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: calc(18px + env(safe-area-inset-top, 0px)) 18px calc(22px + env(safe-area-inset-bottom, 0px)) !important;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: safe center;
}
.w-session-full > * { flex-shrink: 0; }
