﻿/* Streamline brand theme (consolidated v3)
   Brand kit: #1D184B, #E6E6E6, #4B88A2, #DAB785, #EC0B43, #D6EDFF
   Font: PT Sans (loaded via Google Fonts in index.html)
   ─────────────────────────────────────────────────────────────── */

:root {
  /* ── Palette: the Figma design system (docs/Design, page 82:2). Tailwind sky/slate around a
        custom navy — see CLAUDE.md §7. ── */
  --sw-primary:        #0369a1;   /* sky-700 — buttons, links, active nav, progress */
  --sw-primary-strong: #075985;   /* sky-800 — hover / pressed */
  --sw-primary-tint: #e0f2fe;   /* sky-100 — selected rows, badges, icon boxes */
  --sw-primary-rgb: 3,105,161;
  --sw-navy: #0a192f;   /* headings, dark headers, the app icon */
  --sw-bg: #eaeff5;   /* light grey-blue — page ground, a step down from the white cards */
  --sw-surface: #ffffff;   /* cards, bars, sheets */
  --sw-surface-sunken: #f1f5f9;   /* slate-100 — table heads, chips, hover */
  --sw-border: #e2e8f0;   /* slate-200 */
  --sw-text: #0a192f;
  --sw-text-2:         #475569;   /* slate-600 — secondary text, nav */
  --sw-muted: #64748b;   /* slate-500 */
  --sw-muted-2:        #94a3b8;   /* slate-400 — labels, inactive nav */
  --sw-accent: #f59e0b;   /* amber-500 — achievement, streaks */
  --sw-accent-tint: #fef3c7;   /* amber-100 */
  --sw-warning: #d97706;   /* amber-600 */
  --sw-success: #059669;   /* emerald-600 */
  --sw-success-tint: #d1fae5;
  /* Training block phases (Performance P4) */
  --sw-phase-base: #0369a1;
  --sw-phase-build: #059669;
  --sw-phase-race: #f59e0b;
  --sw-phase-taper: #7c3aed;
  --sw-phase-other: #94a3b8;
  --sw-danger: #dc2626;   /* red-600 */
  --sw-danger-tint: #fee2e2;
  /* Sunflower — a long session, and the afternoon tag. Deliberately not --sw-accent: amber is
     the warning/achievement colour, and an ordinary session must not read as either. */
  --sw-sunflower: #eab308;   /* yellow-500 */
  --sw-sunflower-tint: #f9e8b5;   /* the same at 30% on white — the faded tag */
  --sw-sunflower-ink: #a16207;   /* yellow-700 — text on the tint, which the tint cannot carry */
  --sw-navy-lt: #1e3a5f;   /* the evening tag — navy, lifted so it is not the near-black */
  --sw-navy-lt-tint: #bcc4cf;   /* the same at 30% on white */

  /* Training zones, by place in the club's list, easy to hard — cool to hot (Services/ZoneColours.cs). */
  /* Training zones matched to heart rate, as a Polar watch colours them (Gideon, 2026-10-21) — Services/ZoneColours.cs. */
  --sw-hr-lightgrey: #cbd5e1; --sw-hr-grey: #64748b; --sw-hr-blue: #2563eb; --sw-hr-green: #16a34a; --sw-hr-yellow: #eab308;
  --sw-hr-orange: #f97316; --sw-hr-deeporange: #c2410c; --sw-hr-red: #ef4444; --sw-hr-deepred: #991b1b; --sw-hr-purple: #9333ea; --sw-hr-black: #1f2937;
  --sw-zone-1: #10b981;
  --sw-zone-2: #38bdf8;
  --sw-zone-3: #0ea5e9;
  --sw-zone-4: #2563eb;
  --sw-zone-5: #f59e0b;
  --sw-zone-6: #f97316;
  --sw-zone-7: #ef4444;
  --sw-zone-8: #a21caf;

  /* Medals — the three national rungs of the SSA qualifying ladder (SANJ, Youth, Senior).
     ⚠ Deliberately NOT --sw-gold, which is a legacy alias below pointing at the primary BLUE.
     Each is a pale tint to fill the chip plus a much darker ink of the same hue, because the
     metals themselves (#D4AF37, #C0C0C0) are unreadable as text on a light ground. */
  --sw-medal-bronze-tint: #f6e3d3;
  --sw-medal-bronze-ink: #9a5b2d;   /* copper/umber */
  --sw-medal-silver-tint: #dfe7f0;   /* a blue-steel cast, so it reads as chosen metal not as
                                        the disabled grey of --sw-surface-sunken */
  --sw-medal-silver-ink: #2f4661;
  --sw-medal-gold-tint: #f9e8b5;   /* the same pair as sunflower, which is already proven on the
                                        tag chips — repeated rather than aliased so the evening
                                        session tag and a Senior Nationals time can drift apart */
  --sw-medal-gold-ink: #a16207;

  /* ── Legacy aliases. The purple/gold brand is gone (§7); these keep any page that still
        names the old tokens legible until it is ported. Do not use them in new work. ── */
  --sw-gold: var(--sw-primary);
  --sw-blue: var(--sw-primary);
  --sw-ice: var(--sw-primary-tint);
  --sw-surface-lt: var(--sw-surface-sunken);
  --sw-surface-solid: var(--sw-surface);

  --sw-radius: 16px;
  --sw-radius-sm: 12px;
  --sw-radius-pill: 999px;
  /* Spacing scale (declutter plan step 2): five steps, so a gap is chosen rather than invented. */
  --sw-space-1: 4px;
  --sw-space-2: 8px;
  --sw-space-3: 12px;
  --sw-space-4: 16px;
  --sw-space-5: 24px;

  --sw-shadow: 0 1px 2px rgba(15,23,42,0.06), 0 8px 24px rgba(15,23,42,0.08);
  --sw-shadow-sm: 0 1px 2px rgba(15,23,42,0.05), 0 2px 8px rgba(15,23,42,0.06);

  --sw-maxw: 1100px;
  --sw-bottomnav-h: 74px;
}

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family:  "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--sw-bg);
  color: var(--sw-text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}


/* ═══════════════════════════════════════════════════════════════
   TYPOGRAPHY
   ═══════════════════════════════════════════════════════════════ */

h1, .sw-h1 {
  margin: 0 0 1rem 0;
  font-size: 1.75rem;
  letter-spacing: -0.01em;
  font-weight: 800;
  color: var(--sw-navy);
}


/* ═══════════════════════════════════════════════════════════════
   TOP BAR / NAVIGATION
   ═══════════════════════════════════════════════════════════════ */

.sw-topbar,
.top-row {
  position: sticky;
  top: 0;
  z-index: 2000;
  background: var(--sw-surface);
  border-bottom: 1px solid var(--sw-border);
}

.sw-topbar__inner {
  padding: .5rem 1rem;
  display: flex;
  align-items: center;
  gap: .6rem;
}

/* Brand / logo */
.sw-brand {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-shrink: 0;
}
/* The lockup proportions come from docs/Design/brand/README.md: badge ~28px, wordmark ~120px wide. */
.sw-brand__lockup { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.sw-brand__badge { width: 28px; height: 28px; display: block; }
.sw-brand__wordmark { height: 18px; width: auto; display: block; }
.sw-brand__name {
  color: var(--sw-navy) !important;
  text-decoration: none;
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* Desktop nav */
.sw-nav {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex: 1;
  min-width: 0;
  justify-content: center;
}
.sw-nav__link {
  color: var(--sw-text-2);
  text-decoration: none;
  font-weight: 600;
  font-size: .875rem;
  padding: .4rem .7rem;
  border-radius: 10px;
  background: transparent;
  border: 1px solid transparent;
  transition: background .12s ease, color .12s ease;
  white-space: nowrap;
}
.sw-nav__link:hover {
  background: var(--sw-surface-sunken);
  color: var(--sw-navy);
}
.sw-nav__link--active {
  background: var(--sw-primary-tint) !important;
  border-color: transparent !important;
  color: var(--sw-primary) !important;
}
.sw-nav__link--dd {
  cursor: pointer;
  user-select: none;
}

/* ── Nav dropdowns ── */
.sw-nav__dropdown {
  position: relative;
  outline: none;
}
.sw-nav__dd-panel {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--sw-surface);
  border: 1px solid var(--sw-border);
  border-radius: var(--sw-radius-sm);
  box-shadow: var(--sw-shadow);
  padding: .35rem;
  min-width: 160px;
  z-index: 3000;
}
.sw-nav__dropdown:hover .sw-nav__dd-panel,
.sw-nav__dropdown:focus-within .sw-nav__dd-panel {
  display: block;
}
.sw-nav__dd-item {
  display: block;
  padding: .5rem .8rem;
  border-radius: 8px;
  color: var(--sw-text-2);
  text-decoration: none;
  font-weight: 600;
  font-size: .875rem;
  white-space: nowrap;
  transition: background .1s ease;
}
.sw-nav__dd-item:hover {
  background: var(--sw-surface-sunken);
  color: var(--sw-navy);
}
.sw-nav__dd-item--active {
  background: var(--sw-primary-tint) !important;
  color: var(--sw-primary) !important;
}

.sw-topbar__right {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-shrink: 0;
}

/* Role / Club selects in topbar */
.sw-topbar select,
.top-row select {
  background: var(--sw-surface);
  color: var(--sw-text);
  border: 1px solid var(--sw-border);
  border-radius: 10px;
  padding: .3rem .5rem;
  font-weight: 600;
  font-size: .8rem;
  font-family: inherit;
}

/* Nav links inside old MainLayout .top-row (fallback) */
.top-row a,
.top-row .nav-link {
  color: var(--sw-text-2) !important;
  text-decoration: none !important;
  font-weight: 600;
}


/* ── Burger (mobile) ── */

.sw-burger {
  display: none;
  width: 42px;
  height: 42px;
  padding: 0;
  border-radius: 12px;
  border: 1px solid var(--sw-border);
  background: var(--sw-surface);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  cursor: pointer;
}
.sw-burger span {
  display: block;
  flex-shrink: 0;
  width: 18px;
  height: 2px;
  background: var(--sw-navy);
  border-radius: 4px;
}


/* ── Drawer (mobile slide-out) ── */

.sw-drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.35);
  z-index: 2100;
}

.sw-drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: 340px;
  max-width: 92vw;
  background: var(--sw-surface);
  color: var(--sw-text);
  border-left: 1px solid var(--sw-border);
  box-shadow: var(--sw-shadow);
  z-index: 2200;
  padding: 1rem;
  overflow: auto;
}

.sw-drawer__title {
  font-weight: 800;
  color: var(--sw-navy);
  margin-bottom: .75rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
}

.sw-drawer__close {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  border: 1px solid var(--sw-border);
  background: var(--sw-surface);
  color: var(--sw-navy);
  font-weight: 700;
  cursor: pointer;
}

.sw-drawer__nav {
  display: flex;
  flex-direction: column;
  gap: .2rem;
  margin: .5rem 0 1rem 0;
}
.sw-drawer__link {
  display: block;
  padding: .65rem .75rem;
  border-radius: 10px;
  color: var(--sw-text-2);
  text-decoration: none;
  font-weight: 600;
}
.sw-drawer__link:hover {
  background: var(--sw-surface-sunken);
  color: var(--sw-navy);
}
.sw-drawer__link--active {
  background: var(--sw-primary-tint);
  color: var(--sw-primary) !important;
  border: 1px solid transparent;
}

.sw-drawer__group-label {
  font-weight: 700;
  font-size: .7rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--sw-muted-2);
  padding: .6rem 0 .15rem 0;
}

.sw-divider {
  height: 1px;
  background: var(--sw-border);
  margin: .9rem 0;
}


/* ── Responsive: collapse desktop nav ── */

/* ── Top bar: shed content before the nav runs out of room ─────────────────
   The nav is the only flex child that can shrink, its pills are nowrap, and the
   Manage/Admin dropdown panels are position:absolute *inside* it — so `overflow`
   here would clip them and cannot be used to contain the spill. Instead the bar
   drops its least important pieces as it narrows, so the nav never has to
   overflow in the first place.

   Signed in as a club admin the full bar needs roughly 1520px (measured), which
   is wider than any laptop. Hence the first step comes in early. */

/* 1. The email goes first — it is the least useful of the three, and the drawer
      still shows it. 1650 rather than 1550: the 1520px figure is a measurement of
      one case, and the bar is wider with a long email or a two-role select, so
      this leaves room for the estimate to be wrong. */
@media (max-width: 1650px) {
  .sw-topbar__email { display: none; }
}

/* 2. Then the club name. The role stays: it changes what the nav contains. */
@media (max-width: 1400px) {
  .sw-topbar__club { display: none; }
}

/* 3. Then the pills tighten. Worth ~130px across nine of them. */
@media (max-width: 1300px) {
  .sw-nav { gap: .25rem; }
  .sw-nav__link { padding: .35rem .5rem; font-size: .8125rem; }
}

/* 4. Finally the desktop nav gives up and the burger takes over. Raised from
      900px, which was well below the width the bar actually needs — that gap was
      where the wordmark and the email got painted over (§12 item 10). */
@media (max-width: 1150px) {
  .sw-nav--desktop,
  .sw-topbar__desktop {
    display: none !important;
  }
  .sw-burger {
    display: inline-flex;
  }
  .sw-brand { min-width: 0; }
}


/* ═══════════════════════════════════════════════════════════════
   CONTROLS (inputs, selects)
   ═══════════════════════════════════════════════════════════════ */

.sw-control,
.sw-field input,
.sw-field select,
.sw-field textarea {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: var(--sw-text);
  background: var(--sw-surface);
  border: 1px solid var(--sw-border);
  border-radius: 999px;
  padding: .72rem .95rem;
  font-weight: 700;
  outline: none;
  min-height: 44px;
}

.sw-control:focus,
.sw-field input:focus,
.sw-field select:focus,
.sw-field textarea:focus {
  border-color: var(--sw-primary-tint);
  box-shadow: 0 0 0 4px var(--sw-primary-tint);
}

.sw-control--compact {
  min-height: 34px;
  padding: .35rem .65rem;
  border-radius: 999px;
  font-size: .88rem;
  font-weight: 800;
}

.sw-control[type="checkbox"] {
  min-height: auto;
  box-shadow: none;
}

/* The control reset above is written for text boxes and selects, and a checkbox caught by it comes
   out as a 44px empty pill with no tick — appearance:none removes the box the browser draws, and
   nothing replaces it. Any checkbox inside a .sw-field hit this. Opt them back out. */
.sw-field input[type="checkbox"],
.sw-field input[type="radio"] {
  appearance: auto;
  -webkit-appearance: auto;
  width: 18px; height: 18px;
  min-height: 0; padding: 0;
  border: 0; border-radius: 0;
  background: none;
  accent-color: var(--sw-primary);
  flex-shrink: 0;
}
.sw-field input[type="checkbox"]:focus,
.sw-field input[type="radio"]:focus { box-shadow: none; }

input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--sw-gold);
}


/* ═══════════════════════════════════════════════════════════════
   CARDS
   ═══════════════════════════════════════════════════════════════ */

.sw-card {
  border-radius: var(--sw-radius);
  overflow: hidden;
  background: var(--sw-surface);
  border: 1px solid var(--sw-border);
  box-shadow: var(--sw-shadow-sm);
  color: var(--sw-text);
}

.sw-card__header {
  background: var(--sw-surface);
  color: var(--sw-text);
  padding: 1rem 1rem .25rem 1rem;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .75rem;
}

/* A collapsible card's title doubles as its button. Strips the button chrome so a shut card looks
   exactly like an open one, which is what keeps a page of them reading as cards and not controls. */
.sw-card__toggle {
  flex: 1; min-width: 0;
  display: flex; align-items: flex-start; justify-content: space-between; gap: .75rem;
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.sw-card__toggle:hover { background: none; }
.sw-card__toggle .sw-attn__chev { margin-top: .15rem; }

.sw-card__title {
  font-weight: 700;
  color: var(--sw-navy);
  font-size: 1.05rem;
  line-height: 1.2;
}
.sw-card__title svg { vertical-align: -3px; margin-right: .4rem; color: var(--sw-primary); }

.sw-card__subtitle {
  margin-top: .2rem;
  color: var(--sw-muted);
  font-size: .85rem;
}

.sw-card__actions {
  display: flex;
  align-items: center;
  gap: .5rem;
}

.sw-card__body {
  background: var(--sw-surface);
  color: var(--sw-text);
  padding: 1rem;
}

/* Variant: solid (transparent body, used in hero cards) */
.sw-card--solid {
  background: var(--sw-surface);
  border-color: var(--sw-border);
  color: var(--sw-text);
}
.sw-card--solid .sw-card__body {
  background: var(--sw-surface);
  color: var(--sw-text);
}

/* Variant: danger */
.sw-card--danger .sw-card__header {
  background: var(--sw-danger-tint);
}
.sw-card--danger .sw-card__title {
  color: var(--sw-danger);
}


/* ═══════════════════════════════════════════════════════════════
   TILES (dashboard)
   ═══════════════════════════════════════════════════════════════ */

.sw-tile-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .9rem;
}

@media (min-width: 900px) {
  .sw-tile-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.sw-tile {
  display: block;
  text-decoration: none;
  background: var(--sw-surface);
  border: 1px solid var(--sw-border);
  border-radius: var(--sw-radius);
  padding: 1rem;
  min-height: 120px;
  box-shadow: var(--sw-shadow-sm);
  color: var(--sw-text);
  position: relative;
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.sw-tile:hover {
  transform: translateY(-1px);
  box-shadow: var(--sw-shadow);
  color: var(--sw-text);
}
button.sw-tile--clickable {
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  font-size: inherit;
  width: 100%;
}

.sw-tile__title {
  font-weight: 700;
  color: var(--sw-navy);
  font-size: .95rem;
  margin-top: 2.4rem;   /* clears the icon box */
}

.sw-tile__value {
  margin-top: .2rem;
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--sw-navy);
}

.sw-tile__subtitle {
  margin-top: .35rem;
  color: var(--sw-text);
  font-size: .9rem;
  font-weight: 700;
}

.sw-tile__icon {
  position: absolute;
  left: 1rem;
  top: 1rem;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: var(--sw-primary-tint);
  color: var(--sw-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
}


/* ═══════════════════════════════════════════════════════════════
   TABLES
   ═══════════════════════════════════════════════════════════════ */

/* A table wide enough to clip on a phone (the notification log's eight columns) scrolls inside
   this rather than the page scrolling sideways. */
.sw-table-wrap { overflow-x: auto; }

.table.sw-table, .sw-table {
  background: var(--sw-surface-sunken);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: var(--sw-shadow-sm);
}

.table.sw-table {
  border-collapse: separate !important;
  border-spacing: 0;
}
.table.sw-table thead th {
  background: rgba(214,237,255,0.90);
  color: var(--sw-text);
  border-bottom: none;
  font-weight: 900;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: .75rem;
  padding: .75rem .85rem;
}
.table.sw-table tbody td {
  padding: .85rem;
  vertical-align: middle;
  border-top: 1px solid var(--sw-border);
}
.table.sw-table tbody tr:hover td {
  background: var(--sw-surface-sunken);
}

.sw-cell-title {
  font-weight: 950;
  letter-spacing: .01em;
}
.sw-cell-sub {
  color: var(--sw-muted);
  font-weight: 750;
  font-size: .9rem;
  margin-top: .1rem;
}


/* ═══════════════════════════════════════════════════════════════
   BUTTONS (built on top of Bootstrap .btn)
   ═══════════════════════════════════════════════════════════════ */

.btn, button {
  font-family: inherit;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
}
.btn {
  border-radius: 12px !important;
  padding: .6rem 1rem;
  border: 1px solid var(--sw-border);
  background: var(--sw-surface);
  color: var(--sw-text-2);
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
button:hover { background: var(--sw-surface-sunken); color: var(--sw-navy); }

/* Every ordinary button is the soft one (Gideon, 2026-09-25): light blue with dark blue lettering,
   the yellow version on hover. The strong kinds — primary, danger, tint, link, the attendance
   pair — keep their own look. :where() adds no specificity, so a page's own rule for a button
   still wins exactly as it did against the old white .btn. */
.btn:where(:not(.btn-primary, .btn-danger, .btn-tint, .btn-link, .btn-att-fair, .btn-att-poor)) {
  background: var(--sw-primary-tint);
  border-color: var(--sw-primary-tint);
  color: var(--sw-primary-strong);
}
.btn:where(:not(.btn-primary, .btn-danger, .btn-tint, .btn-link, .btn-att-fair, .btn-att-poor)):hover,
.btn:where(:not(.btn-primary, .btn-danger, .btn-tint, .btn-link, .btn-att-fair, .btn-att-poor)):focus-visible {
  background: var(--sw-sunflower-tint);
  border-color: var(--sw-sunflower-tint);
  color: var(--sw-sunflower-ink);
}

.btn-primary {
  background: var(--sw-primary) !important;
  border-color: var(--sw-primary) !important;
  color: #fff !important;
  font-weight: 700;
}
.btn-primary:hover { background: var(--sw-primary-strong) !important; border-color: var(--sw-primary-strong) !important; }

.btn-link {
  color: var(--sw-blue) !important;
  font-weight: 800;
  text-decoration: none;
}
.btn-link:hover { text-decoration: underline; }

.btn-danger {
  background: var(--sw-danger-tint) !important;
  border-color: var(--sw-danger-tint) !important;
  color: var(--sw-danger) !important;
}

/* A faded/tint take on .btn-primary — the same treatment Sessions' active Filter pill uses
   (sw-sched__filter--active), generalised so any button row can share it without borrowing a
   Sessions-specific class name. */
.btn-tint {
  background: var(--sw-primary-tint) !important;
  border-color: var(--sw-primary-tint) !important;
  color: var(--sw-primary) !important;
  font-weight: 700;
}
.btn-tint:hover { background: var(--sw-primary) !important; border-color: var(--sw-primary) !important; color: #fff !important; }


/* ═══════════════════════════════════════════════════════════════
   FORMS
   ═══════════════════════════════════════════════════════════════ */

.sw-form {
  display: flex;
  flex-direction: column;
  gap: .85rem;
}

.sw-form-row {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  align-items: flex-end;
}

.sw-field {
  flex: 1 1 240px;
  min-width: 220px;
}
.sw-field--sm { flex-basis: 160px; min-width: 150px; }
.sw-field--md { flex-basis: 240px; }
.sw-field--lg { flex-basis: 340px; min-width: 280px; }

.sw-field-label {
  font-weight: 950;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: .72rem;
  color: var(--sw-muted);
  margin: 0 0 .25rem .15rem;
}

.sw-actions {
  display: flex;
  gap: .55rem;
  align-items: center;
  flex-wrap: wrap;
}
/* A thin upright rule between a row's buttons and its on/off switch. */
.sw-actions__divider {
  align-self: stretch;
  width: 1px;
  min-height: 1.4rem;
  background: var(--sw-border);
  margin: 0 .15rem;
}

/* The soft small button — now what every ordinary .btn looks like (above), in the .btn-sm size. */
.btn.btn-soft {
  padding: .3rem .65rem;
  font-size: .8rem;
  font-weight: 600;
  border-radius: 8px !important;
  background: var(--sw-primary-tint);
  border-color: var(--sw-primary-tint);
  color: var(--sw-primary-strong);
  display: inline-flex; align-items: center; gap: .3rem;
}
.btn.btn-soft:hover,
.btn.btn-soft:focus-visible {
  background: var(--sw-sunflower-tint);
  border-color: var(--sw-sunflower-tint);
  color: var(--sw-sunflower-ink);
}

@media (max-width: 520px) {
  .sw-field { min-width: 100%; flex-basis: 100%; }
}


/* ═══════════════════════════════════════════════════════════════
   CHIPS
   ═══════════════════════════════════════════════════════════════ */

.sw-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
}

.sw-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .6rem;
  border-radius: var(--sw-radius-pill);
  background: var(--sw-surface-sunken);
  color: var(--sw-text-2);
  border: 1px solid transparent;
  font-weight: 600;
  font-size: .75rem;
}
.sw-chip--primary { background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-chip--warning { background: var(--sw-accent-tint); color: var(--sw-warning); }
.sw-chip--danger  { background: var(--sw-danger-tint);  color: var(--sw-danger); }


/* ═══════════════════════════════════════════════════════════════
   LAYOUT HELPERS
   ═══════════════════════════════════════════════════════════════ */

.sw-page {
  max-width: var(--sw-maxw);
  margin: 0 auto;
  padding: 1rem;
}

.sw-stack {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.sw-toolbar {
  display: flex;
  gap: .6rem;
  align-items: center;
  flex-wrap: wrap;
}

.sw-toolbar__spacer { flex: 1; }

.sw-label {
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--sw-muted-2);
  font-size: .72rem;
}

.sw-error {
  margin-top: .75rem;
  background: var(--sw-danger-tint);
  border: 1px solid transparent;
  color: var(--sw-danger);
  padding: .65rem .75rem;
  border-radius: var(--sw-radius-sm);
  font-weight: 600;
}


/* ═══════════════════════════════════════════════════════════════
   BOTTOM NAVIGATION (mobile)
   ═══════════════════════════════════════════════════════════════ */

.sw-bottomnav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--sw-bottomnav-h);
  display: none;
  align-items: center;
  justify-content: space-around;
  gap: .25rem;
  padding: .3rem .6rem calc(.3rem + env(safe-area-inset-bottom));
  background: var(--sw-surface);
  border-top: 1px solid var(--sw-border);
  z-index: 2500;
}

.sw-bottomnav__item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .2rem;
  text-decoration: none;
  color: var(--sw-muted-2);
  padding: .35rem .2rem;
  border-radius: 12px;
  font-weight: 600;
  letter-spacing: 0;
}

.sw-bottomnav__icon { font-size: 1.25rem; line-height: 1; }
.sw-bottomnav__label { font-size: .7rem; text-transform: none; }

.sw-bottomnav__item--active {
  color: var(--sw-primary);
  background: transparent;
}

@media (max-width: 900px) {
  .sw-bottomnav { display: flex; }
  .sw-page {
    padding-bottom: calc(1rem + var(--sw-bottomnav-h) + env(safe-area-inset-bottom));
  }
}


/* ═══════════════════════════════════════════════════════════════
   DASHBOARD: HERO / WEEKLY OVERVIEW
   ═══════════════════════════════════════════════════════════════ */

.sw-hero-card .sw-card__body { padding: 1.1rem; }

.sw-weekly {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
}

.sw-ring {
  width: 132px;
  height: 132px;
  border-radius: 999px;
  border: 7px solid var(--sw-primary);
  background: var(--sw-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  text-align: center;
}

.sw-ring__value {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--sw-navy);
  line-height: 1;
}

.sw-ring__label {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--sw-muted-2);
}

.sw-weekly__list {
  display: flex;
  flex-direction: column;
  gap: .45rem;
  min-width: 220px;
}

.sw-weekly__item {
  display: flex;
  align-items: center;
  gap: .55rem;
  font-weight: 600;
  color: var(--sw-text);
}

.sw-dot {
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--sw-border);
  border: 1px solid var(--sw-border);
}

.sw-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.sw-banner__main {
  display: flex;
  flex-direction: column;
  gap: .2rem;
}

.sw-banner__title {
  font-weight: 950;
  letter-spacing: .03em;
  color: var(--sw-text);
}

.sw-banner__meta {
  color: var(--sw-text);
  font-weight: 750;
}


/* ═══════════════════════════════════════════════════════════════
   SESSION LIST / ITEMS
   ═══════════════════════════════════════════════════════════════ */

.sw-session-list {
  display: flex;
  flex-direction: column;
  gap: .65rem;
}

.sw-session-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .85rem .9rem;
  border-radius: 18px;
  background: var(--sw-surface-sunken);
  border: 1px solid rgba(0,0,0,0.08);
  text-decoration: none;
  color: var(--sw-text);
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.sw-session-item:hover {
  background: var(--sw-surface-sunken);
  transform: translateY(-1px);
  box-shadow: var(--sw-shadow-sm);
}

.sw-session-item__main { display: flex; flex-direction: column; gap: .2rem; }
.sw-session-item__title { font-weight: 950; letter-spacing: .02em; }
.sw-session-item__meta { color: var(--sw-muted); font-weight: 750; font-size: .92rem; }
.sw-session-item__cta {
  font-weight: 950;
  letter-spacing: .03em;
  text-transform: uppercase;
  font-size: .82rem;
  color: var(--sw-primary);
  white-space: nowrap;
}


/* ═══════════════════════════════════════════════════════════════
   REUSABLE LIST ROW
   ═══════════════════════════════════════════════════════════════ */

.sw-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .85rem .95rem;
  border-radius: 18px;
  background: var(--sw-surface-sunken);
  border: 1px solid rgba(0,0,0,0.08);
  color: var(--sw-text);
  text-decoration: none;
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.sw-row:hover {
  background: var(--sw-surface-sunken);
  transform: translateY(-1px);
  box-shadow: var(--sw-shadow-sm);
}

.sw-row__main { display: flex; flex-direction: column; gap: .2rem; }
.sw-row__title { font-weight: 950; letter-spacing: .02em; }
.sw-row__subtitle { color: var(--sw-muted); font-weight: 750; font-size: .92rem; }
.sw-row__cta {
  font-weight: 950;
  letter-spacing: .03em;
  text-transform: uppercase;
  font-size: .82rem;
  color: var(--sw-primary);
  white-space: nowrap;
}


/* ═══════════════════════════════════════════════════════════════
   ROW ACTION BUTTONS (tables)
   ═══════════════════════════════════════════════════════════════ */

.sw-row-actions {
  display: flex;
  justify-content: flex-end;
  gap: .45rem;
  align-items: center;
  flex-wrap: wrap;
}
.sw-row-actions .btn {
  padding: .35rem .75rem;
  font-size: .82rem;
  font-weight: 950;
  border-radius: 999px;
}

/* ═══════════════════════════════════════════════════════════════
   APPEND THESE to the end of streamline-brand.css
   ═══════════════════════════════════════════════════════════════ */

/* Read-only display field (venue fixed characteristics) */
.sw-readonly {
    padding: .45rem .7rem;
    background: var(--sw-surface-sunken);
    border: 1px solid var(--sw-border);
    border-radius: var(--sw-radius-sm);
    color: var(--sw-text);
    font-weight: 600;
}
/* In solid (dark) cards, invert to light text */
.sw-card--solid .sw-readonly {
    background: var(--sw-surface-sunken);
    border-color: var(--sw-border);
    color: var(--sw-text);
}

/* Success message */
.sw-success {
    color: #6fcf97;
    font-weight: 700;
    margin: .35rem 0;
}

/* Muted text helper */
.sw-muted {
    opacity: 0.5;
}

/* Weather loading indicator badge */
.sw-weather-badge {
    display: inline-block;
    font-size: .7rem;
    font-weight: 700;
    color: var(--sw-blue);
    background: var(--sw-primary-tint);
    padding: .1rem .4rem;
    border-radius: 4px;
    margin-left: .3rem;
    animation: sw-pulse 1.2s ease-in-out infinite;
}

@keyframes sw-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: 0.4;
    }
}

/* ═══════════════════════════════════════════════════════════════
   REPEAT DAY LINEUP
   ═══════════════════════════════════════════════════════════════ */
.sw-lineup-list {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.sw-lineup-item {
  display: flex;
  align-items: center;
  gap: .5rem;
  background: var(--sw-surface-sunken);
  border: 1px solid var(--sw-border);
  border-radius: var(--sw-radius-sm);
  padding: .4rem .8rem;
}
.sw-lineup-item__group {
  font-weight: 900;
  color: var(--sw-primary);
  letter-spacing: .02em;
}
.sw-lineup-item__detail {
  font-size: .85rem;
  color: var(--sw-muted);
  font-weight: 700;
}

/* ═══════════════════════════════════════════════════════════════
   ATTENDANCE ROW STATES
   ═══════════════════════════════════════════════════════════════ */
.sw-attendance-row--absent td {
  opacity: 0.45;
}
.sw-attendance-row--excused td {
  opacity: 0.55;
}
/* Meet entry: selected row */
.sw-row--selected { background: rgba(209, 174, 127, 0.12); }
.sw-row--selected td { font-weight: 600; }

/* ── Collapsible drawer groups ── */
.sw-drawer__group {
    border-bottom: 1px solid var(--sw-border);
    padding-bottom: .15rem;
    margin-bottom: .15rem;
}

.sw-drawer__group-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    font-weight: 900;
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--sw-primary);
    padding: .7rem .75rem .35rem .75rem;
}

    .sw-drawer__group-toggle:hover {
        color: var(--sw-gold);
    }

.sw-drawer__group-chevron {
    font-size: .65rem;
    transition: transform 0.2s ease;
    display: inline-block;
}

.sw-drawer__group-chevron--open {
    transform: rotate(90deg);
}

.sw-drawer__group-items {
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.25s ease;
}

.sw-drawer__group-items--open {
    max-height: 500px;
}

/* ═══════════════════════════════════════════════════════════════
   ICONS · ROLE CONTEXT BAR · BOTTOM SHEET  (Figma library, §7a)
   ═══════════════════════════════════════════════════════════════ */
.sw-icon { display: inline-block; vertical-align: middle; flex-shrink: 0; }

.sw-rolebar {
  display: none;               /* mobile only; the desktop bar has its own controls */
  align-items: center;
  gap: .5rem;
  padding: .55rem 1rem;
  background: var(--sw-surface-sunken);
  border-bottom: 1px solid var(--sw-border);
  font-size: .8rem;
}
.sw-rolebar__glyph { color: var(--sw-muted-2); }
.sw-rolebar__label { color: var(--sw-muted); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; font-size: .68rem; }
.sw-rolebar__role  { color: var(--sw-navy); font-weight: 700; }
.sw-rolebar__switch {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: .15rem;
  border: 0; background: transparent; padding: .2rem .1rem;
  color: var(--sw-primary); font-weight: 700; font-size: .8rem; cursor: pointer;
}
@media (max-width: 900px) { .sw-rolebar { display: flex; } }

.sw-sheet-backdrop { position: fixed; inset: 0; background: rgba(10,25,47,0.55); z-index: 3000; }
.sw-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 3100;
  background: var(--sw-surface);
  border-radius: 20px 20px 0 0;
  padding: .6rem 1rem calc(1rem + env(safe-area-inset-bottom));
  box-shadow: 0 -12px 40px rgba(15,23,42,0.18);
  max-width: 520px; margin: 0 auto;
  max-height: 92dvh; overflow-y: auto; overscroll-behavior: contain; /* a tall sheet scrolls inside itself, never off the top */
}
.sw-sheet__handle { width: 40px; height: 4px; border-radius: 2px; background: var(--sw-border); margin: 0 auto .9rem; }
.sw-sheet__head   { display: flex; align-items: center; justify-content: space-between; margin-bottom: .75rem; }
.sw-sheet__title  { font-weight: 800; font-size: 1.15rem; color: var(--sw-navy); }
.sw-sheet__close  {
  width: 36px; height: 36px; border-radius: 999px; border: 0;
  background: var(--sw-surface-sunken); color: var(--sw-text-2);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 0;
}
.sw-sheet__options { display: flex; flex-direction: column; gap: .6rem; }
.sw-sheet__option {
  display: flex; align-items: center; gap: .8rem; width: 100%; text-align: left;
  padding: .8rem .9rem; border-radius: 14px;
  border: 1px solid var(--sw-border); background: var(--sw-bg); color: var(--sw-text); cursor: pointer;
}
.sw-sheet__option--selected { background: var(--sw-primary-tint); border-color: var(--sw-primary); }
.sw-sheet__option-icon  { width: 36px; height: 36px; border-radius: 10px; background: var(--sw-surface); border: 1px solid var(--sw-border); display: inline-flex; align-items: center; justify-content: center; color: var(--sw-navy); flex-shrink: 0; }
.sw-sheet__option--selected .sw-sheet__option-icon { color: var(--sw-primary); border-color: transparent; }
.sw-sheet__option-text  { display: flex; flex-direction: column; gap: .1rem; flex: 1; min-width: 0; }
.sw-sheet__option-label { font-weight: 700; font-size: .95rem; color: var(--sw-navy); }
.sw-sheet__option--selected .sw-sheet__option-label { color: var(--sw-primary); }
.sw-sheet__option-desc  { font-size: .8rem; color: var(--sw-muted); }
.sw-sheet__option-check { color: var(--sw-primary); }

/* bottom nav with real icons */
.sw-bottomnav__icon { line-height: 0; }
.sw-bottomnav__icon .sw-icon { width: 22px; height: 22px; }

/* ═══════════════════════════════════════════════════════════════
   MEMBER HOME  (docs/Design/02-home-training/dashboard.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-streak {
  display: flex; align-items: center; gap: .9rem;
  padding: .9rem 1rem;
  background: var(--sw-accent-tint);
  border: 1px solid var(--sw-accent);
  border-radius: var(--sw-radius);
}
.sw-streak__icon {
  width: 44px; height: 44px; border-radius: 999px; flex-shrink: 0;
  background: var(--sw-accent); color: var(--sw-navy);
  display: inline-flex; align-items: center; justify-content: center;
}
.sw-streak__title { font-weight: 700; font-size: 1.05rem; color: var(--sw-navy); }
.sw-streak__sub   { font-size: .85rem; color: var(--sw-muted); margin-top: .1rem; }

.sw-home-att { padding: 1rem; }
.sw-home-att__body { display: flex; align-items: center; gap: 1rem; }
.sw-ring--sm { width: 88px; height: 88px; flex-shrink: 0; }
.sw-ring--sm .sw-ring__value { font-size: 1.35rem; }
.sw-home-att__text { min-width: 0; }
.sw-home-att__headline { font-weight: 800; font-size: 1.15rem; color: var(--sw-navy); margin-top: .15rem; }
.sw-home-att__sub { font-size: .85rem; color: var(--sw-muted); margin-top: .2rem; }
.sw-home-att__goals {
  display: flex; align-items: center; gap: .6rem;
  margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--sw-border);
  color: var(--sw-navy); text-decoration: none; font-weight: 700;
}
.sw-home-att__goals .sw-chip { text-transform: uppercase; letter-spacing: .05em; font-size: .68rem; }
.sw-home-att__goals-text { flex: 1; }
.sw-home-att__goals .sw-icon { color: var(--sw-primary); }

.sw-home__section { margin: .25rem 0 -.25rem; font-size: .8rem; color: var(--sw-navy); }
.sw-qa {
  display: flex; flex-direction: column; gap: .2rem;
  padding: 1rem; min-height: 128px;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); text-decoration: none; color: var(--sw-text);
}
.sw-qa__icon {
  width: 40px; height: 40px; border-radius: 12px; margin-bottom: .6rem;
  background: var(--sw-primary-tint); color: var(--sw-primary);
  display: inline-flex; align-items: center; justify-content: center;
}
.sw-qa__icon--accent { background: var(--sw-accent-tint); color: var(--sw-warning); }
.sw-qa__icon--sunken { background: var(--sw-surface-sunken); color: var(--sw-text-2); }
.sw-qa__title { font-weight: 700; color: var(--sw-navy); }
.sw-qa__sub   { font-size: .82rem; color: var(--sw-muted); }

/* loading skeletons (design: dashboard-loading) */
.sw-skeleton {
  border-radius: var(--sw-radius);
  background: linear-gradient(90deg, var(--sw-surface-sunken) 25%, var(--sw-border) 50%, var(--sw-surface-sunken) 75%);
  background-size: 200% 100%;
  animation: sw-shimmer 1.4s infinite;
}
.sw-skeleton--label { height: 14px; width: 40%; border-radius: 6px; }
@keyframes sw-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ═══════════════════════════════════════════════════════════════
   COACH HOME — TODAY'S SESSIONS  (docs/Design/11-head-coach/head-coach-dashboard.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem; }
.sw-stat {
  padding: .9rem 1rem;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm);
}
.sw-stat__value { font-size: 1.5rem; font-weight: 800; color: var(--sw-navy); margin-top: .2rem; letter-spacing: -0.01em; }
.sw-stat__unit  { font-size: 1.05rem; font-weight: 700; }

.sw-section-head { display: flex; align-items: baseline; justify-content: space-between; }
.sw-section-head__link { color: var(--sw-primary); font-weight: 700; font-size: .85rem; text-decoration: none; }

/* A period switch in a section head — the attendance wheels' 4 weeks / 3 months / 12 months. It
   sits where the section's link would, so it reads as "about this section" rather than as a
   control over the whole page, and it stays a row of buttons rather than a <select> because there
   are only ever three and the current one should be readable without opening anything. */
.sw-periods { display: flex; gap: .15rem; background: var(--sw-surface-sunken); border-radius: 999px; padding: .15rem; }
.sw-period {
  border: 0; background: none; cursor: pointer;
  padding: .25rem .6rem; border-radius: 999px;
  font: inherit; font-size: .75rem; font-weight: 700; color: var(--sw-muted);
  white-space: nowrap;
}
.sw-period:hover:not(:disabled) { color: var(--sw-text); }
.sw-period:disabled { cursor: default; opacity: .6; }
.sw-period--on { background: var(--sw-surface); color: var(--sw-primary); box-shadow: var(--sw-shadow-sm); }
@media (max-width: 26rem) { .sw-period { padding: .25rem .45rem; font-size: .7rem; } }

/* A small unread-style count, e.g. the Import queue link (Meets page) — how many items are
   waiting, not what they are; the link itself still names the destination. */
.sw-badge-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; padding: 0 4px; margin-left: 4px;
  border-radius: 999px; background: var(--sw-danger, #dc2626); color: #fff;
  font-size: .68rem; font-weight: 800; line-height: 1; vertical-align: middle;
}
/* A section head with more than one thing on its right. */
.sw-section-head__actions { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
/* A retired standards set still reads, just quietly — last season's times stay legible on the
   meets that used them. */
.sw-attn--retired { opacity: .65; }
/* Times line up in a column so a set can be scanned down rather than read across. */
.sw-std__time { font-variant-numeric: tabular-nums; min-width: 5.5rem; text-align: right; flex-shrink: 0; }

.sw-sess {
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); padding: 1rem;
}
.sw-sess--live { background: #f0fdf4; border-color: var(--sw-success); }
.sw-sess__head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; }
.sw-sess__time { display: inline-flex; align-items: center; gap: .35rem; color: var(--sw-primary); font-weight: 700; font-size: .95rem; }
.sw-sess__chips { display: inline-flex; gap: .4rem; }
.sw-sess__title { font-weight: 700; font-size: 1.1rem; color: var(--sw-navy); margin-top: .5rem; }
.sw-sess__venue { display: inline-flex; align-items: center; gap: .3rem; color: var(--sw-muted); font-size: .9rem; margin-top: .2rem; }
.sw-sess__foot  { display: flex; align-items: center; justify-content: space-between; margin-top: .8rem; padding-top: .8rem; border-top: 1px solid var(--sw-border); }
.sw-sess__athletes { display: inline-flex; align-items: center; gap: .35rem; color: var(--sw-muted); font-weight: 600; font-size: .9rem; }
.sw-sess__cta { display: inline-flex; align-items: center; gap: .1rem; color: var(--sw-primary); font-weight: 700; text-decoration: none; font-size: .95rem; }
.sw-sess__cta--live { color: var(--sw-success); }

.sw-empty {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: .35rem;
  padding: 1.6rem 1rem;
  background: var(--sw-surface); border: 1px dashed var(--sw-border); border-radius: var(--sw-radius);
}
.sw-empty__icon { width: 44px; height: 44px; border-radius: 12px; background: var(--sw-surface-sunken); color: var(--sw-text-2); display: inline-flex; align-items: center; justify-content: center; margin-bottom: .3rem; }
.sw-empty__title { font-weight: 700; color: var(--sw-navy); }
.sw-empty__sub   { color: var(--sw-muted); font-size: .9rem; max-width: 34ch; }
.sw-empty .btn   { margin-top: .6rem; }

/* ═══════════════════════════════════════════════════════════════
   COACH MANAGEMENT · PERMISSIONS MATRIX · MY SQUADS  (§7a)
   ═══════════════════════════════════════════════════════════════ */
.btn-sm { padding: .3rem .65rem; font-size: .8rem; display: inline-flex; align-items: center; gap: .3rem; border-radius: 8px !important; }
.sw-muted-text { color: var(--sw-muted); font-size: .9rem; margin: 0; }
.sw-success-note { color: var(--sw-success); font-weight: 600; font-size: .9rem; }
.sw-chip--navy { background: var(--sw-navy); color: #fff; }

.sw-switch { position: relative; display: inline-block; width: 40px; height: 24px; flex-shrink: 0; }
.sw-switch input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.sw-switch__knob { position: absolute; inset: 0; border-radius: 999px; background: var(--sw-border); transition: background .15s ease; }
.sw-switch__knob::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 999px; background: #fff; box-shadow: 0 1px 2px rgba(15,23,42,.25); transition: transform .15s ease; }
.sw-switch--on .sw-switch__knob { background: var(--sw-primary); }
.sw-switch--on .sw-switch__knob::after { transform: translateX(16px); }
.sw-switch input:disabled + .sw-switch__knob { opacity: .5; }
.sw-switchrow { display: flex; align-items: center; justify-content: space-between; gap: .8rem; padding: .55rem 0; border-bottom: 1px solid var(--sw-border); cursor: pointer; }
.sw-switchrow:last-child { border-bottom: 0; }
.sw-switchrow__label { color: var(--sw-text); font-weight: 600; font-size: .95rem; }
.sw-switches { display: flex; flex-direction: column; }

.sw-coach { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm); padding: .9rem 1rem; }
.sw-coach--open { border-color: var(--sw-primary); }
.sw-coach__head { display: flex; align-items: center; gap: .8rem; width: 100%; background: transparent; border: 0; padding: 0; text-align: left; cursor: pointer; }
.sw-coach__avatar { width: 40px; height: 40px; border-radius: 999px; background: var(--sw-primary-tint); color: var(--sw-primary); font-weight: 700; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sw-coach__avatar--sm { width: 32px; height: 32px; font-size: .8rem; }
.sw-coach__who { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.sw-coach__name { font-weight: 700; color: var(--sw-navy); }
.sw-coach__email { font-size: .82rem; color: var(--sw-muted); overflow: hidden; text-overflow: ellipsis; }
.sw-coach__groups { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; margin-top: .7rem; }
.sw-coach__none { color: var(--sw-muted-2); font-size: .85rem; }
.sw-coach__body { margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--sw-border); }
.sw-coach__note { color: var(--sw-muted); font-size: .8rem; margin: .8rem 0 0; }
.sw-checks { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .4rem; }
.sw-check { display: inline-flex; align-items: center; gap: .4rem; padding: .35rem .7rem; border-radius: 999px; border: 1px solid var(--sw-border); background: var(--sw-surface); font-size: .85rem; font-weight: 600; color: var(--sw-text-2); cursor: pointer; }
.sw-check--on { background: var(--sw-primary-tint); border-color: var(--sw-primary); color: var(--sw-primary); }
.sw-check input { margin: 0; accent-color: var(--sw-primary); }

.sw-matrix { padding: .25rem; overflow-x: auto; }
.sw-matrix table { width: 100%; border-collapse: collapse; }
.sw-matrix th { text-align: left; font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--sw-muted-2); padding: .7rem .8rem; background: var(--sw-surface-sunken); }
.sw-matrix th:not(:first-child), .sw-matrix td:not(:first-child) { text-align: center; }
.sw-matrix td { padding: .6rem .8rem; border-top: 1px solid var(--sw-border); font-weight: 600; color: var(--sw-text); }

.sw-squad { padding: 1rem; }
.sw-squad__head { display: flex; gap: .4rem; }
.sw-squad__title { font-weight: 700; font-size: 1.05rem; color: var(--sw-navy); margin-top: .5rem; }
.sw-squad__link { display: inline-flex; align-items: center; gap: .1rem; margin-top: .4rem; color: var(--sw-primary); font-weight: 700; font-size: .9rem; text-decoration: none; }
.sw-search { display: flex; align-items: center; gap: .5rem; padding: .55rem .8rem; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 12px; color: var(--sw-muted-2); }
.sw-search__input { flex: 1; border: 0; outline: 0; background: transparent; font: inherit; color: var(--sw-text); }
.sw-agroup { padding: .25rem .5rem; }
.sw-agroup__head { display: flex; align-items: center; gap: .6rem; width: 100%; background: transparent; border: 0; padding: .6rem .5rem; cursor: pointer; text-align: left; }
.sw-agroup__name { font-weight: 700; color: var(--sw-navy); flex: 1; }
.sw-agroup__chev { color: var(--sw-muted-2); transition: transform .15s ease; display: inline-flex; }
.sw-agroup__chev--open { transform: rotate(180deg); }
.sw-agroup__list { display: flex; flex-direction: column; gap: .4rem; padding: 0 .5rem .6rem; }
.sw-arow { display: flex; align-items: center; gap: .7rem; padding: .6rem .7rem; border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-bg); text-decoration: none; color: var(--sw-text); }
.sw-arow__name { flex: 1; font-weight: 600; }
.sw-arow__chev { color: var(--sw-muted-2); }


/* ═══════════════════════════════════════════════════════════════
   TRAINING SCHEDULE · SESSION DETAILS · TAKE REGISTER
   (docs/Design/02-home-training/training-schedule-list.png, training-session-detail.png,
    11-head-coach/head-take-register.png, 10-assistant-coach/attendance-submitted.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-titlebar { display: flex; align-items: center; gap: .7rem; margin-bottom: 1rem; }
.sw-titlebar h1 { margin: 0; }
.sw-back {
  width: 36px; height: 36px; border-radius: 999px; flex-shrink: 0;
  background: var(--sw-surface-sunken); color: var(--sw-navy);
  display: inline-flex; align-items: center; justify-content: center; text-decoration: none;
}

a.btn, a.btn:hover { text-decoration: none; }   /* a link dressed as a button keeps no underline */
.sw-sched__month { font-weight: 800; font-size: 1.2rem; color: var(--sw-navy); letter-spacing: -0.01em; }
.sw-sched__tools { display: inline-flex; gap: .5rem; }
.sw-sched__filter--active { border-color: var(--sw-primary); color: var(--sw-primary); background: var(--sw-primary-tint); }
.sw-sched__card {
  position: relative; display: block; padding: .9rem 2.4rem .9rem 1rem;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); text-decoration: none; color: var(--sw-text);
}
.sw-sched__card--today { border-color: var(--sw-primary); box-shadow: inset 0 0 0 1px var(--sw-primary), var(--sw-shadow-sm); }
.sw-sched__card--past { opacity: .75; }
.sw-sched__chips { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; }
.sw-sched__chips .sw-chip { text-transform: uppercase; letter-spacing: .05em; font-size: .68rem; }
.sw-sched__chips .sw-chip--group { text-transform: none; letter-spacing: 0; font-size: .75rem; }
.sw-sched__date { font-size: .82rem; font-weight: 600; color: var(--sw-muted); }
.sw-sched__title { font-weight: 700; font-size: 1.02rem; color: var(--sw-navy); margin-top: .55rem; }
.sw-sched__meta { font-size: .85rem; color: var(--sw-muted); margin-top: .2rem; }
.sw-sched__chev { position: absolute; right: .8rem; top: 50%; transform: translateY(-50%); color: var(--sw-muted-2); display: inline-flex; }

.sw-choices { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .45rem; }
.sw-choice {
  display: inline-flex; align-items: center; gap: .35rem; padding: .45rem .85rem; border-radius: 999px;
  border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2);
  font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer;
}
.sw-choice--on, .sw-choice--on:hover { background: var(--sw-primary-tint); border-color: var(--sw-primary); color: var(--sw-primary); }
.sw-choice--sm { padding: .25rem .6rem; font-size: .78rem; }
.sw-choice:disabled { cursor: default; opacity: .6; }
.sw-sheet__section { margin-bottom: 1rem; }
.sw-sheet__cta { width: 100%; margin-top: .25rem; }

.sw-hero { background: var(--sw-navy); color: #fff; border-radius: var(--sw-radius); padding: 1rem 1.1rem; }
.sw-hero__kicker { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; }
.sw-hero .sw-chip { text-transform: uppercase; letter-spacing: .05em; font-size: .68rem; }
.sw-chip--hero { background: var(--sw-primary); color: #fff; }
.sw-chip--hero-muted { background: rgba(255,255,255,.14); color: #e2e8f0; }
.sw-hero__date { font-size: .82rem; color: #cbd5e1; }
.sw-hero__title { font-weight: 800; font-size: 1.3rem; margin-top: .6rem; letter-spacing: -0.01em; }
.sw-hero__meta { display: flex; flex-wrap: wrap; gap: .4rem 1rem; margin-top: .5rem; font-size: .9rem; color: #cbd5e1; }
.sw-hero__meta span { display: inline-flex; align-items: center; gap: .35rem; }

.sw-workout { padding: 1rem; }
.sw-workout__head { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; }
.sw-workout__name { font-weight: 700; font-size: 1.05rem; color: var(--sw-navy); }
.sw-workout__sum { font-size: .82rem; color: var(--sw-muted); white-space: nowrap; }
.sw-workout__list { list-style: none; margin: .6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.sw-workout__item { display: flex; align-items: center; gap: .6rem; }
.sw-workout__n {
  width: 22px; height: 22px; border-radius: 999px; flex-shrink: 0;
  background: var(--sw-primary-tint); color: var(--sw-primary); font-size: .7rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.sw-workout__drill { flex: 1; font-weight: 600; }
.sw-workout__reps { font-weight: 700; color: var(--sw-text-2); }
.sw-workout__rest { font-size: .8rem; color: var(--sw-muted); }

.sw-reg__count { font-weight: 700; color: var(--sw-text-2); }
.sw-linkbtn, .sw-linkbtn:hover { background: transparent; border: 0; padding: 0; cursor: pointer; font: inherit; color: var(--sw-primary); font-weight: 700; }
.sw-note { padding: .7rem .9rem; border-radius: 12px; background: var(--sw-accent-tint); color: var(--sw-warning); font-size: .88rem; font-weight: 600; }
.sw-reg { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 14px; box-shadow: var(--sw-shadow-sm); padding: .7rem .8rem; }
.sw-reg__row { display: flex; align-items: center; gap: .7rem; }
.sw-reg__who { flex: 1; min-width: 0; }
.sw-reg__name { font-weight: 700; color: var(--sw-navy); display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.sw-reg--absent .sw-reg__name { color: var(--sw-text-2); }
.sw-reg__checkin { font-size: .78rem; color: var(--sw-muted); margin-top: .1rem; display: inline-flex; align-items: center; gap: .3rem; }
.sw-reg__mark { display: inline-flex; gap: .4rem; align-items: center; }
.sw-mark {
  width: 40px; height: 34px; border-radius: 10px; padding: 0; cursor: pointer;
  border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2);
  display: inline-flex; align-items: center; justify-content: center;
}
.sw-mark:disabled { cursor: default; opacity: .6; }
.sw-mark--yes.sw-mark--on, .sw-mark--yes.sw-mark--on:hover { background: var(--sw-success-tint); border-color: var(--sw-success); color: var(--sw-success); }
.sw-mark--no.sw-mark--on, .sw-mark--no.sw-mark--on:hover { background: var(--sw-danger-tint); border-color: var(--sw-danger); color: var(--sw-danger); }
.sw-reg__detail { display: flex; align-items: center; gap: .5rem; margin-top: .6rem; padding-top: .6rem; border-top: 1px solid var(--sw-border); }
.sw-reg__label { color: var(--sw-muted); font-size: .9rem; flex: 1; }
.sw-reg__reason { max-width: 60%; }
.sw-reg__rpe { display: inline-flex; align-items: center; gap: .35rem; font-size: .78rem; color: var(--sw-muted); font-weight: 600; margin: 0; }
.sw-reg__note { flex: 1; min-width: 0; }
.sw-reg__other { margin-top: .5rem; width: 100%; }
.sw-reg__submit { width: 100%; padding: .85rem 1rem; font-size: 1.05rem; }
/* The register, thin (Gideon, 2026-09-30): the away list's row height, a small gap, marks a
   thumb can still hit — so a squad of twenty is one screen rather than three. */
.sw-reg-list { display: flex; flex-direction: column; gap: .3rem; }
.sw-reg-list .sw-reg { padding: .3rem .5rem .3rem .6rem; border-radius: 10px; box-shadow: none; }
.sw-reg-list .sw-reg__row { gap: .55rem; }
.sw-reg-list .sw-reg__name { font-size: .9rem; }
.sw-reg-list .sw-coach__avatar--sm { width: 26px; height: 26px; font-size: .72rem; }
.sw-reg-list .sw-mark { width: 40px; height: 30px; border-radius: 8px; }
.sw-reg-list .sw-reg--present { border-left: 4px solid var(--sw-success); }
.sw-reg-list .sw-reg--absent { border-left: 4px solid var(--sw-danger); }
.sw-reg-list .sw-reg--late { border-left: 4px solid var(--sw-accent); }
.sw-late { display: inline-flex; align-items: center; border: 1px solid var(--sw-border); border-radius: 8px; overflow: hidden; height: 30px; flex-shrink: 0; }
.sw-late__label { padding: 0 .45rem; font-size: .75rem; font-weight: 700; color: var(--sw-muted); }
.sw-late__q { border: 0; border-left: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2); width: 28px; height: 100%; font-size: .85rem; font-weight: 700; cursor: pointer; padding: 0; }
.sw-late__q:hover:not(:disabled) { background: var(--sw-surface-sunken); }
.sw-late__q:disabled { cursor: default; opacity: .6; }
.sw-late--on { border-color: var(--sw-accent); }
.sw-late--on .sw-late__label { color: var(--sw-warning); }
.sw-late__q--on { background: var(--sw-accent-tint); color: var(--sw-warning); }
.sw-mark--more { font-weight: 800; letter-spacing: .05em; color: var(--sw-muted-2); }
.sw-mark--filled { color: var(--sw-primary); border-color: var(--sw-primary); background: var(--sw-primary-tint); }
.sw-mark--open { color: var(--sw-navy); border-color: var(--sw-navy); }
.sw-reg-list .sw-reg__detail { margin-top: .35rem; padding-top: .35rem; }
.sw-reg__extras-link { display: inline-flex; align-items: center; gap: .3rem; align-self: center; font-size: .9rem; }
.sw-extras { display: flex; flex-direction: column; gap: .4rem; margin-top: .7rem; }
.sw-extras__row {
  display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left; padding: .5rem .6rem;
  border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-bg); cursor: pointer; font: inherit; color: var(--sw-text);
}
.sw-extras__row .sw-icon { color: var(--sw-primary); margin-left: auto; }

.sw-toast {
  position: fixed; left: 1rem; right: 1rem; bottom: calc(1rem + env(safe-area-inset-bottom)); z-index: 2500;
  margin: 0 auto; max-width: 480px;
  display: flex; align-items: center; gap: .6rem; padding: .85rem 1rem; border-radius: 12px;
  background: var(--sw-navy); color: #fff; font-weight: 600;
  box-shadow: 0 12px 30px rgba(15,23,42,.25); animation: sw-toast-in .2s ease-out;
}
@media (max-width: 900px) {
  .sw-toast { bottom: calc(1rem + var(--sw-bottomnav-h) + env(safe-area-inset-bottom)); }
}
.sw-toast__dot { width: 10px; height: 10px; border-radius: 999px; background: var(--sw-success); flex-shrink: 0; }
.sw-toast--error .sw-toast__dot { background: var(--sw-danger); }
.sw-toast--info .sw-toast__dot { background: var(--sw-primary); }
/* Movement only: a background tab pauses animations, and a toast paused at opacity 0 is a toast nobody sees. */
@keyframes sw-toast-in { from { transform: translateY(8px); } to { transform: none; } }


/* ═══════════════════════════════════════════════════════════════
   SQUADS · ROSTER DIRECTORY · SWIMMER
   (docs/Design/11-head-coach/squad-dashboard.png, athlete-directory.png, athlete-detail.png,
    athlete-group-assignment.png, 05-club-billing/group-detail.png)
   ═══════════════════════════════════════════════════════════════ */
a.sw-choice { text-decoration: none; }
.sw-stat-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .6rem; }
.sw-stat--center { text-align: center; padding: .9rem .4rem; }
.sw-stat--center .sw-stat__value { font-size: 1.55rem; margin: 0 0 .2rem; }
.sw-stat--center .sw-label { font-size: .62rem; }
.sw-stat--raised { border-color: var(--sw-primary); box-shadow: 0 6px 18px rgba(3,105,161,.14); }
.sw-note--link { display: block; text-decoration: none; }
.sw-actions--end { justify-content: flex-end; }

.sw-squad-card {
  position: relative; display: block; padding: 1rem 2.4rem 1rem 1rem;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); text-decoration: none; color: var(--sw-text);
}
.sw-squad-card__chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.sw-squad-card__title { font-weight: 700; font-size: 1.1rem; color: var(--sw-navy); margin-top: .55rem; }
.sw-squad-card__chev { position: absolute; right: .8rem; top: 1.1rem; color: var(--sw-muted-2); display: inline-flex; }
.sw-bar-row { display: flex; align-items: center; gap: .6rem; margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--sw-border); font-size: .85rem; font-weight: 600; color: var(--sw-text-2); }
.sw-bar { flex: 1; height: 6px; border-radius: 999px; background: var(--sw-surface-sunken); overflow: hidden; }
.sw-bar__fill { display: block; height: 100%; border-radius: 999px; background: var(--sw-primary); }
.sw-bar-row__pct { color: var(--sw-primary); font-weight: 700; min-width: 3.2ch; text-align: right; }

.sw-dir { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm); overflow: hidden; }
.sw-dir__head, .sw-dir__head:hover { display: flex; align-items: center; gap: .6rem; width: 100%; background: transparent; border: 0; padding: .85rem 1rem; cursor: pointer; text-align: left; font: inherit; color: var(--sw-text); }
.sw-dir__name { font-weight: 700; color: var(--sw-navy); }
.sw-dir__chev { margin-left: auto; color: var(--sw-muted-2); display: inline-flex; transition: transform .15s ease; }
.sw-dir__chev--open { transform: rotate(180deg); }
.sw-dir__list { display: flex; flex-direction: column; gap: .45rem; padding: 0 .6rem .7rem; }
.sw-dir__list .sw-muted-text { padding: .2rem .4rem .4rem; }

.sw-ath { display: flex; align-items: center; gap: .7rem; padding: .6rem .7rem; border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-bg); text-decoration: none; color: var(--sw-text); cursor: pointer; margin: 0; }
.sw-ath__who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-ath__name { font-weight: 700; color: var(--sw-navy); }
.sw-ath__sub { font-size: .8rem; color: var(--sw-muted); font-weight: 500; }
.sw-ath__chev { color: var(--sw-muted-2); display: inline-flex; }
.sw-ath input[type=checkbox] { width: 18px; height: 18px; accent-color: var(--sw-primary); margin: 0; flex-shrink: 0; }
.sw-rate { font-size: .75rem; font-weight: 700; padding: .25rem .5rem; border-radius: 999px; flex-shrink: 0; }
.sw-rate--good { background: var(--sw-success-tint); color: var(--sw-success); }
.sw-rate--ok   { background: var(--sw-accent-tint); color: var(--sw-warning); }
.sw-rate--low  { background: var(--sw-danger-tint); color: var(--sw-danger); }
.sw-rate--none { background: var(--sw-surface-sunken); color: var(--sw-muted-2); }

/* The roster row's two rating chips: the Streamline level, and the meet the swimmer has qualified
   for. Both sit between the name and the attendance rate, so a coach scanning down the list reads
   name → how fast → what they can enter → how often they turn up.

   The level reuses .sw-tier and so is coloured by level, the same badge as on the profile — a "7B"
   must not mean one thing on one screen and another elsewhere.

   The qualification used to be deliberately quiet — a flat grey, on the argument that it is a long
   string, it repeats down a squad, and shouting it would bury the level beside it. That argument
   was right while the chip was only a name. It now carries the rung's colour (.sw-standard--N,
   which wins on source order below), and the same reasoning points the other way: the colour is
   what lets a coach scan the column without reading it, so the repetition down a squad is the
   feature rather than the cost. The grey here stays as the fallback for a chip with no rank. */
/* A fixed-width slot, rendered on every row whether or not it has anything in it. Without it the
   level chip slides left whenever a swimmer has a qualification beside it, and the column a coach
   scans down becomes a zigzag — which defeats the entire point of putting it here. */
.sw-ath__rating { display: flex; align-items: center; gap: .4rem; flex-shrink: 0; width: 11.5rem; }
.sw-ath__tier { flex-shrink: 0; width: 2.6rem; }
.sw-ath__qual {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: center;
  font-size: .72rem; font-weight: 700; padding: .2rem .45rem; border-radius: 999px;
  background: var(--sw-surface-sunken); color: var(--sw-muted);
}
/* Narrow screens keep the level and drop the qualification: the level is the scannable one, and
   two chips plus a rate crush the name on a phone. The full picture is one tap away. */
@media (max-width: 30rem) {
  .sw-ath__rating { width: auto; }
  .sw-ath__qual { display: none; }
}
.sw-actionbar {
  position: sticky; bottom: calc(var(--sw-bottomnav-h) + .6rem); z-index: 5;
  display: flex; gap: .5rem; align-items: center; padding: .6rem;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 14px; box-shadow: var(--sw-shadow);
}
@media (min-width: 901px) { .sw-actionbar { bottom: .6rem; } }

.sw-avatar--lg { width: 64px; height: 64px; font-size: 1.3rem; }
.sw-profile { display: flex; align-items: center; gap: 1rem; padding: 1rem; }
.sw-profile__who { flex: 1; min-width: 0; }
.sw-profile__name { font-weight: 800; font-size: 1.15rem; color: var(--sw-navy); }
.sw-profile__chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .4rem; }
.sw-profile__chips a.sw-chip { text-decoration: none; }
.sw-profile__sub { font-size: .82rem; color: var(--sw-muted); margin-top: .4rem; }

.sw-tabs { display: flex; border-bottom: 1px solid var(--sw-border); }
.sw-tab, .sw-tab:hover { flex: 1; background: transparent; border: 0; border-bottom: 2px solid transparent; padding: .6rem 0; font: inherit; font-weight: 600; color: var(--sw-muted); cursor: pointer; margin-bottom: -1px; }
.sw-tab:hover { color: var(--sw-navy); }
.sw-tab--on, .sw-tab--on:hover { color: var(--sw-primary); border-bottom-color: var(--sw-primary); }

.sw-ring--pct { --p: 0; width: 80px; height: 80px; border: 0; position: relative; flex-shrink: 0;
  background: conic-gradient(var(--sw-primary) calc(var(--p) * 1%), var(--sw-primary-tint) 0); }
.sw-ring--pct::before { content: ""; position: absolute; inset: 7px; border-radius: 999px; background: var(--sw-surface); }
.sw-ring--pct .sw-ring__value { position: relative; font-size: 1.15rem; color: var(--sw-primary); }

.sw-hist { display: flex; align-items: center; gap: .7rem; padding: .7rem .9rem; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 12px; box-shadow: var(--sw-shadow-sm); text-decoration: none; color: var(--sw-text); }
.sw-hist__who { flex: 1; min-width: 0; }
.sw-hist__title { font-weight: 700; color: var(--sw-navy); }
.sw-hist__sub, .sw-hist__reason { font-size: .8rem; color: var(--sw-muted); }
.sw-hist .sw-chip { text-transform: uppercase; letter-spacing: .05em; font-size: .66rem; flex-shrink: 0; }

.sw-pb { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: .15rem .8rem; padding: .7rem 1rem; border-top: 1px solid var(--sw-border); }
.sw-pb:first-child { border-top: 0; }
.sw-pb__event { font-weight: 700; color: var(--sw-navy); }
.sw-pb__time { font-weight: 800; color: var(--sw-primary); text-align: right; font-variant-numeric: tabular-nums; }
.sw-pb__meta { grid-column: 1 / -1; font-size: .78rem; color: var(--sw-muted); }
.sw-sheet__cols { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }


/* ═══════════════════════════════════════════════════════════════
   MEETS  (docs/Design/12-club-admin/gala-management.png, gala-detail.png, gala-program.png,
           03-meet-entries/event-entries.png, entry-checkout.png, meets-empty.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-meets__create { align-self: stretch; }
/* The schedule's own button is a quiet afterthought to the list, not a call to action. */
.sw-meets__add { align-self: flex-start; }
.sw-meet {
  display: block; padding: 1rem;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); text-decoration: none; color: var(--sw-text);
}
.sw-meet--past { opacity: .75; }
.sw-meet__head { display: flex; align-items: flex-start; justify-content: space-between; gap: .6rem; }
.sw-meet__name { font-weight: 700; font-size: 1.1rem; color: var(--sw-navy); }
.sw-meet__head .sw-chip { text-transform: uppercase; letter-spacing: .05em; font-size: .66rem; flex-shrink: 0; margin-top: .15rem; }
.sw-meet__row { display: flex; align-items: center; gap: .45rem; margin-top: .45rem; font-size: .9rem; color: var(--sw-text-2); }
.sw-meet__row .sw-icon { color: var(--sw-muted-2); flex-shrink: 0; }
.sw-meet__row--danger, .sw-meet__row--danger .sw-icon { color: var(--sw-danger); font-weight: 600; }
.sw-meet__foot { display: flex; align-items: center; justify-content: space-between; margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--sw-border); }
.sw-meet__foot-text { font-weight: 700; color: var(--sw-primary); font-size: .92rem; }

/* The season schedule. A gala with no programme yet is a date, not a meet, so it gets the planning
   calendar's thin row (.sw-plancal__row) rather than a card — a card promising entries would be a
   lie until the federation's file lands. */
/* The age group beside an event's name on the entry screen. Quiet, because the distance and
   stroke are still the headline — but present, because a programme of single-age events has six
   rows called "200 m Individual Medley" and nothing else tells them apart. */
.sw-entry__age { font-size: .78rem; font-weight: 600; color: var(--sw-muted); margin-left: .35rem; }

.sw-schedrow__date { min-width: 4.6rem; flex-shrink: 0; }
.sw-schedrow__venue { flex: 1; min-width: 0; font-size: .8rem; color: var(--sw-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-schedrow .sw-chip { flex-shrink: 0; }
.sw-sheet__cols--3 { grid-template-columns: 1fr 1fr 1fr; }

.sw-countdown {
  display: flex; align-items: center; justify-content: space-between;
  padding: .8rem 1rem; border-radius: 12px; background: var(--sw-primary-tint); color: var(--sw-primary); font-weight: 600;
}
.sw-countdown strong { font-size: 1.05rem; font-weight: 800; }

.sw-session-bar { display: flex; justify-content: space-between; align-items: baseline; padding: .55rem .9rem; border-radius: 10px; background: var(--sw-navy); color: #fff; font-weight: 700; }
.sw-session-bar span { font-size: .78rem; font-weight: 600; color: #cbd5e1; }
/* The same bar as a control. Restates the navy because the global button rule would otherwise
   repaint it, and keeps the chevron aligned with the count it sits beside. */
.sw-session-bar--btn {
  width: 100%; font: inherit; cursor: pointer;
  background: var(--sw-navy); color: #fff; border: 0;
  font-weight: 700; text-align: left;
}
.sw-session-bar--btn:hover { background: var(--sw-navy); filter: brightness(1.12); color: #fff; }
.sw-session-bar--btn span { display: inline-flex; align-items: center; gap: .35rem; }
.sw-ev { display: flex; align-items: center; gap: .7rem; padding: .65rem .9rem; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 12px; box-shadow: var(--sw-shadow-sm); }
.sw-ev__num { min-width: 34px; padding: .25rem .4rem; border-radius: 8px; background: var(--sw-primary-tint); color: var(--sw-primary); font-size: .72rem; font-weight: 800; text-align: center; flex-shrink: 0; }
.sw-ev__who { display: flex; flex-direction: column; min-width: 0; }
.sw-ev__name { font-weight: 700; color: var(--sw-navy); }
.sw-ev__sub { font-size: .8rem; color: var(--sw-muted); }

.sw-mine { padding: 1rem; }
.sw-mine__head { display: flex; align-items: center; gap: .7rem; }
.sw-mine__who { flex: 1; min-width: 0; }
.sw-mine__name { font-weight: 700; color: var(--sw-navy); }
.sw-mine__sub { font-size: .82rem; color: var(--sw-muted); }
.sw-mine__list { list-style: none; margin: .7rem 0 0; padding: .6rem 0 0; border-top: 1px solid var(--sw-border); display: flex; flex-direction: column; gap: .4rem; font-weight: 600; }
.sw-mine__list li { display: flex; align-items: center; gap: .5rem; }
.sw-mine__cta { display: block; text-align: center; margin-top: .8rem; }

.sw-meet-intro__name { font-weight: 800; font-size: 1.25rem; color: var(--sw-navy); letter-spacing: -0.01em; }
.sw-meet-intro__sub { color: var(--sw-muted); margin-top: .15rem; }
.sw-meet-intro__fee { color: var(--sw-primary); font-weight: 700; font-size: .9rem; margin-top: .35rem; }
.sw-meet-intro__who { display: inline-flex; align-items: center; gap: .3rem; margin-top: .4rem; font-size: .85rem; color: var(--sw-text-2); font-weight: 600; }
.sw-entry {
  display: flex; align-items: center; gap: .7rem; padding: .8rem .9rem; margin: 0; cursor: pointer;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 12px; box-shadow: var(--sw-shadow-sm);
}
.sw-entry--on { border-color: var(--sw-primary); box-shadow: inset 0 0 0 1px var(--sw-primary), var(--sw-shadow-sm); }
.sw-entry--off { cursor: default; }
.sw-entry--off .sw-entry__name { color: var(--sw-text-2); }
.sw-entry__who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-entry__name { font-weight: 700; color: var(--sw-navy); }
.sw-entry__sub { font-size: .82rem; color: var(--sw-muted); }
.sw-entry__na { color: var(--sw-muted-2); padding: 0 .4rem; }
.sw-entry input[type=checkbox] { width: 22px; height: 22px; accent-color: var(--sw-primary); margin: 0; flex-shrink: 0; }
.sw-summary { padding: 1rem; }
.sw-summary__row { display: flex; justify-content: space-between; gap: .8rem; padding: .35rem 0; color: var(--sw-text-2); }
.sw-summary__total { display: flex; justify-content: space-between; margin-top: .5rem; padding-top: .6rem; border-top: 1px solid var(--sw-border); font-weight: 800; color: var(--sw-navy); }
.sw-summary__total span:last-child { color: var(--sw-primary); font-size: 1.15rem; }
.sw-stack--footer { padding-bottom: 4.5rem; }
.sw-footerbar {
  position: fixed; left: 0; right: 0; bottom: calc(var(--sw-bottomnav-h) + env(safe-area-inset-bottom)); z-index: 20;
  padding: .6rem 1rem; background: linear-gradient(to top, var(--sw-bg) 70%, transparent);
}
.sw-footerbar__btn { display: block; width: 100%; max-width: 480px; margin: 0 auto; padding: .85rem 1rem; font-size: 1.02rem; }
@media (min-width: 901px) { .sw-footerbar { bottom: 0; } }


/* ═══════════════════════════════════════════════════════════════
   GOALS · TOP TIMES · PB CELEBRATION
   (docs/Design/06-performance-attendance/goals.png, top-times-50free.png, pb-celebration.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-titlebar--split { justify-content: space-between; }
.sw-pill { padding: .35rem .8rem; border-radius: 999px; background: var(--sw-navy); color: #fff; font-weight: 700; font-size: .85rem; }
.sw-search__clear { margin-left: auto; background: transparent; border: 0; padding: 0; color: var(--sw-muted-2); cursor: pointer; display: inline-flex; }
.sw-stat__icon { color: var(--sw-primary); margin-bottom: .3rem; display: inline-flex; }
.sw-stat--center .sw-stat__icon + .sw-label + .sw-stat__value { margin-top: .2rem; }

.sw-goal { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm); padding: 1rem; }
.sw-goal--done { border-color: var(--sw-success); }
.sw-goal__head { display: flex; align-items: flex-start; gap: .8rem; }
.sw-goal__who { flex: 1; min-width: 0; }
.sw-goal__title { font-weight: 700; font-size: 1.05rem; color: var(--sw-navy); }
.sw-goal__desc { font-size: .88rem; color: var(--sw-muted); margin-top: .2rem; }
.sw-goal__icon { width: 34px; height: 34px; border-radius: 999px; flex-shrink: 0; background: var(--sw-primary-tint); color: var(--sw-primary); display: inline-flex; align-items: center; justify-content: center; }
.sw-goal__icon--done { background: var(--sw-success-tint); color: var(--sw-success); }
.sw-goal__foot { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--sw-border); }
.sw-goal__remove { font-size: .85rem; color: var(--sw-muted); font-weight: 600; }
.sw-timefields { display: flex; align-items: center; gap: .4rem; }
.sw-timefields input { width: 5.5rem; text-align: center; }
.sw-timefields span { font-weight: 700; color: var(--sw-muted); }

.sw-tt { padding: 1rem; }
.sw-tt__event { font-weight: 800; font-size: 1.25rem; color: var(--sw-navy); margin: .15rem 0 .5rem; letter-spacing: -0.01em; }
.sw-tt__one { padding: 1.6rem 0; text-align: center; color: var(--sw-muted); font-size: .9rem; }
/* Scales evenly now that the viewBox is drawn in the proportion it is shown at — height follows
   width instead of being pinned, which is what stretched the old one sideways. */
.sw-chart { width: 100%; max-width: 760px; height: auto; display: block; }
.sw-chart__grid { stroke: var(--sw-border); stroke-width: 1; stroke-dasharray: 3 4; }
/* 9px was chosen when the viewBox was stretched almost four times, so it landed on screen far
   bigger than it read. At true scale it needs to be a real size. */
.sw-chart__ylabel, .sw-chart__xlabel { font-size: 13px; font-weight: 700; fill: var(--sw-muted-2); letter-spacing: .04em; }
.sw-chart__line { fill: none; stroke: var(--sw-primary); stroke-width: 3; stroke-linejoin: round; stroke-linecap: round; }
.sw-chart__line--prev { stroke: var(--sw-muted); stroke-width: 2; stroke-dasharray: 5 5; }
.sw-chart__dot { fill: var(--sw-primary); stroke: var(--sw-surface); stroke-width: 2; }
.sw-tt__legend { display: flex; justify-content: space-between; gap: 1rem; margin-top: .6rem; padding-top: .6rem; border-top: 1px solid var(--sw-border); font-size: .78rem; color: var(--sw-text-2); }
.sw-tt__key { display: inline-flex; align-items: center; gap: .5rem; }
.sw-tt__key--prev { text-align: right; }
.sw-tt__key b { font-weight: 700; color: var(--sw-navy); }
.sw-tt__swatch { width: 18px; height: 3px; border-radius: 2px; background: var(--sw-primary); }
.sw-tt__swatch--prev { background: var(--sw-muted); }
.sw-tt__row {
  display: flex; align-items: center; gap: .7rem; width: 100%; padding: .75rem .9rem; text-align: left; cursor: pointer; font: inherit;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 12px; box-shadow: var(--sw-shadow-sm); color: var(--sw-text);
}
.sw-tt__row:hover { background: var(--sw-surface); }
.sw-tt__row--on, .sw-tt__row--on:hover { background: var(--sw-primary-tint); border-color: var(--sw-primary); box-shadow: inset 0 0 0 1px var(--sw-primary); }
.sw-tt__wave { width: 32px; height: 32px; border-radius: 8px; background: var(--sw-surface-sunken); color: var(--sw-text-2); display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sw-tt__row--on .sw-tt__wave { background: var(--sw-primary); color: #fff; }
.sw-tt__name { flex: 1; font-weight: 700; color: var(--sw-navy); }
.sw-tt__row--on .sw-tt__name { color: var(--sw-primary); }
.sw-tt__time { font-weight: 800; color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-tt__row--on .sw-tt__time { color: var(--sw-primary); }

.sw-dir__body { padding: 0 1rem .9rem; }
.sw-req { display: flex; align-items: center; gap: .7rem; padding: .6rem .7rem; border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-bg); margin-bottom: .45rem; }
.sw-req--off { opacity: .55; }
.sw-req__who { flex: 1; min-width: 0; }
.sw-req__edit { display: flex; flex-direction: column; gap: .4rem; }
.sw-req__title { font-weight: 700; color: var(--sw-navy); font-size: .92rem; }
.sw-req__sub { font-size: .8rem; color: var(--sw-muted); }

.sw-celebrate {
  position: fixed; inset: 0; z-index: 4000; display: flex; flex-direction: column; justify-content: center; padding: 2rem 1.5rem;
  background: var(--sw-navy) radial-gradient(ellipse at 50% 120%, rgba(3,105,161,.55), transparent 60%); color: #fff; text-align: center;
}
.sw-celebrate__body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .5rem; }
.sw-celebrate__medal { width: 88px; height: 88px; border-radius: 999px; background: var(--sw-accent); color: var(--sw-navy); display: inline-flex; align-items: center; justify-content: center; margin-bottom: 1rem; }
.sw-celebrate__kicker { font-size: .78rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--sw-accent); }
.sw-celebrate__event { font-size: 1.15rem; font-weight: 700; }
.sw-celebrate__time { font-size: 2.4rem; font-weight: 800; letter-spacing: -0.02em; }
.sw-celebrate__faster { display: inline-flex; align-items: center; gap: .3rem; padding: .45rem .9rem; border-radius: 999px; background: var(--sw-accent); color: var(--sw-navy); font-weight: 700; }
.sw-celebrate__prev { font-size: .88rem; color: #cbd5e1; margin-top: .4rem; }
.sw-celebrate__actions { display: flex; flex-direction: column; gap: .6rem; max-width: 420px; width: 100%; margin: 0 auto; }
.sw-celebrate__share, .sw-celebrate__share:hover { background: var(--sw-accent) !important; border-color: var(--sw-accent) !important; color: var(--sw-navy) !important; font-weight: 800; padding: .9rem 1rem; border-radius: 999px !important; }
.sw-celebrate__done, .sw-celebrate__done:hover { background: #fff !important; border-color: #fff !important; color: var(--sw-navy) !important; font-weight: 800; padding: .9rem 1rem; border-radius: 999px !important; }
/* ── Athlete profile identity card (docs/Design/11-head-coach/athlete-detail.png) ── */
.ath-id { display: flex; align-items: center; gap: .9rem; }
.ath-id__avatar { width: 56px; height: 56px; border-radius: 999px; background: var(--sw-primary-tint); color: var(--sw-primary); font-weight: 800; font-size: 1.15rem; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ath-id__body { min-width: 0; }
.ath-id__name { font-weight: 800; font-size: 1.15rem; color: var(--sw-navy); margin-bottom: .45rem; }

/* ── Attention needed (SwClubOverview) ──────────────────────────────
   Severity is a left rail and a tint, not a whole coloured card: the list must stay scannable
   when several rows are showing at once. */
.sw-attn-list { display: flex; flex-direction: column; gap: .6rem; }
.sw-attn {
  display: flex; align-items: center; gap: .8rem;
  padding: .85rem 1rem;
  border: 1px solid var(--sw-border);
  border-left: 4px solid var(--sw-muted-2);
  border-radius: 12px;
  background: var(--sw-surface);
  text-decoration: none;
  color: var(--sw-text);
}
a.sw-attn:hover { background: var(--sw-surface-sunken); }
.sw-attn__body { flex: 1; min-width: 0; }
.sw-attn__title { font-weight: 700; color: var(--sw-navy); }
.sw-attn__detail { font-size: .85rem; color: var(--sw-muted); margin-top: .15rem; }
.sw-attn .sw-icon { color: var(--sw-muted-2); flex-shrink: 0; }

.sw-attn--danger  { border-left-color: var(--sw-danger); }
.sw-attn--warning { border-left-color: var(--sw-warning); }
.sw-attn--info    { border-left-color: var(--sw-primary); }

/* An unread notification's own marker — the row's severity colour already carries urgency, this
   just says "you haven't seen this yet" independently of it. */
.sw-notif__dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 999px;
  background: var(--sw-primary); margin-right: .3rem; vertical-align: middle;
}

/* The notification bell in the top bar: an icon with the unread count riding its top-right
   corner, rather than inline the way the import queue's badge sits next to its own link text —
   the bell has no label to sit beside. */
.sw-topbar__bell {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  color: var(--sw-text); flex-shrink: 0;
}
.sw-topbar__bell .sw-badge-count {
  position: absolute; top: -4px; right: -6px; margin-left: 0;
}

/* Top bar identity text. Capped and ellipsised so a long email or club name can
   never push the nav, whatever the width. */
.sw-topbar__email,
.sw-topbar__club {
  font-size: .75rem;
  color: var(--sw-muted);
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sw-topbar__role {
  font-size: .75rem;
  font-weight: 700;
  color: var(--sw-primary);
  white-space: nowrap;
}

/* Attendance scale — three bands, traffic light, thresholds set where swim-club attendance
   actually varies.

     under 70 red · 70–84 amber · 85+ green · grey when nothing has been marked

   Three rather than five on purpose. Five steps put four bands under 70%, a range a working
   club rarely enters, and one band over 85%, where every real squad sits — so every squad came
   out the same colour and the chart said nothing. Three steps are also the most a reader can
   tell apart on a small ring at a glance; the earlier yellow and orange were near-indistinct.
   No blue at the top: blue is --sw-primary, which means "interactive" everywhere else here.

   The exact number is always printed in the middle, so colour is a second reading of the same
   fact rather than the only one. */
:root {
  --sw-att-poor: var(--sw-danger);    /* under 70 */
  --sw-att-fair: var(--sw-warning);   /* 70–84    */
  --sw-att-good: var(--sw-success);   /* 85+      */
}

/* ── Attendance wheels (SwClubOverview) ────────────────────────────
   conic-gradient rather than SVG: one element, no viewBox arithmetic, and the
   percentage drives it straight from --pct. The colour comes from the number,
   so a squad in trouble reads before you've read the figure. */
.sw-wheels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: .9rem;
}
.sw-wheel-card {
  display: block;
  text-decoration: none;        /* the card is an <a>; nothing inside it should look like a link */
  color: inherit;
  background: var(--sw-surface);
  border: 1px solid var(--sw-border);
  border-radius: 16px;
  padding: 1.1rem .8rem;
  text-align: center;
}
.sw-wheel {
  width: 96px;
  height: 96px;
  margin: 0 auto .7rem;
  border-radius: 999px;
  background: conic-gradient(var(--wheel) calc(var(--pct) * 1%), var(--sw-surface-sunken) 0);
  display: grid;
  place-items: center;
}
.sw-wheel__hole {
  width: 74px;
  height: 74px;
  border-radius: 999px;
  background: var(--sw-surface);
  display: grid;
  place-items: center;
}
.sw-wheel__value {
  font-size: 1.3rem;
  font-weight: 800;
  color: var(--sw-navy);
  font-variant-numeric: tabular-nums;
}
.sw-wheel-card__name { font-weight: 700; color: var(--sw-navy); font-size: .95rem; }
.sw-wheel-card__sub { font-size: .78rem; color: var(--sw-muted); margin-top: .15rem; }

/* ── Birthdays ─────────────────────────────────────────────────── */
.sw-bdays {
  display: flex;
  align-items: center;
  gap: .8rem;
  width: 100%;
  text-align: left;
  padding: .85rem 1rem;
  border: 1px solid var(--sw-border);
  border-radius: 12px;
  background: var(--sw-surface);
  cursor: pointer;
  font: inherit;
  color: var(--sw-text);
}
.sw-bdays:hover { background: var(--sw-surface-sunken); }
.sw-bdays__icon { color: var(--sw-accent, var(--sw-primary)); display: inline-flex; flex-shrink: 0; }
.sw-bdays__body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-bdays__title { font-weight: 700; color: var(--sw-navy); }
.sw-bdays__sub { font-size: .85rem; color: var(--sw-muted); margin-top: .15rem; }
.sw-bdays .sw-icon { color: var(--sw-muted-2); flex-shrink: 0; }

.sw-bday-list { display: flex; flex-direction: column; gap: .35rem; margin-top: -.35rem; }
.sw-bday {
  display: flex;
  align-items: baseline;
  gap: .7rem;
  padding: .55rem 1rem;
  border-left: 2px solid var(--sw-border);
  margin-left: 1rem;
}
.sw-bday__when { font-size: .78rem; font-weight: 700; color: var(--sw-primary); min-width: 6.5rem; }
.sw-bday__name { flex: 1; font-weight: 600; color: var(--sw-navy); }
.sw-bday__age { font-size: .8rem; color: var(--sw-muted); }

/* ── Upcoming meets ────────────────────────────────────────────────
   The countdown is the point: a gala eleven weeks out and one closing on Friday need to read
   differently at a glance, so the weeks number is the largest thing on the row. */
.sw-upmeet-list { display: flex; flex-direction: column; gap: .6rem; }
.sw-upmeet {
  display: flex; align-items: center; gap: 1rem;
  padding: .9rem 1rem;
  border: 1px solid var(--sw-border);
  border-radius: 12px;
  background: var(--sw-surface);
  text-decoration: none;
  color: inherit;
}
.sw-upmeet:hover { background: var(--sw-surface-sunken); }
.sw-upmeet__count {
  flex-shrink: 0; width: 62px; text-align: center;
  border-right: 1px solid var(--sw-border); padding-right: .8rem;
}
.sw-upmeet__weeks {
  display: block; font-size: 1.5rem; font-weight: 800; line-height: 1;
  color: var(--sw-navy); font-variant-numeric: tabular-nums;
}
.sw-upmeet__weeks-unit {
  display: block; font-size: .68rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--sw-muted); margin-top: .2rem;
}
.sw-upmeet__body { flex: 1; min-width: 0; }
.sw-upmeet__name { font-weight: 700; color: var(--sw-navy); }
.sw-upmeet__when { font-size: .85rem; color: var(--sw-muted); margin-top: .15rem; }
.sw-upmeet__entries { font-size: .8rem; color: var(--sw-muted); margin-top: .3rem; }
.sw-upmeet--soon .sw-upmeet__weeks { color: var(--sw-danger); }
.sw-upmeet--soon { border-left: 4px solid var(--sw-danger); }

/* ── Finances ──────────────────────────────────────────────────────
   Days overdue leads each row, because the list is sorted by it — the number you scan should be
   the number it is ordered by, or the ordering looks arbitrary. */
.sw-stat--alert .sw-stat__value { color: var(--sw-danger); }
.sw-stat--good  .sw-stat__value { color: var(--sw-success); }
.sw-stat--warn  .sw-stat__value { color: var(--sw-warning); }

.sw-overdue-list { display: flex; flex-direction: column; gap: .35rem; }
.sw-overdue {
  display: flex; align-items: center; gap: .9rem;
  padding: .6rem .9rem;
  border: 1px solid var(--sw-border);
  border-left: 3px solid var(--sw-danger);
  border-radius: 10px;
  background: var(--sw-surface);
  text-decoration: none; color: inherit;
}
.sw-overdue:hover { background: var(--sw-surface-sunken); }
.sw-overdue__days {
  flex-shrink: 0; min-width: 3.2rem; text-align: center;
  font-weight: 800; font-size: 1.05rem; color: var(--sw-danger);
  font-variant-numeric: tabular-nums;
}
.sw-overdue__days-unit {
  display: block; font-size: .62rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--sw-muted);
}
.sw-overdue__name { flex: 1; min-width: 0; font-weight: 600; color: var(--sw-navy);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-overdue__amount { font-weight: 700; color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-overdue__more { font-size: .82rem; color: var(--sw-muted); padding: .3rem .9rem; }

/* ── Attention needed: expanded rows ───────────────────────────────
   The collapsed item is a <button> when it expands and an <a> when it navigates, so the two
   behaviours are distinguishable by keyboard and screen reader as well as by the chevron
   direction. Both wear .sw-attn, so they look identical at rest. */
.sw-attn { width: 100%; font: inherit; text-align: left; cursor: pointer; }
button.sw-attn:hover { background: var(--sw-surface-sunken); }
.sw-attn--open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.sw-attn__chev { display: inline-flex; color: var(--sw-muted-2); transition: transform .15s ease; }
.sw-attn__chev--open { transform: rotate(180deg); }

.sw-attn-rows {
  border: 1px solid var(--sw-border);
  border-top: none;
  border-radius: 0 0 12px 12px;
  background: var(--sw-surface-sunken);
  margin-top: -.6rem;          /* close the gap the list's row-gap leaves above */
  padding: .3rem .4rem .4rem;
}
.sw-attn-row {
  display: flex; align-items: center; gap: .8rem;
  padding: .55rem .7rem;
  border-radius: 8px;
  background: var(--sw-surface);
  margin-top: .3rem;
}
.sw-attn-row__body { flex: 1; min-width: 0; }
.sw-attn-row__label { font-weight: 600; color: var(--sw-navy); font-size: .9rem; }
.sw-attn-row__sub { font-size: .78rem; color: var(--sw-muted); margin-top: .1rem; }
.sw-attn-row__action {
  flex-shrink: 0;
  font-size: .78rem; font-weight: 700;
  padding: .35rem .7rem;
  border-radius: 8px;
  border: 1px solid var(--sw-primary-tint);
  background: var(--sw-primary-tint);
  color: var(--sw-primary-strong);
  text-decoration: none;
  white-space: nowrap;
}
.sw-attn-row__action:hover { background: var(--sw-sunflower-tint); border-color: var(--sw-sunflower-tint); color: var(--sw-sunflower-ink); }
.sw-attn-row__more { font-size: .78rem; color: var(--sw-muted); padding: .45rem .7rem .2rem; }

@media (prefers-reduced-motion: reduce) {
  .sw-attn__chev { transition: none; }
}

/* ── Set editor ────────────────────────────────────────────────────
   Monospace and pre-wrap: a coach lines sets up with spaces and indentation, and a proportional
   font throws that away. What they type is what they see and what goes to WhatsApp. */
/* Selector deliberately carries the wrapper and the element: the base rule above is
   `.sw-field textarea` (0,1,1), so a lone `.sw-setbody` class (0,1,0) loses to it and the pill
   radius stays on. This has to out-specify it, not merely come later in the file. */
.sw-field textarea.sw-setbody {
  /* .sw-control is a 999px pill, which is right for a one-line input and turns an eighteen-row
     textarea into an oval. A workout is a document; it gets document corners. */
  border-radius: 14px;
  /* A textarea with no width falls back to its `cols` default — about 20 characters — because
     nothing in .sw-field stretches it. Without this the workout box is a narrow column. */
  width: 100%;
  box-sizing: border-box;
  /* A textarea is inline-block by default, so its line box leaves ~4px under it. The painted copy
     is `inset: 0` on the wrapper and would be that much taller than the box — the two then run out
     of scroll at different points and the last line's colour sits high. Block removes the gap. */
  display: block;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .85rem;
  line-height: 1.55;
  white-space: pre-wrap;
  tab-size: 2;
  resize: vertical;
  min-height: 18rem;
}
.sw-setmeta {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: .7rem .9rem;
  border: 1px solid var(--sw-border);
  border-radius: 12px;
  background: var(--sw-surface-sunken);
}
.sw-setmeta__figures { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.sw-setmeta__big { font-size: 1.25rem; font-weight: 800; color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-setmeta__unit { font-size: .75rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--sw-muted); }
.sw-setmeta__second { font-size: .8rem; color: var(--sw-muted); }
.sw-setmeta__none { font-size: .85rem; color: var(--sw-muted-2); }
.sw-setnote {
  display: flex; align-items: flex-start; gap: .5rem;
  font-size: .82rem; color: var(--sw-warning);
  padding: 0 .2rem;
}
.sw-setnote .sw-icon { flex-shrink: 0; margin-top: .1rem; }
.sw-setnote--ambiguous { flex-direction: column; color: var(--sw-text-2); }
.sw-setnote--ambiguous > svg { align-self: flex-start; }

/* ── The workout editor's audience chip bar (spec §5.5) ────────────────────
   Every chip — squad or tag — carries its own colour twice over: the thick left accent, and the dot
   that also changes it. Wraps freely: a club's dictionary is a handful of names, not a menu bar to
   fit on one line at 390px.

   ⚠ **A chip is tinted in its own colour, and that is how the colour reads** (Gideon, 2026-09-23:
   "a backdrop on each pill with the colour selected, like a light glow"). It replaced a
   `border-left: 3px` accent, which on a 999px pill rendered as a crescent rather than a rail and
   made every chip read as an opening bracket. Do not go back to a border for this, and do not strip
   the tint as duplicating the swatch — the colour is how a coach recognises an audience at a
   glance, so carrying it across the whole pill is the point rather than a repetition to tidy up. */
.sw-chipbar { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .3rem; }
.sw-audiencechip {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .3rem .65rem; border-radius: 999px; border: 1px solid var(--sw-border);
  background: var(--sw-surface); font-size: .8rem; font-weight: 600; color: var(--sw-text-2);
  cursor: pointer;
}
.sw-audiencechip:hover { border-color: var(--sw-primary); color: var(--sw-primary); }

/* The pill wears its audience's colour: a wash of it for the ground, a deeper draw of the same hue
   for the edge and the name, and a soft shadow in it so the chip lifts off the page — the "light
   glow". Every value is mixed from the one `--chip-colour` the markup sets inline, so a club
   picking any hex at all gets a chip that holds together rather than a palette of hand-tuned pairs.
   Mixed toward --sw-surface rather than toward white, so the wash follows the page's own ground. */
.sw-audiencechip--tag {
  --chip: var(--chip-colour, var(--sw-primary));
  background: color-mix(in srgb, var(--chip) 11%, var(--sw-surface));
  border-color: color-mix(in srgb, var(--chip) 30%, var(--sw-border));
  /* ⚠ Only a third of the way toward the chip's own hue, not most of the way. A club may pick any
     hex, and a pale one — a soft yellow, a mint — drawn 65% into the text left the name a washed
     olive on a near-white wash that could not be read. Held close to the body colour, the name
     stays legible for every possible choice while still leaning the right way; the ground and the
     glow are what carry the colour. */
  color: color-mix(in srgb, var(--chip) 35%, var(--sw-text));
  box-shadow: 0 1px 7px color-mix(in srgb, var(--chip) 24%, transparent);
}
/* Hover deepens the same hue instead of jumping to the brand primary, which would make every chip
   momentarily forget whose colour it is — the one thing the chip exists to say. */
.sw-audiencechip--tag:hover {
  background: color-mix(in srgb, var(--chip) 18%, var(--sw-surface));
  border-color: color-mix(in srgb, var(--chip) 48%, var(--sw-border));
  color: color-mix(in srgb, var(--chip) 45%, var(--sw-text));
  box-shadow: 0 2px 10px color-mix(in srgb, var(--chip) 34%, transparent);
}
.sw-audiencechip__count { font-size: .72rem; color: var(--sw-muted-2); font-variant-numeric: tabular-nums; }
.sw-audiencechip--add { border-style: dashed; color: var(--sw-muted); }
/* A zone chip reads in the same colour the zone word is painted in the set. */
/* A zone chip wears its zone's colour, so the row of them is the key to the tinted lines. */
.sw-audiencechip--zone {
  --chip: var(--chip-colour, var(--sw-accent));
  background: color-mix(in srgb, var(--chip) 12%, var(--sw-surface));
  border-color: color-mix(in srgb, var(--chip) 40%, var(--sw-border));
  color: color-mix(in srgb, var(--chip) 45%, var(--sw-text));
  font-weight: 700;
}

/* A tag chip holds three controls, so its own padding moves onto the name button — otherwise the
   swatch and the × sit inside the chip's padding and the tap target for inserting the tag stops
   short of the edges a coach aims at. */
.sw-audiencechip--tag { padding: 0 .4rem 0 0; gap: .25rem; }
.sw-audiencechip__name {
  appearance: none; border: 0; background: none; cursor: pointer;
  font: inherit; color: inherit;
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .3rem .25rem .3rem .5rem;
}
/* The colour input made into the swatch itself: the chip already shows the tag's colour, so the
   thing that shows it is the thing that changes it rather than a second control beside it. The
   browser's own well and border are stripped so what is left is the dot. */
.sw-audiencechip__swatch {
  appearance: none; -webkit-appearance: none;
  width: 14px; height: 14px; min-height: 0;
  padding: 0; border: 0; border-radius: 50%;
  background: none; cursor: pointer; flex: none;
  margin-left: .45rem;
}
.sw-audiencechip__swatch::-webkit-color-swatch-wrapper { padding: 0; }
.sw-audiencechip__swatch::-webkit-color-swatch { border: 1px solid var(--sw-border); border-radius: 50%; }
.sw-audiencechip__swatch::-moz-color-swatch { border: 1px solid var(--sw-border); border-radius: 50%; }

.sw-audiencechip__x {
  appearance: none; border: 0; background: none; cursor: pointer;
  font-size: 1rem; line-height: 1;
  padding: 0 .15rem; margin: 0;
  color: var(--sw-muted-2);
  flex: none;
}
.sw-audiencechip__x:hover { color: var(--sw-danger); }
.sw-newchip { display: flex; align-items: center; gap: .4rem; margin: .3rem 0; }
.sw-newchip__colour { width: 2rem; height: 2rem; padding: 0; border: 1px solid var(--sw-border); border-radius: 8px; }

/* ── Recurring plans ───────────────────────────────────────────────
   A plan is a rule, not an event, so it reads as a compact row rather than a card competing with
   the sessions it generates below it. */
.sw-plan-list { display: flex; flex-direction: column; gap: .5rem; }
.sw-plan {
  display: flex; align-items: center; gap: .9rem;
  padding: .8rem 1rem;
  border: 1px solid var(--sw-border);
  border-left: 3px solid var(--sw-primary);
  border-radius: 12px;
  background: var(--sw-surface);
}
.sw-plan__body { flex: 1; min-width: 0; }
.sw-plan__head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.sw-plan__squad { font-weight: 700; color: var(--sw-navy); }
.sw-plan__meta { font-size: .82rem; color: var(--sw-muted); margin-top: .15rem; }
/* Reading a workout: same monospace and wrapping as writing it, so what the coach sees on deck
   is exactly what they typed. */
.sw-setbody--read {
  margin: .6rem 0 0;
  padding: 0;
  border: 0;
  background: none;
  min-height: 0;
  overflow-x: auto;
}

/* ── A painted workout (SwWorkoutText) ─────────────────────────────
   The colours a workout is read in, decided once for both the writing box and the saved view
   (Gideon, 2026-09-23). Monospace and the same line height as .sw-setbody, because write mode
   lays this painting directly under the typing box and every character has to land in the same
   place — which is also why nothing here changes a glyph's width. Bold is safe in a monospace
   face (the advance width is fixed); padding, a larger font and letter-spacing are not, so the
   chip padding below is a read-mode-only rule and must stay inside .sw-wtext--read. */
.sw-wtext {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .85rem;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--sw-text);
}
.sw-wtext--dense { font-size: .8rem; line-height: 1.45; }
.sw-wtext__row {
  display: flex; align-items: baseline; gap: .6rem;
  padding: .05rem 0;
}
.sw-wtext__line { flex: 1; min-width: 0; }
/* A line tinted by its training zone (the editor's Zones switch). A wash only — nothing that could
   move a character, since in write mode this sits under the typing box; the rail is read mode's. */
.sw-wtext__row--zoned { background: var(--zone-tint); border-radius: 4px; }
.sw-wtext--read .sw-wtext__row--zoned { box-shadow: inset 3px 0 0 var(--zone-colour); padding-left: .4rem; }
/* A round drawn down the margin (B, 2026-10-24): a rule beside every line a "6x" repeats, stopping at its
   last line. Drawn outside the text so nothing under the caret moves. ⚠ Not "--round": that is already the
   class of a round's own header row (sw-wtext__row--@Kind). */
.sw-wtext__row--inround { position: relative; }
.sw-wtext__row--inround::before { content: ""; position: absolute; left: -.55rem; top: 0; bottom: 0; width: 3px; border-radius: 2px; background: var(--sw-primary); }
.sw-wtext__row--inroundend::before { bottom: 30%; border-radius: 0 0 2px 2px; }

/* A line that names who the work is for, or titles a part of the session. The underline is the
   structure the coach wrote made visible; it changes no character's width. */
.sw-wtext__row--label .sw-wtext__line,
.sw-wtext__row--round .sw-wtext__line,
.sw-wtext__row--variation .sw-wtext__line {
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: .25em;
  text-decoration-color: var(--sw-border);
}
/* Notation C: a line varying the block under it rather than starting a new one. It reads as
   structure like a label does, but dashed, because it does not open anything — it qualifies what
   is already open, and that difference is exactly what a coach needs to see at a glance. */
.sw-wtext__row--variation .sw-wtext__line { text-decoration-style: dashed; }
.sw-wtext__row--label { margin-top: .5rem; }
.sw-wtext__row--label:first-child { margin-top: 0; }

/* Each line's own distance, down the right. Tabular figures so the column lines up. */
.sw-wtext__m {
  flex: none;
  font-size: .75rem; font-weight: 700;
  color: var(--sw-muted);
  font-variant-numeric: tabular-nums;
}
/* A heading's figure is the block under it, so it reads darker than a line's own. */
.sw-wtext__m--total { color: var(--sw-navy); }
/* What the system made of the line, in words — the ghost writer. Quieter than the workout
   itself: it is a confirmation, not part of the set. */
.sw-wtext__say {
  flex: none; max-width: 45%;
  font-family: Inter, system-ui, sans-serif;
  font-size: .72rem;
  color: var(--sw-muted);
  text-align: right;
}

/* A swimmer's own pace target, just after the term it comes from — read-only, never in the text. */
.sw-wtext__pace {
  /* A bubble set a little apart from the term it answers (Gideon, 2026-09-24). */
  display: inline-block; margin: 0 .35rem 0 .75rem;
  padding: .08rem .6rem; border-radius: 999px; line-height: 1.3; vertical-align: 1px;
  font-family: Inter, system-ui, sans-serif; font-size: .78rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--sw-primary-strong); background: var(--sw-primary-tint);
  border: 1px solid color-mix(in srgb, var(--sw-primary) 30%, transparent);
  box-shadow: 0 1px 2px rgba(10, 25, 47, .12);
}
/* The coach's squad table of pace targets on the session page. */
.sw-pacetable { width: 100%; border-collapse: collapse; font-size: .85rem; }
.sw-pacetable th, .sw-pacetable td { padding: .3rem .5rem; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--sw-border); }
.sw-pacetable th:first-child, .sw-pacetable td:first-child { text-align: left; }
.sw-pacetable th { font-weight: 700; }
.sw-pacetable th small { display: block; font-weight: 400; color: var(--sw-muted); }
.sw-pacetable td { font-variant-numeric: tabular-nums; }

.sw-wtok { border-radius: 3px; }
.sw-wtok--num { font-weight: 700; color: var(--sw-navy); }
.sw-wtok--stroke { color: var(--sw-primary); }
.sw-wtok--gear { color: var(--sw-success); }
.sw-wtok--qual { color: var(--sw-text-2); }
.sw-wtok--zone { color: color-mix(in srgb, var(--sw-accent) 70%, var(--sw-navy)); font-weight: 700; }
.sw-wtok--time { color: var(--sw-muted); }
/* A coach's note is never counted — greyed, colour only: a change of weight or slant would move the caret off the letters in write mode */
.sw-wtok--note { color: var(--sw-muted-2); }

/* The workout writer's symbol guide and welcome (Gideon, 2026-10-23) — SwWorkoutGuide, and SwSetEditor's welcome sheet. */
.sw-wguide { display: grid; gap: var(--sw-space-5); }
.sw-wguide__top { gap: var(--sw-space-2); margin-bottom: var(--sw-space-3); }
.sw-wguide__intro { color: var(--sw-text-2); margin: 0 0 var(--sw-space-3); }
.sw-wguide__title { font-size: 1rem; font-weight: 700; color: var(--sw-navy); margin: 0; }
.sw-wguide__lede { color: var(--sw-muted); font-size: .85rem; margin: 2px 0 var(--sw-space-2); }
.sw-wguide__rows { display: grid; border: 1px solid var(--sw-border); border-radius: 12px; overflow: hidden; }
.sw-wguide__row { display: grid; grid-template-columns: 140px minmax(0, 1fr) minmax(0, 1.2fr) 80px; gap: var(--sw-space-3);
  align-items: start; padding: var(--sw-space-3); background: var(--sw-surface); }
.sw-wguide__row + .sw-wguide__row { border-top: 1px solid var(--sw-border); }
.sw-wguide__sym { justify-self: start; font-family: ui-monospace, Menlo, monospace; font-weight: 700; font-size: .9rem;
  color: var(--sw-primary); background: var(--sw-primary-tint); border-radius: 8px; padding: 2px 8px; white-space: pre; }
.sw-wguide__means { color: var(--sw-text); font-size: .9rem; }
.sw-wguide__example { background: var(--sw-surface-sunken); border-radius: 8px; padding: 6px 10px; min-width: 0; overflow-x: auto; }
.sw-wguide__counts { font-weight: 700; color: var(--sw-navy); font-variant-numeric: tabular-nums; white-space: nowrap; font-size: .9rem; }
@media (max-width: 700px) {
  .sw-wguide__row { grid-template-columns: auto minmax(0, 1fr); }
  .sw-wguide__example { grid-column: 1 / -1; }
  .sw-wguide__counts { grid-column: 1 / -1; }
}
.sw-wwelcome { display: grid; gap: var(--sw-space-3); }
.sw-wwelcome__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--sw-space-3); }
.sw-wwelcome__card { display: grid; gap: var(--sw-space-2); align-content: start; padding: var(--sw-space-4);
  border: 1px solid var(--sw-border); border-radius: 16px; background: var(--sw-surface); }
.sw-wwelcome__title { font-weight: 700; color: var(--sw-navy); }
.sw-wwelcome__text { margin: 0; color: var(--sw-text-2); font-size: .88rem; }
/* A squad wears its own colour, the same way a tag does — falling back to the brand's primary for
   a squad nobody has picked one for, which is how every squad looked before clubs could choose. */
.sw-wtok--squad {
  font-weight: 700;
  color: var(--chip-colour, var(--sw-primary));
  background: color-mix(in srgb, var(--chip-colour, var(--sw-primary)) 13%, transparent);
}
/* A tag wears its own colour — the same one its chip in the editor's chip bar carries, so the
   word and the button a coach tapped to insert it read as the same thing. */
.sw-wtok--tag {
  font-weight: 700;
  color: var(--chip-colour, var(--sw-accent));
  background: color-mix(in srgb, var(--chip-colour, var(--sw-accent)) 15%, transparent);
}
/* A line the parser made nothing of, and one whose label it could not resolve. A soft underline
   rather than a background, so it reads as a spellcheck mark and not as an error.
   ⚠ Write mode only, deliberately. Every real set carries headings the parser has no use for —
   "W/u :", "M set" — and marking them is exactly the feedback a coach wants while writing and pure
   noise once the set is written and being swum off the wall. */
.sw-wtext--write .sw-wtext__row--unread .sw-wtext__line,
.sw-wtext--write .sw-wtext__row--ambiguous .sw-wtext__line {
  text-decoration: underline wavy var(--sw-accent);
  text-underline-offset: .25em;
}
/* A speed-chart term naming a target its chart does not have ("100SS 2nd" on a 35) — red, because
   swimmers would get no number from it, which is worth fixing before the set goes out. */
.sw-wtext--write .sw-wtext__row--pacemiss .sw-wtext__line {
  text-decoration: underline wavy var(--sw-danger);
  text-underline-offset: .25em;
}
.sw-wtext__row--pacemiss .sw-wtext__say,
.sw-writer__now--warn { color: var(--sw-danger); }

/* Read mode only: with no cursor to stay aligned with, a squad or a tag can have real air around
   it. Never move this out of the read-mode block — in the writing box it would shift every
   character after it and the painting would slide out of step with what is being typed. */
.sw-wtext--read .sw-wtok--squad,
.sw-wtext--read .sw-wtok--tag {
  padding: .05rem .35rem;
  border-radius: 999px;
}

/* ── The ghost writer: the painted copy under the typing box ───────
   A browser text box cannot hold colour, so an exact painted copy sits underneath it and the box's
   own text is made invisible — the overlay every web code editor uses. Everything here exists to
   hold the two to identical metrics, because the coach's caret is in the box on top and the colour
   has to land under the same characters.

   ⚠ Nothing in write mode may change how wide a character is. Bold is safe (the face is monospace,
   so the advance width is fixed) and so are colour, a background tint and an underline. Padding, a
   different font size and letter-spacing are not — which is why .sw-wtext--read owns the chip
   padding and this block does not. */
.sw-bodyfield--ghost { position: relative; }

.sw-writer__mirror {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;            /* scrolled in step with the box by streamlineWriter.followScroll */
  pointer-events: none;        /* every click belongs to the box on top */
  /* The box's own border and padding, repeated exactly. A transparent border rather than none, so
     the content box starts in the same place rather than one pixel higher. */
  border: 1px solid transparent;
  border-radius: 14px;
  padding: .72rem .95rem;
  box-sizing: border-box;
  /* ⚠ And the box's own surface, because in write mode the textarea's background is made
     transparent so the painting shows through it — which left nothing at all drawing the white
     card, and the workout box read as loose text on the page ground (Gideon, 2026-09-23: "looks
     funny and missing its white box"). This layer is the one that draws what the box looks like,
     so the surface belongs here; the border stays on the textarea above, where focus can still
     colour it. */
  background: var(--sw-surface);
}
/* ⚠ Every property here is one the two layers must agree on, and each was found disagreeing by
   measuring the live pair rather than by reading the rules — the box inherits some of these from
   .sw-control and the painting does not:
     white-space / overflow-wrap  a line has to wrap at the same character in both, or every line
                                  after the first long one is off by a row;
     tab-size                     .sw-setbody sets 2 and the default is 8, so one tab would slide
                                  the rest of its line sideways;
     font-weight                  .sw-control makes the box 700. Matching it means the token
                                  classes below, which are also 700, change no width at all —
                                  which is the whole rule of write mode. */
.sw-writer__mirror .sw-wtext {
  /* Spare room under the last line, so the painting can always scroll at least as far as the box.
     If it ever falls short it stops scrolling early, and every line near the bottom of a long set
     sits below the caret (2026-09-27). Below every line, so it moves nothing that is aligned. */
  padding-bottom: 50vh;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  tab-size: 2;
  font-weight: 700;
}

/* The box itself: still where the typing, the caret and the selection live — only its own text is
   hidden, so the painting below shows through. */
.sw-field textarea.sw-setbody--ghost {
  position: relative;
  z-index: 1;
  color: transparent;
  background: transparent;
  caret-color: var(--sw-text);
}
.sw-field textarea.sw-setbody--ghost::selection { background: var(--sw-primary-tint); color: transparent; }

/* Room down the right for the readings, reserved on BOTH layers so the text keeps landing in the
   same place. A line of a workout is short; the gutter costs nothing a coach was using. */
.sw-field textarea.sw-setbody--ghost,
.sw-writer__mirror { padding-right: 11rem; }

/* ⚠ A row in write mode is EXACTLY one line of text tall, and nothing may add to that. The read
   mode above gives each row `padding: .05rem 0` for air, which is 1.6px a row — invisible on one
   line and half a line adrift by the eighth, so the caret sat between the painted lines further
   down the set (Gideon spotted it, 2026-09-23: "the type bar and letter placed isn't on the same
   line"). The box on top has no such padding, and every vertical rule here has to be judged
   against that, not against how it looks on its own. `.sw-wtext__row` height must equal
   `line-height`; measure it rather than assume it. */
.sw-wtext--write .sw-wtext__row { padding: 0; margin: 0; }

/* In write mode a row is a plain block — a flex row with gaps would move the text sideways. The
   reading and the distance are lifted out of the flow entirely and parked in the gutter, which is
   what keeps them beside their own line however it wraps. */
.sw-wtext--write .sw-wtext__row { display: block; position: relative; }
.sw-wtext--write .sw-wtext__say,
.sw-wtext--write .sw-wtext__m {
  position: absolute;
  top: 0;
  left: calc(100% + .7rem);
  width: 10rem;
  text-align: left;
  max-width: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* On a wide screen the gutter has room to spare, so the readings get more of it before they are cut
   off. Both layers again, and the reading's own width with them. The full reading of the line
   under the caret is always spelled out below the box (.sw-writer__now), whatever the width. */
@media (min-width: 900px) {
  .sw-field textarea.sw-setbody--ghost,
  .sw-writer__mirror { padding-right: 20rem; }
  .sw-wtext--write .sw-wtext__say,
  .sw-wtext--write .sw-wtext__m { width: 19rem; }
}
.sw-writer__now {
  margin-top: -.35rem;
  font-size: .8rem;
  color: var(--sw-text-2);
  line-height: 1.4;
}
.sw-writer__nowline { font-weight: 700; color: var(--sw-muted); margin-right: .35rem; }

/* A label or round header keeps its weight but loses the underline: under a cursor it reads as a
   spelling mark rather than as structure. */
.sw-wtext--write .sw-wtext__row--label .sw-wtext__line,
.sw-wtext--write .sw-wtext__row--round .sw-wtext__line,
.sw-wtext--write .sw-wtext__row--variation .sw-wtext__line { text-decoration: none; }
.sw-wtext--write .sw-wtext__row--label { margin-top: 0; }

.sw-writerbar { display: flex; justify-content: flex-end; margin-bottom: .4rem; }
.sw-writertoggle {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .3rem .7rem;
  border: 1px solid var(--sw-border);
  border-radius: 999px;
  background: var(--sw-surface);
  color: var(--sw-muted);
  font-size: .75rem; font-weight: 700;
  cursor: pointer;
}
.sw-writertoggle__dot {
  width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--sw-muted-2);
}
.sw-writertoggle--on { color: var(--sw-primary); border-color: var(--sw-primary); }
.sw-writertoggle--on .sw-writertoggle__dot { background: var(--sw-primary); }

/* On a phone there is no room for a gutter beside the line, and squeezing the text into half the
   width to make one would cost more than the readings are worth there. The colour stays — it needs
   no space of its own — and the readings step aside until there is room. */
@media (max-width: 640px) {
  .sw-field textarea.sw-setbody--ghost,
  .sw-writer__mirror { padding-right: .95rem; }
  .sw-wtext--write .sw-wtext__say,
  .sw-wtext--write .sw-wtext__m { display: none; }
}

/* ── Workout name suggestions ──────────────────────────────────────
   The name field is also a search of the library, so the list hangs under it like any other
   autocomplete rather than sitting in the page flow and shoving the editor down. */
.sw-namefield { position: relative; }
.sw-suggest {
  position: absolute; left: 0; right: 0; top: 100%;
  z-index: 40;
  margin-top: .3rem;
  background: var(--sw-surface);
  border: 1px solid var(--sw-border);
  border-radius: 12px;
  box-shadow: var(--sw-shadow);
  overflow: hidden;
}
.sw-suggest__item {
  display: flex; flex-direction: column; gap: .15rem;
  width: 100%; text-align: left;
  padding: .6rem .8rem;
  background: none; border: 0; border-bottom: 1px solid var(--sw-border);
  font: inherit; color: inherit; cursor: pointer;
}
.sw-suggest__item:last-child { border-bottom: 0; }
.sw-suggest__item:hover { background: var(--sw-surface-sunken); }
.sw-suggest__main { display: flex; align-items: center; gap: .5rem; }
.sw-suggest__name { font-weight: 700; color: var(--sw-navy); }
.sw-suggest__meta { font-size: .75rem; color: var(--sw-muted); }
.sw-suggest__peek {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .74rem; color: var(--sw-muted-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── The workout's total distance ──────────────────────────────────
   Sits directly under the box, because that is where the coach is already looking once they stop
   typing. Primary blue and larger than the surrounding text: it is the one number this screen
   produces, and it has to be readable at arm's length on a phone at the poolside. */
.sw-setvolume {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  padding: .1rem .2rem;
}
.sw-setvolume__km {
  font-size: 1.6rem;
  font-weight: 800;
  color: var(--sw-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.sw-setvolume__from {
  font-size: .78rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sw-muted);
}
.sw-setvolume__none { font-size: .85rem; color: var(--sw-muted-2); }

/* The first-line library search hangs off the workout box the same way the name's does. The
   textarea needs the positioning context, which .sw-field alone does not provide. */
.sw-bodyfield { position: relative; }

/* Anchored just under the first line rather than under the whole field: the search is happening on
   line one, so the list belongs there, not 400px below it past the end of an empty textarea.
   2.1rem = the textarea's top padding plus one line of monospace text. */
.sw-suggest--body { top: 2.1rem; margin-top: 0; }

/* The rules shown before anything is typed. Grey and roman — it must not read as content that is
   already in the box, which is exactly how a worked example read. */
.sw-setbody::placeholder {
  color: var(--sw-muted-2);
  font-style: normal;
  opacity: 1;
}

/* A plain statement of what a control is about to do — not a warning, so no icon and no amber. */
.sw-hint {
  font-size: .82rem;
  color: var(--sw-muted);
  padding: .1rem .2rem;
}


/* ═══════════════════════════════════════════════════════════════
   ADMIN OVERVIEW · PARENT HOME  (docs/Design/12-club-admin/admin-dashboard.png,
   09-parent-guardian/parent-dashboard.png)
   ═══════════════════════════════════════════════════════════════ */
a.sw-stat--link { text-decoration: none; color: var(--sw-text); display: block; }
.sw-navy-card { display: flex; align-items: center; gap: 1rem; padding: 1rem 1.1rem; border-radius: var(--sw-radius); background: var(--sw-navy); color: #fff; }
.sw-navy-card__ring { width: 68px; height: 68px; border-radius: 999px; flex-shrink: 0; background: rgba(255,255,255,.12); border: 2px solid rgba(255,255,255,.25); display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 1.15rem; }
.sw-navy-card__title { font-weight: 700; font-size: 1.05rem; }
.sw-navy-card__sub { font-size: .85rem; color: #cbd5e1; margin-top: .15rem; }

.sw-todo { display: flex; align-items: center; gap: .7rem; padding: .85rem 1rem; border-radius: 14px; border: 1px solid var(--sw-border); background: var(--sw-surface); text-decoration: none; color: var(--sw-text); }
.sw-todo__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.sw-todo__title { font-weight: 700; color: var(--sw-navy); }
.sw-todo__sub { font-size: .85rem; color: var(--sw-muted); }
.sw-todo .sw-icon { color: var(--sw-muted-2); flex-shrink: 0; }
.sw-todo--warn { background: var(--sw-accent-tint); border-color: var(--sw-accent); }
.sw-todo--warn .sw-todo__title { color: var(--sw-warning); }
.sw-todo--info { background: var(--sw-primary-tint); border-color: var(--sw-primary); }
.sw-todo--info .sw-todo__title { color: var(--sw-primary); }
.sw-todo--danger { background: var(--sw-danger-tint); border-color: var(--sw-danger); }
.sw-todo--danger .sw-todo__title { color: var(--sw-danger); }
.sw-todo--ok { flex-direction: column; align-items: flex-start; background: var(--sw-success-tint); border-color: var(--sw-success); }
.sw-todo--ok .sw-todo__title { color: var(--sw-success); }

.sw-child { padding: 0; overflow: hidden; }
.sw-child__head { display: flex; align-items: center; gap: .8rem; padding: 1rem; text-decoration: none; color: var(--sw-text); }
.sw-child__who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-child__name { font-weight: 700; font-size: 1.05rem; color: var(--sw-navy); }
.sw-child__sub { font-size: .85rem; color: var(--sw-muted); }
.sw-child__body { padding: .8rem 1rem; border-top: 1px solid var(--sw-border); }
.sw-child__session { display: flex; flex-direction: column; margin-top: .3rem; text-decoration: none; color: var(--sw-text); }
.sw-child__session-title { font-weight: 700; color: var(--sw-navy); }
.sw-child__session-sub { font-size: .85rem; color: var(--sw-muted); }
.sw-child__none { margin-top: .3rem; color: var(--sw-muted); font-size: .9rem; }
.sw-child__foot { display: flex; align-items: center; justify-content: space-between; padding: .7rem 1rem; border-top: 1px solid var(--sw-border); font-weight: 600; color: var(--sw-text-2); font-size: .9rem; }
.sw-child__rate { display: inline-flex; align-items: center; gap: .5rem; }
.sw-child__rate b { color: var(--sw-primary); font-size: 1rem; }


/* ═══════════════════════════════════════════════════════════════
   INVITE LINKS · JOIN  (docs/Design/11-head-coach/invite-code-generator.png,
   01-auth-onboarding/invite-code-entry.png, invalid-code.png, invite-confirmation.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-invite-form { padding: 1rem; display: flex; flex-direction: column; gap: .8rem; }
.sw-invite-form > .sw-label:first-child { margin-bottom: -.2rem; }
.sw-invite-active { padding: 1rem; border-color: var(--sw-primary); box-shadow: inset 0 0 0 1px var(--sw-primary), var(--sw-shadow-sm); }
.sw-invite-active__label { font-size: .7rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--sw-primary); }
.sw-invite-active__code { font-size: 1.6rem; font-weight: 800; letter-spacing: .08em; color: var(--sw-navy); margin-top: .35rem; font-variant-numeric: tabular-nums; }
.sw-invite-active__link { display: inline-block; margin-top: .3rem; padding: .25rem .55rem; border-radius: 8px; background: var(--sw-surface-sunken); color: var(--sw-text-2); font-size: .8rem; font-weight: 600; word-break: break-all; }
.sw-invite-active__actions { display: flex; gap: .6rem; margin-top: .9rem; }
.sw-invite-active__meta { margin-top: .7rem; font-size: .82rem; color: var(--sw-muted); }
.sw-pillbtn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: .4rem; border-radius: 999px !important; padding: .7rem 1rem; font-weight: 700; }
.sw-invite { display: flex; align-items: center; gap: .7rem; padding: .8rem .9rem; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 12px; box-shadow: var(--sw-shadow-sm); }
.sw-invite--off { opacity: .6; }
.sw-invite__who { flex: 1; min-width: 0; }
.sw-invite__code { font-weight: 800; letter-spacing: .06em; color: var(--sw-navy); }
.sw-invite__sub { font-size: .82rem; color: var(--sw-muted); }
.sw-invite__status { display: flex; flex-direction: column; align-items: flex-end; gap: .25rem; }
.sw-invite__status .sw-chip { text-transform: uppercase; letter-spacing: .05em; font-size: .66rem; }
.sw-invite__exp { font-size: .75rem; color: var(--sw-muted); }
.sw-invite__revoke { font-size: .8rem; color: var(--sw-muted); font-weight: 600; }
.sw-iconbtn, .sw-iconbtn:hover { width: 36px; height: 36px; border-radius: 10px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; flex-shrink: 0; }

.sw-join { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 2rem 0 1rem; max-width: 420px; margin: 0 auto; }
.sw-join__badge { width: 64px; height: 64px; }
.sw-join__wordmark { height: 30px; width: auto; margin-top: .8rem; }
.sw-join__title { font-size: 1.25rem; font-weight: 800; color: var(--sw-navy); margin: 1.6rem 0 .3rem; }
.sw-join__sub { color: var(--sw-muted); margin: 0 0 1.4rem; }
.sw-join__sub--left { text-align: center; margin-bottom: 1rem; }
.sw-join .sw-label { align-self: flex-start; text-transform: none; letter-spacing: 0; font-size: .85rem; color: var(--sw-text-2); margin-bottom: .35rem; }
.sw-join__label--error { color: var(--sw-danger) !important; }
.sw-join__field { display: flex; align-items: center; gap: .6rem; width: 100%; padding: .75rem .9rem; border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-surface); color: var(--sw-muted-2); }
.sw-join__field--error { border-color: var(--sw-danger); color: var(--sw-danger); }
.sw-join__input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font: inherit; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--sw-navy); }
.sw-join__field--error .sw-join__input { color: var(--sw-danger); }
.sw-join__error { display: flex; gap: .6rem; align-items: flex-start; width: 100%; text-align: left; margin-top: .8rem; padding: .8rem .9rem; border-radius: 12px; background: var(--sw-danger-tint); border: 1px solid var(--sw-danger); color: var(--sw-danger); font-size: .9rem; }
.sw-join__error .sw-icon { flex-shrink: 0; margin-top: .1rem; }
.sw-join__cta { width: 100%; margin-top: 1rem; padding: .85rem 1rem; border-radius: 999px !important; font-size: 1.02rem; }
.sw-join__foot { margin-top: 3rem; color: var(--sw-muted); font-size: .9rem; }
.sw-join__foot a { color: var(--sw-primary); font-weight: 700; text-decoration: none; }
.sw-join__info { display: flex; gap: .6rem; align-items: flex-start; margin-top: 1rem; padding: .8rem .9rem; border-radius: 12px; background: var(--sw-primary-tint); border: 1px solid var(--sw-primary); color: var(--sw-primary); font-size: .9rem; }
.sw-join__info .sw-icon { flex-shrink: 0; margin-top: .1rem; }
.sw-join__form { padding: 1rem; display: flex; flex-direction: column; gap: .8rem; }
.sw-kv { padding: .3rem 1rem; }
.sw-kv__row { display: flex; justify-content: space-between; gap: 1rem; padding: .75rem 0; border-bottom: 1px solid var(--sw-border); }
.sw-kv__row:last-child { border-bottom: 0; }
.sw-kv__row span { color: var(--sw-muted); }
.sw-kv__row b { color: var(--sw-navy); text-align: right; }
.sw-steps { display: flex; gap: .4rem; margin-bottom: 1rem; }
.sw-steps__dot { flex: 1; text-align: center; font-size: .7rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--sw-muted-2); padding: .35rem 0; border-top: 3px solid var(--sw-border); }
.sw-steps__dot--on { color: var(--sw-primary); border-top-color: var(--sw-primary); }
.sw-steps__dot--done { color: var(--sw-success); border-top-color: var(--sw-success); }
.sw-terms { padding: 1rem; max-height: 320px; overflow-y: auto; font-size: .9rem; line-height: 1.55; }
.sw-terms p { margin: 0 0 .6rem; }
.sw-footerbar--two { display: flex; flex-direction: column; gap: .5rem; }
.sw-footerbar--two .sw-footerbar__btn { margin: 0 auto; }
/* Why Save is greyed out — on its own ground, since it sits in the bar's faded top edge. */
.sw-footerbar__why { margin: 0 auto; padding: .3rem .8rem; border-radius: 999px; background: var(--sw-accent-tint); color: var(--sw-text); font-size: .85rem; text-align: center; }
.sw-invite-link { display: inline-flex; align-items: center; gap: .35rem; margin-bottom: .75rem; font-size: .9rem; font-weight: 700; color: var(--sw-primary); text-decoration: none; }


/* ═══════════════════════════════════════════════════════════════
   PROFILE  (docs/Design/04-profile-account/profile-settings.png, edit-profile.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-profile-hero { display: flex; flex-direction: column; align-items: center; text-align: center; padding: .5rem 0 1rem; }
.sw-profile-hero__avatar { width: 80px; height: 80px; border-radius: 999px; object-fit: cover; }
.sw-profile-hero__avatar--initials { display: inline-flex; align-items: center; justify-content: center; background: var(--sw-navy); color: #fff; font-weight: 800; font-size: 1.5rem; letter-spacing: .04em; }
.sw-profile-hero__avatar--sm { width: 64px; height: 64px; font-size: 1.2rem; }
.sw-profile-hero__name { font-weight: 800; font-size: 1.15rem; color: var(--sw-navy); margin-top: .8rem; }
.sw-profile-hero__email { color: var(--sw-muted); font-size: .9rem; margin-top: .15rem; }
.sw-setrows { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm); overflow: hidden; }
.sw-setrow { display: flex; align-items: center; gap: .8rem; padding: .9rem 1rem; border-bottom: 1px solid var(--sw-border); text-decoration: none; color: var(--sw-text); }
.sw-setrow:last-child { border-bottom: 0; }
.sw-setrow > .sw-icon:first-child { color: var(--sw-text-2); flex-shrink: 0; }
.sw-setrow > .sw-icon:last-child { color: var(--sw-muted-2); flex-shrink: 0; }
.sw-setrow__label { flex: 1; min-width: 0; font-weight: 600; color: var(--sw-navy); display: flex; flex-direction: column; gap: .2rem; }
.sw-setrow__sub { font-weight: 500; font-size: .85rem; color: var(--sw-muted); display: flex; flex-direction: column; gap: .15rem; }
.sw-setrow__sub a { color: var(--sw-primary); font-weight: 600; text-decoration: none; }
.sw-setrow--static { cursor: default; }
.sw-logout, .sw-logout:hover { display: inline-flex; align-items: center; gap: .5rem; align-self: flex-start; background: transparent; border: 0; padding: .6rem 0; font: inherit; font-weight: 700; color: var(--sw-danger); cursor: pointer; }
.sw-profile-photo { display: flex; align-items: center; gap: 1rem; }
.sw-profile-photo__title { font-weight: 700; color: var(--sw-navy); }
.sw-profile-photo__sub { font-size: .85rem; color: var(--sw-muted); }


/* ═══════════════════════════════════════════════════════════════
   REPORTS  (docs/Design/11-head-coach/team-reports.png, athlete-performance-review.png,
             06-performance-attendance/session-report.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-bars { padding: 1rem; display: flex; flex-direction: column; gap: .9rem; }
.sw-bars__head { display: flex; justify-content: space-between; margin-bottom: .35rem; font-weight: 600; color: var(--sw-text-2); }
.sw-bars__head b { color: var(--sw-navy); }
.sw-bar__fill--accent { background: var(--sw-warning); }
.sw-bar__fill--navy { background: var(--sw-navy); }
.sw-top { padding: .4rem 1rem; }
.sw-top__row { display: flex; justify-content: space-between; align-items: center; gap: .8rem; padding: .6rem 0; border-bottom: 1px solid var(--sw-border); }
.sw-top__row:last-child { border-bottom: 0; }
.sw-top__who { font-weight: 700; color: var(--sw-navy); }
.sw-top__what { font-weight: 700; color: var(--sw-success); text-align: right; flex-shrink: 0; }
.sw-pbhead, .sw-pbrow { display: grid; grid-template-columns: 1.6fr 1fr .9fr .9fr; gap: .5rem; align-items: center; padding: .6rem 1rem; }
.sw-pbhead { font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--sw-muted-2); background: var(--sw-surface-sunken); border-radius: var(--sw-radius) var(--sw-radius) 0 0; }
.sw-pbhead span:not(:first-child), .sw-pbrow span:not(:first-child) { text-align: right; }
.sw-pbrow { border-top: 1px solid var(--sw-border); font-variant-numeric: tabular-nums; }
/* The break between long-course and short-course times. Tinted rather than merely spaced, so the
   two sets read as separate lists — they are not comparable, and a gap alone would not say that
   loudly enough on a long table. */
.sw-pbcourse {
  padding: .5rem 1rem;
  border-top: 1px solid var(--sw-border);
  background: var(--sw-primary-tint);
  color: var(--sw-primary);
  font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.sw-pbrow__event { font-weight: 700; color: var(--sw-navy); }
.sw-pbrow__pb { font-weight: 800; color: var(--sw-primary); }
.sw-pbrow__prev { color: var(--sw-muted); }
.sw-pbrow__delta { font-weight: 700; color: var(--sw-muted-2); }
.sw-pbrow__delta--up { color: var(--sw-success); }
.sw-pbrow__delta--down { color: var(--sw-danger); }
.sw-results { padding: 0; overflow: hidden; }
.sw-results__head { display: grid; grid-template-columns: 1fr auto auto; gap: 1rem; padding: .6rem 1rem; background: var(--sw-navy); color: #fff; font-size: .78rem; font-weight: 700; }
.sw-results__row { display: grid; grid-template-columns: 1fr auto auto; gap: 1rem; padding: .65rem 1rem; border-top: 1px solid var(--sw-border); font-size: .92rem; }
.sw-results__row span:first-child { color: var(--sw-navy); font-weight: 600; }
.sw-results__row span:not(:first-child) { font-variant-numeric: tabular-nums; text-align: right; min-width: 3ch; }
.sw-results__row .sw-results__place { color: var(--sw-primary); font-weight: 800; }


/* ═══════════════════════════════════════════════════════════════
   SESSION BUILDER  (docs/Design/11-head-coach/program-builder.png)
   ═══════════════════════════════════════════════════════════════ */
.sw-sheet__cols--4 { grid-template-columns: repeat(4, 1fr); gap: .5rem; }
.sw-label--tiny { font-size: .62rem; margin-bottom: .2rem; }
.sw-builder__suggest { margin-left: auto; font-size: .85rem; }

/* ── Club: club-management, club-settings and club-directory ─────────────────── */
.sw-titlebar__cta { margin-left: auto; }
button.sw-back { border: 0; cursor: pointer; font: inherit; }
.sw-club-archived-toggle { margin: .6rem 0 .2rem; }
.sw-club-list { display: flex; flex-direction: column; gap: .6rem; }
.sw-club {
  display: flex; align-items: center; gap: .8rem; width: 100%; text-align: left; margin: 0;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); padding: .95rem 1rem; font: inherit; color: var(--sw-text); cursor: pointer;
}
.sw-club--on { border-color: var(--sw-primary); box-shadow: inset 0 0 0 1px var(--sw-primary); }
.sw-club--archived { cursor: default; opacity: .8; }
.sw-club__body { flex: 1; min-width: 0; }
.sw-club__name { font-weight: 700; color: var(--sw-navy); display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.sw-club__meta { display: flex; flex-wrap: wrap; gap: .3rem .9rem; margin-top: .25rem; font-size: .85rem; color: var(--sw-muted); }
.sw-club__meta span { display: inline-flex; align-items: center; gap: .3rem; }
.sw-club > .sw-icon:last-child { color: var(--sw-muted-2); flex-shrink: 0; }
.sw-club-hero { display: flex; flex-direction: column; align-items: center; text-align: center; padding: .4rem 0 1.1rem; }
.sw-club-hero__logo { width: 84px; height: 84px; border-radius: 20px; }
.sw-club-hero__name { font-weight: 800; font-size: 1.25rem; color: var(--sw-navy); margin-top: .9rem; letter-spacing: -0.01em; }
.sw-club-hero__sub { display: inline-flex; align-items: center; gap: .3rem; color: var(--sw-muted); font-size: .9rem; margin-top: .25rem; }
.sw-details {
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); padding: 1rem; margin-top: 1rem;
}
.sw-details__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .35rem; }
.sw-details__title { font-weight: 700; color: var(--sw-navy); }
.sw-details__row { display: flex; justify-content: space-between; gap: 1rem; padding: .45rem 0; font-size: .92rem; }
.sw-details__row + .sw-details__row { border-top: 1px solid var(--sw-border); }
.sw-details__key { color: var(--sw-muted); flex-shrink: 0; }
.sw-details__val { font-weight: 600; color: var(--sw-text); text-align: right; min-width: 0; overflow-wrap: anywhere; }
.sw-club-hero + .sw-stat-grid + .sw-label, .sw-details + .sw-label, .sw-setrows + .sw-label { margin-top: 1.1rem; }
.sw-setrows + .sw-card { margin-top: 1.1rem; }

/* ── Calendar (calendar-view) ─────────────────────────────────────────────────── */
.sw-cal {
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm); padding: 1rem;
}
.sw-cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
.sw-cal__month { font-weight: 800; font-size: 1.1rem; color: var(--sw-navy); letter-spacing: -0.01em; }
.sw-cal__nav { display: inline-flex; gap: .15rem; }
.sw-cal__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .3rem .1rem; }
.sw-cal__dow { text-align: center; font-size: .78rem; font-weight: 700; color: var(--sw-muted); padding: .25rem 0; }
.sw-cal__day {
  width: 36px; height: 36px; max-width: 100%; margin: 0 auto; border-radius: 999px; border: 0; padding: 0;
  background: transparent; font: inherit; font-weight: 600; color: var(--sw-text); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.sw-cal__day--out { color: var(--sw-muted-2); }
.sw-cal__day--has { background: var(--sw-primary-tint); color: var(--sw-primary); font-weight: 700; }
.sw-cal__day--today { background: var(--sw-primary); color: #fff; font-weight: 800; }
.sw-cal__day--on:not(.sw-cal__day--today) { box-shadow: inset 0 0 0 2px var(--sw-primary); }
.sw-cal + .sw-label, .sw-sched__card + .sw-label, .sw-muted-text + .sw-label { margin-top: .6rem; }

/* ── A cancelled session ───────────────────────────────────────────────────
   Kept on the schedule rather than deleted, so it has to read as "called off" at a glance —
   danger-toned, but a notice rather than an error, since nothing has gone wrong. */
.sw-cancelled {
  display: flex; align-items: center; gap: .75rem;
  padding: .8rem 1rem;
  border: 1px solid var(--sw-danger);
  border-left-width: 3px;
  border-radius: 12px;
  background: var(--sw-danger-tint);
  color: var(--sw-danger);
}
.sw-cancelled__body { flex: 1; min-width: 0; }
.sw-cancelled__title { font-weight: 700; }
.sw-cancelled__why { font-size: .85rem; margin-top: .1rem; opacity: .85; }
.sw-cancelled .sw-icon { flex-shrink: 0; }

/* ── Session actions, in the attendance palette ─────────────────────────────
   The same three colours the dashboard wheels use, so amber and red mean the same thing here as
   they do there: amber is a change, red is calling it off. Tinted rather than solid — these sit
   under the hero as options, not as the page's primary action. */
.btn-att-fair {
  background: var(--sw-accent-tint) !important;
  border-color: var(--sw-accent-tint) !important;
  color: var(--sw-att-fair) !important;
  font-weight: 700;
}
.btn-att-fair:hover { filter: brightness(.97); }

.btn-att-poor {
  background: var(--sw-danger-tint) !important;
  border-color: var(--sw-danger-tint) !important;
  color: var(--sw-att-poor) !important;
  font-weight: 700;
}
.btn-att-poor:hover { filter: brightness(.97); }

/* With the heading gone the back link has no row-mate, so the bar collapses to just the control. */
.sw-titlebar--bare { min-height: 0; margin-bottom: .35rem; }

/* ── The schedule, a day at a time ─────────────────────────────────────────
   Collapsed rows in the same shape as the dashboard's Attention needed list, so the whole week
   fits on one screen and a coach opens the day they want. The session cards sit inside the
   expanded panel, which supplies its own padding. */
.sw-day-rows { padding: .6rem; gap: .5rem; display: flex; flex-direction: column; align-items: stretch; }
/* A flex column stretches its children to fill the height, which left a form field floating in a
   panel of empty space. Fields size to their content; only the list of cards should grow. */
.sw-day-rows > .sw-field,
.sw-day-rows > .sw-hint,
.sw-day-rows > .sw-actions { flex: 0 0 auto; }
.sw-day-rows > .sw-field .sw-control { width: 100%; box-sizing: border-box; }

/* The weekday sits beside its Today / Tomorrow badge rather than against it. */
.sw-attn__title { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.sw-day-rows .sw-sched__card { margin: 0; }

/* A cancelled session stays on the schedule, greyed and struck, so the squad sees it was called
   off rather than finding it missing. */
.sw-sched__card--off { opacity: .6; }
.sw-sched__card--off .sw-sched__title { text-decoration: line-through; }
.sw-chip--danger { background: var(--sw-danger-tint); color: var(--sw-danger); }

/* ── The planning calendar ─────────────────────────────────────────────────
   Sits with the recurring plans rather than on its own page: the grid shows where the pattern
   lands, the plans underneath are what produce it. Two marks, two meanings — a filled day has
   sessions, a ringed day is a plan that has not been generated yet, and the boundary between them
   is the schedule's one-week horizon. */
.sw-plancal { display: flex; flex-direction: column; gap: .7rem; }

.sw-cal__day--planned {
  box-shadow: inset 0 0 0 1.5px var(--sw-primary);
  color: var(--sw-primary);
  font-weight: 700;
}

.sw-plancal__key {
  display: flex; gap: 1rem; flex-wrap: wrap;
  font-size: .75rem; color: var(--sw-muted);
  padding: 0 .2rem;
}
/* Each swatch is the mark it names, at the size of a dot: solid for today, the pale tint for a day
   that has sessions, a ring for a plan that has not been generated. "sessions" used to carry the
   solid dot, which is what today wears on the grid — so the key named the wrong mark. */
.sw-plancal__key i { display: inline-block; width: .8rem; height: .8rem; border-radius: 50%; margin-right: .3rem; vertical-align: -2px; }
.sw-key--today { background: var(--sw-primary); }
.sw-key--has { background: var(--sw-primary-tint); }
.sw-key--planned { background: transparent; box-shadow: inset 0 0 0 1.5px var(--sw-primary); }

.sw-plancal__day {
  border-top: 1px solid var(--sw-border);
  padding-top: .7rem;
}
.sw-plancal__date { font-weight: 800; color: var(--sw-navy); }
.sw-plancal__what { font-size: .85rem; color: var(--sw-muted); margin-top: .15rem; }

.sw-plancal__list { display: flex; flex-direction: column; gap: .3rem; margin-top: .6rem; }
.sw-plancal__row {
  display: flex; align-items: center; gap: .6rem;
  padding: .5rem .65rem;
  border: 1px solid var(--sw-border);
  border-radius: 10px;
  background: var(--sw-surface);
  color: inherit; text-decoration: none;
}
.sw-plancal__row:hover { background: var(--sw-surface-sunken); }

/* Swimmers away (Sessions → Time off & absences): the day list's thin row, its left edge the
   decision — amber waiting, green approved, red declined — with the register's marks to change it. */
.sw-awaylist { display: flex; flex-direction: column; gap: .35rem; margin-top: .4rem; }
.sw-awayrow {
  display: flex; align-items: center; gap: .55rem; padding: .35rem .5rem .35rem .65rem;
  border: 1px solid var(--sw-border); border-left: 4px solid var(--sw-accent); border-radius: 10px;
  background: var(--sw-surface); font-size: .86rem;
}
.sw-awayrow--approved { border-left-color: var(--sw-success); background: color-mix(in srgb, var(--sw-success-tint) 45%, var(--sw-surface)); }
.sw-awayrow--declined { border-left-color: var(--sw-danger); background: color-mix(in srgb, var(--sw-danger-tint) 45%, var(--sw-surface)); }
.sw-awayrow__name { font-weight: 700; color: var(--sw-navy); text-decoration: none; white-space: nowrap; }
.sw-awayrow__when { font-variant-numeric: tabular-nums; color: var(--sw-text-2); white-space: nowrap; }
.sw-awayrow__note { flex: 1; min-width: 0; color: var(--sw-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-awayrow .sw-mark { width: 34px; height: 28px; border-radius: 8px; flex-shrink: 0; }
@media (max-width: 640px) {
  .sw-awayrow { flex-wrap: wrap; }
  .sw-awayrow__note { flex-basis: 100%; order: 9; }
}
.sw-plancal__row--off { opacity: .6; }
.sw-plancal__row--off .sw-plancal__name { text-decoration: line-through; }
.sw-plancal__time { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--sw-navy); font-size: .85rem; }
.sw-plancal__name { flex: 1; min-width: 0; font-size: .88rem; }
.sw-plancal__row .sw-icon { color: var(--sw-muted-2); flex-shrink: 0; }

/* ── The swimmer's profile, on one page ────────────────────────────────────
   Registration and the four numbers first, then each area behind a row that opens — the same
   disclosure the dashboard and the schedule use, so the whole swimmer is one page rather than
   three tabs a coach has to remember to visit. */
.sw-profile__reg { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .45rem; }

/* Guardians on the swimmer's card. The name leads and the ways to reach them follow, because the
   coach reading this already knows whose parent they want and is looking for the number. Each row
   wraps rather than truncating — a phone number cut in half is worse than a second line. */
.sw-guardians { margin-top: .55rem; }
.sw-guardians__row {
  display: flex; flex-wrap: wrap; gap: .15rem .6rem;
  align-items: baseline; font-size: .82rem; margin-top: .2rem;
}
.sw-guardians__name { color: var(--sw-text-2); font-weight: 600; }
.sw-guardians__link { color: var(--sw-primary); text-decoration: none; }
.sw-guardians__link:hover { text-decoration: underline; }

.sw-statrow {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: .6rem;
}
@media (max-width: 560px) { .sw-statrow { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.sw-stat {
  border: 1px solid var(--sw-border);
  border-radius: 14px;
  background: var(--sw-surface);
  padding: .75rem .8rem;
  text-align: center;
}
.sw-stat__value {
  font-size: 1.35rem; font-weight: 800; color: var(--sw-navy);
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.sw-stat__label {
  font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sw-muted); margin-top: .15rem;
}

.sw-chip--success { background: var(--sw-success-tint); color: var(--sw-success); }

/* A saved registration number, read back rather than sitting in an open form. */
.sw-idline { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; padding: .2rem .1rem; }
.sw-idline__label {
  font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sw-muted);
}
.sw-idline__value {
  font-weight: 800; color: var(--sw-navy); font-variant-numeric: tabular-nums;
}
.sw-idline .btn { margin-left: auto; }

/* A disclosure nested inside an open panel: quieter than the section rows around it. */
.sw-attn--sub { border-left-color: var(--sw-border); background: var(--sw-surface-sunken); }

/* The four tiles are also the tabs: the number and the way into the detail behind it are one
   control, rather than a tile above a row repeating the same figure. */
.sw-stat { width: 100%; font: inherit; cursor: pointer; transition: border-color .12s ease, background .12s ease; }
.sw-stat:hover { background: var(--sw-surface-sunken); }
.sw-stat--on {
  border-color: var(--sw-primary);
  box-shadow: inset 0 -3px 0 var(--sw-primary);
  background: var(--sw-surface);
}
.sw-stat--on .sw-stat__label { color: var(--sw-primary); }

/* The breakdown inside a panel is display only — smaller, and not clickable. */
.sw-statrow--sub .sw-stat { cursor: default; }
.sw-statrow--sub .sw-stat:hover { background: var(--sw-surface); }
.sw-statrow--sub .sw-stat__value { font-size: 1.1rem; }

.sw-panel { display: flex; flex-direction: column; gap: .6rem; }

/* A quiet inline control — "Edit ID" beside the registration chip. */
.sw-linkbtn {
  background: none; border: 0; padding: 0 .2rem;
  color: var(--sw-primary); font: inherit; font-size: .8rem; font-weight: 700;
  cursor: pointer;
}
.sw-linkbtn:hover { text-decoration: underline; }

/* ── Streamline ranking ────────────────────────────────────────────────────
   The pentagon on the athlete profile. Every axis is the level scale — world record 100, Level 1
   cutoff 0 — so the shape is absolute and two swimmers' can be compared, unlike the self-relative
   stroke profile this replaced. The tier badges below it use the same `.sw-tier--N` colours. */
.sw-spec-wrap {
  display: grid;
  grid-template-columns: minmax(220px, 300px) 1fr;
  gap: 1rem;
  align-items: center;
}
@media (max-width: 640px) { .sw-spec-wrap { grid-template-columns: 1fr; } }

.sw-spec { display: flex; flex-direction: column; gap: .5rem; }
.sw-spec__svg { width: 100%; height: auto; display: block; }
.sw-spec__ring { fill: none; stroke: var(--sw-border); stroke-width: 1; }
.sw-spec__spoke { stroke: var(--sw-border); stroke-width: 1; }
.sw-spec__area { fill: var(--sw-primary); fill-opacity: .22; stroke: var(--sw-primary); stroke-width: 2; }
.sw-spec__dot { fill: var(--sw-primary); }
.sw-spec__label { font-size: 11px; font-weight: 700; fill: var(--sw-text-2); }
.sw-spec__note { padding: 0 .1rem; }

/* The headline reads "8A · Butterfly · 100m LC" — the swimmer's single best-rated swim, which is
   what the pentagon's longest spoke is pointing at. */
.sw-rank__head { display: flex; flex-direction: column; gap: .25rem; }
.sw-rank__title {
  font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--sw-muted);
}
.sw-rank__peak { display: flex; align-items: center; gap: .4rem; }
.sw-rank__best { font-size: .82rem; font-weight: 700; color: var(--sw-navy); }
/* Sits under the stroke name on each spoke, so an axis says what level it is, not just how long
   it is. Smaller and lighter than the stroke name — the name is what you scan, the tier is the
   detail you stop on. */
.sw-rank__axistier { font-size: 10px; font-weight: 700; fill: var(--sw-primary); }

.sw-spec__range { padding: 0 .2rem; }
.sw-spec__bar {
  position: relative; height: 4px; border-radius: 999px;
  background: linear-gradient(90deg, var(--sw-accent), var(--sw-primary));
}
.sw-spec__bar span {
  position: absolute; top: 50%; width: 11px; height: 11px; margin-left: -5.5px;
  transform: translateY(-50%); border-radius: 50%;
  background: var(--sw-surface); border: 2.5px solid var(--sw-navy);
}
.sw-spec__ends {
  display: flex; justify-content: space-between;
  font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--sw-muted); margin-top: .35rem;
}

.sw-strokes { display: flex; flex-direction: column; gap: .4rem; }
.sw-stroke {
  display: grid; grid-template-columns: 1fr auto; gap: 0 .8rem;
  padding: .5rem .7rem;
  border: 1px solid var(--sw-border); border-radius: 10px; background: var(--sw-surface);
}
.sw-stroke__name {
  font-weight: 700; color: var(--sw-navy);
  display: flex; align-items: center; gap: .4rem;
}
.sw-stroke__best {
  font-weight: 800; color: var(--sw-primary); font-variant-numeric: tabular-nums;
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
}
.sw-stroke__meta { font-size: .78rem; color: var(--sw-muted); }

/* Only the name is a link on a register row — the present and absent buttons own the rest of it. */
.sw-reg__link { color: inherit; text-decoration: none; }
.sw-reg__link:hover { color: var(--sw-primary); text-decoration: underline; }

/* ── Time away ─────────────────────────────────────────────────────────────
   Sits with the attendance history because it is the reason behind the gaps in it: three misses in
   a row read very differently with an injury against them. */
.sw-abs { display: flex; flex-direction: column; gap: .45rem; }
.sw-abs__head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; }
.sw-abs__form {
  display: flex; flex-direction: column; gap: .55rem;
  padding: .7rem; border: 1px solid var(--sw-border); border-radius: 12px;
  background: var(--sw-surface);
}
.sw-abs__row {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .55rem .7rem;
  border: 1px solid var(--sw-border); border-radius: 10px; background: var(--sw-surface);
}
.sw-abs__row--now { border-color: var(--sw-warning); background: var(--sw-accent-tint); }
.sw-abs__when { flex: 1; min-width: 0; font-size: .88rem; color: var(--sw-navy); }
.sw-abs__note { font-size: .78rem; color: var(--sw-muted); margin-top: .1rem; }

/* Distance among the header facts, rather than owning a tab of its own. */
.sw-profile__facts {
  display: flex; gap: .9rem; flex-wrap: wrap;
  margin-top: .5rem; font-size: .82rem; color: var(--sw-muted);
}
.sw-profile__facts strong { color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-profile__facts-note { color: var(--sw-muted-2); }

.sw-pb--link { text-decoration: none; color: inherit; }
.sw-pb--link:hover { background: var(--sw-surface-sunken); }

/* Away, on the profile card. A swimmer who is injured or on holiday changes how their attendance
   figure should be read, so it sits with the name rather than behind a tab. */
.sw-away {
  display: flex; align-items: flex-start; gap: .55rem;
  margin-top: .55rem; padding: .5rem .7rem;
  border: 1px solid var(--sw-warning); border-left-width: 3px; border-radius: 10px;
  background: var(--sw-accent-tint); color: var(--sw-att-fair);
}
.sw-away .sw-icon { flex-shrink: 0; margin-top: .1rem; }
.sw-away__body { display: flex; flex-wrap: wrap; gap: .1rem .5rem; align-items: baseline; }
.sw-away__what { font-weight: 800; }
.sw-away__when { font-size: .85rem; opacity: .9; }
.sw-away__note { flex-basis: 100%; font-size: .8rem; opacity: .85; }

/* An absence that has not started yet is information, not a warning. */
.sw-away--soon {
  border-color: var(--sw-border); background: var(--sw-surface-sunken); color: var(--sw-text-2);
}

/* The absence note is a description, not a label — it gets document corners and room to breathe,
   for the same reason the workout box does. */
.sw-field textarea.sw-absnote {
  border-radius: 12px; width: 100%; box-sizing: border-box;
  min-height: 4.5rem; resize: vertical; line-height: 1.45; font-weight: 400;
}

/* The attendance wheel standing in for the avatar on the profile card. */
.sw-profile__ring { flex-shrink: 0; width: 68px; height: 68px; }
.sw-profile__ring .sw-ring__value { font-size: .95rem; font-weight: 800; }

/* The attendance summary without its own wheel — the card above already carries the number. */
.sw-attsum {
  display: flex; flex-direction: column; gap: .15rem;
  padding: .1rem .2rem .3rem;
  font-size: .88rem; color: var(--sw-text-2);
}
.sw-attsum__streak { color: var(--sw-muted); font-size: .82rem; }
/* The period switch sits above the sentence it changes, aligned right so it reads as a control on
   this figure rather than a heading over the whole panel. */
.sw-attsum__periods { align-self: flex-end; margin-bottom: .2rem; }

/* The attendance tile carries the wheel instead of a bare figure: the colour says whether the
   number is a problem before the number is read, and it matches the squad wheels on the dashboard.
   Sized to sit in a tile without making the row taller than its neighbours. */
.sw-stat--wheel { padding-top: .6rem; padding-bottom: .6rem; }
.sw-wheel--sm { width: 58px; height: 58px; margin: 0 auto .3rem; }
.sw-wheel--sm .sw-wheel__hole { width: 44px; height: 44px; }
.sw-wheel--sm .sw-wheel__value { font-size: .82rem; font-weight: 800; }

/* ── Level tiers and SSA qualifying standards ──────────────────────────────
   The tier is a rating on a world scale; the standard is what the swimmer has earned the right to
   enter. They answer different questions, so they read differently — the tier is a compact badge
   that darkens as it climbs, the standard is a named chip. */
.sw-tier {
  display: inline-block; min-width: 2.4rem; text-align: center;
  padding: .12rem .4rem; border-radius: 6px;
  font-size: .78rem; font-weight: 800; font-variant-numeric: tabular-nums;
  background: var(--sw-surface-sunken); color: var(--sw-muted);
}
/* 1–3 developing, 4–6 club, 7–8 provincial and up, 9–10 the top of the scale. */
.sw-tier--1, .sw-tier--2, .sw-tier--3 { background: var(--sw-surface-sunken); color: var(--sw-muted); }
.sw-tier--4, .sw-tier--5, .sw-tier--6 { background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-tier--7, .sw-tier--8 { background: var(--sw-accent-tint); color: var(--sw-att-fair); }
.sw-tier--9, .sw-tier--10 { background: var(--sw-success-tint); color: var(--sw-success); }

/* ── The Streamline Standard page ────────────────────────────────────────────────────────────
   The bars are drawn to the real band widths, so the silhouette is the scale itself: a broad
   base at Level 1 narrowing to a sliver at Level 10, with 10S as a capstone above it. They reuse
   the .sw-tier--N colours, so a level is the same colour here as on the chip beside a swimmer. */
.sw-std__lede { color: var(--sw-text-2); max-width: 62ch; margin: 0 0 1rem; }

.sw-std__anchors { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: .75rem; }
.sw-std__anchor {
  background: var(--sw-surface); border: 1px solid var(--sw-border);
  border-left: 3px solid var(--sw-accent); border-radius: 12px; padding: .85rem 1rem;
}
.sw-std__anchorpct { font-size: 1.4rem; font-weight: 800; color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-std__anchorpct span { font-size: .8rem; font-weight: 500; color: var(--sw-muted); }
.sw-std__anchorwhat { font-weight: 700; font-size: .9rem; margin-top: .15rem; }
.sw-std__anchornote { font-size: .8rem; color: var(--sw-muted); margin-top: .1rem; line-height: 1.4; }

.sw-std__picker { display: grid; grid-template-columns: 2fr 1fr 1.4fr; gap: .75rem; }
.sw-std__wr { margin-top: .75rem; font-size: .85rem; color: var(--sw-muted); font-variant-numeric: tabular-nums; }
.sw-std__wr b { color: var(--sw-text); }

.sw-std__scale { display: flex; flex-direction: column; gap: 2px; overflow-x: auto; }
.sw-std__row {
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) 10.5rem;
  align-items: center; gap: .8rem; min-width: 34rem;
}
.sw-std__row--btn {
  background: none; border: 0; padding: 0; margin: 0; width: 100%;
  font: inherit; color: inherit; text-align: left; cursor: pointer; border-radius: 8px;
}
.sw-std__row--btn:hover .sw-std__bar { filter: brightness(.94); }
.sw-std__row--btn:focus-visible { outline: 2px solid var(--sw-primary); outline-offset: 2px; }
.sw-std__row--open .sw-std__n { color: var(--sw-primary); }

.sw-std__lvl { display: flex; align-items: baseline; justify-content: flex-end; gap: .45rem; }
.sw-std__n { font-size: 1.35rem; font-weight: 800; color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-std__n--cap { color: var(--sw-att-fair); }
.sw-std__meaning { font-size: .7rem; color: var(--sw-muted); text-align: right; line-height: 1.2; }

.sw-std__barcell { display: flex; align-items: center; justify-content: center; height: 2.4rem; }
.sw-std__bar {
  height: 100%; border-radius: 3px; min-width: 3px;
  display: flex; align-items: center; justify-content: center;
  /* .sw-tier--N supplies a pale tint and a strong text colour. On a chip the tint is enough; on a
     bar the width of Level 1 would read as empty space, so the bar takes an edge in its own hue. */
  border: 1px solid currentColor; box-sizing: border-box;
}
.sw-std__barw { font-size: .7rem; font-weight: 700; white-space: nowrap; padding: 0 .5rem; }
.sw-std__cap {
  height: 100%; width: 1.35rem; background: var(--sw-accent);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.sw-std__times { font-size: .82rem; color: var(--sw-text-2); font-variant-numeric: tabular-nums; }
.sw-std__times b { color: var(--sw-text); }
.sw-std__at { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--sw-muted); }

.sw-std__letters {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: .5rem;
  padding: .6rem .75rem .8rem; margin: 0 0 .3rem;
  background: var(--sw-surface-sunken); border-radius: 10px;
}
.sw-std__letter { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.sw-std__lettertime { font-size: .82rem; font-variant-numeric: tabular-nums; color: var(--sw-text-2); }
.sw-std__lettertime b { color: var(--sw-text); }
.sw-std__letterwhat { font-size: .72rem; color: var(--sw-muted); flex-basis: 100%; }

.sw-std__foot { margin-top: .9rem; }

@media (max-width: 40rem) {
  .sw-std__picker { grid-template-columns: 1fr; }
  .sw-std__row { grid-template-columns: 5rem minmax(0, 1fr) 8.5rem; gap: .5rem; min-width: 22rem; }
  .sw-std__meaning { display: none; }
  .sw-std__times { font-size: .75rem; }
}

/* The rungs are two families with a deliberate break between them, because the ladder itself has
   one: SSA Levels 2–3 are provincial progression, while SANJ, Youth and Senior are the rungs that
   put a swimmer at a national gala. Colouring that break is the point — a coach scanning a squad
   sees who is on a national ladder without reading a word.

   Levels climb by darkening within the one sky hue, the same way .sw-tier does, so the two scales
   stay visually consistent even though they must never be conflated (QualifyingLadder.cs).
   The national rungs are bronze → silver → gold.

   ⚠ Ranks are 1–5 and start at SSA LEVEL 2. There is no --0: SSA Level 1 has no qualifying times
   at all and the API returns a null QualifiedFor for it, so no chip renders — which is correct.
   It is "the absence of a standard, not a standard" (QualifyingLadder.cs), and giving it a grey
   badge is what would make the silver above it look like nothing.

   The medals order by rank, not by difficulty: SANJ is age-graded while Youth is open-age, so a
   16-year-old can hold a Youth time and miss SANJ. Every screen already sorts these by Rank, so
   this is consistent with the app — just do not read gold/silver/bronze as "harder". */
.sw-standard { font-weight: 700; }
.sw-standard--1 { background: #eff9fe;                   color: #0284c7; }              /* SSA Level 2 */
.sw-standard--2 { background: var(--sw-primary-tint);    color: var(--sw-primary-strong); } /* SSA Level 3 */
.sw-standard--3 { background: var(--sw-medal-bronze-tint); color: var(--sw-medal-bronze-ink); } /* SANJ */
.sw-standard--4 { background: var(--sw-medal-silver-tint); color: var(--sw-medal-silver-ink); } /* Youth */
.sw-standard--5 { background: var(--sw-medal-gold-tint);   color: var(--sw-medal-gold-ink); }   /* Senior */
.sw-standard .sw-icon { vertical-align: -2px; margin-right: .15rem; }

/* ── Workout library ───────────────────────────────────────────────
   The same tile as the dashboard's "Attention needed" list: a coloured tag down the left, the
   title and its figures, a chevron, and the workout unfolding underneath. The tag reads session
   size rather than severity — nothing in a library is wrong, it is just bigger or smaller. */
.sw-libbar { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin: 0 0 .9rem; }
.sw-libbar__gap { flex: 1; min-width: .5rem; }
.sw-libbar__label {
  font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--sw-muted-2); margin-right: .1rem;
}
.sw-libbar__btn {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .4rem .8rem;
  font-size: .85rem; font-weight: 600;
  border: 1px solid var(--sw-primary-tint);
  border-radius: var(--sw-radius-pill);
  background: var(--sw-primary-tint);
  color: var(--sw-primary-strong);
  cursor: pointer;
}
/* The app's soft button (see .btn): yellow on hover; the one switched on is solid, so it still
   stands out from the soft ones beside it. */
.sw-libbar__btn:hover { background: var(--sw-sunflower-tint); border-color: var(--sw-sunflower-tint); color: var(--sw-sunflower-ink); }
.sw-libbar__btn--on,
.sw-libbar__btn--on:hover {
  background: var(--sw-primary);
  border-color: var(--sw-primary);
  color: #fff;
}
.sw-libbar__btn .sw-icon { flex-shrink: 0; }

.sw-libsearch { display: flex; align-items: center; gap: .6rem; margin-bottom: .9rem; }
.sw-libsearch .sw-control { flex: 1; min-width: 0; }

.sw-libsel {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .55rem .9rem; margin-bottom: .9rem;
  border: 1px solid var(--sw-primary);
  border-radius: var(--sw-radius-sm);
  background: var(--sw-primary-tint);
  font-size: .85rem; font-weight: 600; color: var(--sw-primary);
}

/* The tile. Mirrors .sw-attn, but is a row of its own controls rather than one big button, so
   the actions sit on the side without nesting a button inside a button. */
.sw-lib {
  display: flex; align-items: center; gap: .6rem;
  padding: .5rem 1rem .5rem 0;
  border: 1px solid var(--sw-border);
  border-left: 4px solid var(--sw-muted-2);
  border-radius: 12px;
  background: var(--sw-surface);
}
.sw-lib--open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.sw-lib__pick { margin-left: 1rem; width: 1.05rem; height: 1.05rem; flex-shrink: 0; }
.sw-lib__main {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: .8rem;
  padding: .35rem 0 .35rem 1rem;
  background: none; border: 0; font: inherit; text-align: left; cursor: pointer;
}
.sw-lib__main:hover { background: none; }
.sw-lib__main:hover .sw-lib__title { color: var(--sw-primary); }
.sw-lib__body { flex: 1; min-width: 0; }
.sw-lib__title { display: block; font-weight: 700; color: var(--sw-navy); }
.sw-lib__detail { display: block; font-size: .85rem; color: var(--sw-muted); margin-top: .15rem; }
.sw-lib__acts { display: flex; gap: .35rem; flex-wrap: wrap; flex-shrink: 0; }
.sw-lib__rename { margin-left: 1rem; max-width: 20rem; }

/* Size, not severity: faint when no distance could be read, deepening as the session grows. */
.sw-lib--none   { border-left-color: var(--sw-border); }
.sw-lib--short  { border-left-color: var(--sw-muted-2); }
.sw-lib--middle { border-left-color: var(--sw-primary); }
.sw-lib--long   { border-left-color: var(--sw-navy); }

.sw-lib-open {
  border: 1px solid var(--sw-border);
  border-top: none;
  border-radius: 0 0 12px 12px;
  background: var(--sw-surface-sunken);
  margin-top: -.6rem;          /* close the gap the list's row-gap leaves above */
  padding: .5rem .6rem .6rem;
}
/* Monospace and pre-wrap, the same as the editor: a coach's alignment is part of the workout. */
/* The typography moved onto .sw-wtext inside this when the library's workouts started being
   painted rather than printed (2026-09-23) — one definition of what a workout looks like, shared
   with the editor and the session page. What is left here is the panel the workout sits in. */
.sw-lib-open__body {
  margin: 0;
  padding: .7rem .85rem;
  border-radius: 8px;
  background: var(--sw-surface);
  color: var(--sw-text);
}

@media (max-width: 48rem) {
  /* On a phone the actions cannot share the line with the title, so they drop under it. */
  .sw-lib { flex-wrap: wrap; padding-bottom: .7rem; }
  .sw-lib__main { flex-basis: 100%; }
  .sw-lib__acts { padding-left: 1rem; }
}

/* The composer. Sits above the list rather than in a dialog: writing a workout is the point of
   the page, not an interruption to it. */
.sw-libwrite {
  border: 1px solid var(--sw-primary);
  border-radius: var(--sw-radius-sm);
  background: var(--sw-surface);
  padding: 1rem;
  margin-bottom: 1.1rem;
}
.sw-libwrite__head {
  font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--sw-primary); margin-bottom: .7rem;
}
.sw-libwrite__name { margin-top: .8rem; max-width: 28rem; }

/* A chip small enough to sit inside a line of secondary text, as the part-of-day tag does on the
   dashboard's attention rows. */
.sw-chip--sm { padding: .12rem .45rem; font-size: .68rem; letter-spacing: .02em; }
/* That row now carries a tag beside its time, so it lines them up instead of stacking. */
.sw-attn-row__sub { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }

/* ── Upcoming sessions ─────────────────────────────────────────────
   The same row as the planning calendar's day list (.sw-plancal__row) — time, tag, squad — so the
   schedule reads the same whether it is reached from the plan above or the week below. The day is
   the only thing that opens; a session row goes to the session. */
.sw-sess .sw-chip,
.sw-plancal__row .sw-chip { text-transform: uppercase; letter-spacing: .05em; font-size: .68rem; flex-shrink: 0; }
.sw-sess--past { opacity: .75; }
/* The squad takes the room; anything after it is secondary and gives way first. */
.sw-sess .sw-plancal__name { flex: 0 1 auto; text-transform: none; letter-spacing: 0; }
.sw-sess__title { font-size: .85rem; color: var(--sw-text-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⚠ The session page's own heading is also .sw-sess__title (bold, 1.1rem, pushed down .5rem), and
   in a row that made the title sit low and heavy beside the squad (Gideon, 2026-09-28). */
.sw-plancal__row .sw-sess__title { font-weight: 400; margin-top: 0; }
/* The workout's name, on the right just before its distance — its first line when it was never
   named. Gives way before the distance and counts do. */
.sw-sess__set {
  flex: 0 1 auto; min-width: 0; max-width: 16rem;
  font-size: .8rem; font-weight: 600; color: var(--sw-text-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Trails the squad as quieter text and takes the slack, so the cancelled chip stays at the end. */
.sw-sess__venue { flex: 1; min-width: 0; font-size: .8rem; color: var(--sw-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The Standard's second tile, when it is about a swimmer rather than about the scale. Marked in
   the primary rather than the accent so it reads as "this is you", not as another anchor. */
.sw-std__anchor--you { border-left-color: var(--sw-primary); background: var(--sw-primary-tint); }
.sw-std__anchor--you .sw-std__anchorpct span { color: var(--sw-primary-strong); }

/* ── Progression, off the clock ────────────────────────────────────
   One event at a time, because a 50 free and a 400 IM cannot share an axis and pretending they can
   is how a chart lies. The window buttons reuse the library's pill so the app has one of them. */
.sw-prog { margin-bottom: 1rem; }
.sw-prog__head { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap; }
.sw-prog__windows { display: flex; gap: .35rem; }
.sw-prog__event { margin: .5rem 0 .6rem; max-width: 22rem; }
.sw-prog__read { font-size: .85rem; color: var(--sw-muted); margin-top: .4rem; }
.sw-prog__read b { color: var(--sw-navy); }
.sw-prog__up { color: var(--sw-success); font-weight: 600; }
.sw-prog__down { color: var(--sw-muted); }

/* ── Today's schedule — the size tag ───────────────────────────────
   A session that has a workout carries its length on the left edge, on the workout library's three
   bands and in its colours (§14), so "navy is a long one" means the same thing in both places.
   Declared after .sw-sess--live deliberately: a live session keeps its green ring on three sides
   and still says how far it is. A session with no workout, or one whose distance the parser could
   not read, gets no tag rather than a fourth colour that would have to be explained. */
.sw-sess--short  { border-left: 4px solid var(--sw-muted-2); }   /* under 2.5 km — slate */
.sw-sess--middle { border-left: 4px solid var(--sw-primary); }   /* 2.5–4.5 km — sky */
.sw-sess--long   { border-left: 4px solid var(--sw-sunflower); } /* over 4.5 km — sunflower */

/* The two day-part tags that are not the primary sky. Solid rather than tinted: a tint of yellow
   reads as cream and stops being the colour that was asked for. Navy text on the sunflower, white
   on the navy — each is the legible pairing for its ground. */
.sw-chip--sunflower { background: var(--sw-sunflower-tint); color: var(--sw-sunflower-ink); }
.sw-chip--navy-lt   { background: var(--sw-navy-lt-tint); color: var(--sw-navy-lt); }

/* A session that has been moved. Amber rather than the cancelled red: it is still happening, and
   a swimmer who reads red for "moved" stops reading red for "off". */
.sw-chip--moved { background: var(--sw-accent-tint); color: var(--sw-warning); }
/* A slot swimmers pick one of (SessionChoices) — sky, since nothing is wrong with it. */
.sw-chip--choice { background: var(--sw-primary-tint); color: var(--sw-primary); }
/* The figure behind the colour. Quiet, tabular so a column of them lines up, and never the thing
   that gives way when the row is squeezed — the venue is. */
.sw-sess__km {
  font-size: .78rem; font-weight: 700; color: var(--sw-muted);
  font-variant-numeric: tabular-nums; flex-shrink: 0;
}
.sw-sess__athletes { flex-shrink: 0; font-size: .78rem; font-weight: 600; }
/* Who is here, beside how many could be — green, so the two numbers never read as one. */
.sw-sess__present {
  display: inline-flex; align-items: center; gap: .3rem; flex-shrink: 0;
  font-size: .78rem; font-weight: 700; color: var(--sw-success);
  font-variant-numeric: tabular-nums;
}

/* ── Manual event add (MeetView) — a small labelled grid, the same idea as .sw-sheet__cols but
   for a form with more fields than a sheet holds at once. */
.sw-form-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: .6rem .8rem; align-items: end;
}
.sw-form-grid label { display: flex; flex-direction: column; gap: .25rem; font-size: .82rem; color: var(--sw-text-2); }
.sw-form-grid label:has(input[type="checkbox"]) { flex-direction: row; align-items: center; gap: .4rem; }

/* ── The file-picker label used by every import (meet events, HY3 results, create-from-zip) ──
   A real Meet Manager export's own filename can run past 60 characters — "Meet Events-NTS Senior
   Short Course Champs 2026-28Aug2026-001.hyv" is a real one — and .btn has no width or overflow
   rule of its own, so that text ran on past the label and sat on top of whatever followed it.
   Fixed to a real button box with its own width ceiling; the name truncates with an ellipsis
   rather than overflowing, and the full name is still there on hover. */
.sw-filepick { cursor: pointer; display: inline-flex; align-items: center; max-width: 100%; }
.sw-filepick__name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: min(420px, 100%); display: inline-block; vertical-align: bottom;
}

/* ── The meet-create dropzone ──────────────────────────────────────
   One real <input type=file>, absolutely positioned to cover the whole box and made invisible —
   not a custom drop handler. Dropping a file anywhere on the box lands on that input the way a
   browser already handles a drop onto a file input; the same input is what a tap anywhere in the
   box opens, which is the only path a phone or tablet has. The visible "Choose file" pill is purely
   decorative — pointer-events are off on the whole body so every click and drop reaches the real
   input underneath rather than the pill itself. */
.sw-dropzone {
  position: relative;
  border: 2px dashed var(--sw-border);
  border-radius: var(--sw-radius);
  background: var(--sw-surface-sunken);
  padding: 1.6rem 1rem;
  text-align: center;
  transition: border-color .12s ease, background .12s ease;
}
.sw-dropzone--over { border-color: var(--sw-primary); background: var(--sw-primary-tint); }
.sw-dropzone--picked { border-style: solid; border-color: var(--sw-success); }
.sw-dropzone__input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}
.sw-dropzone__body {
  pointer-events: none; /* the real input above receives every click and drop */
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  color: var(--sw-muted);
}
.sw-dropzone__title {
  font-weight: 700; color: var(--sw-navy);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sw-dropzone__sub { font-size: .82rem; }
.sw-dropzone__btn { margin-top: .3rem; pointer-events: none; }

/* ── Gala days on the calendar ─────────────────────────────────────
   A training day is tinted; a gala day gets the accent underline instead, so the two read apart at
   a glance and a day carrying both still shows both. Sunflower rather than the primary, because
   the primary already means "there is training on". */
.sw-cal__day--gala { box-shadow: inset 0 -3px 0 var(--sw-sunflower); font-weight: 800; }
.sw-cal__day--gala.sw-cal__day--on { box-shadow: inset 0 -3px 0 var(--sw-sunflower); }
.sw-sched__card--gala { border-left: 4px solid var(--sw-sunflower); }

/* ── Club setup wizard and the contract gate (CLAUDE.md §20) ─────────────────────── */
.sw-wizard { display: flex; flex-direction: column; gap: 1rem; }
.sw-wizard__bar { height: 6px; border-radius: 999px; background: var(--sw-surface-sunken); overflow: hidden; }
.sw-wizard__fill { height: 100%; background: var(--sw-primary); border-radius: 999px; transition: width .3s ease; }
.sw-wizard__steps { display: flex; gap: .4rem; overflow-x: auto; padding-bottom: .25rem; scrollbar-width: none; }
.sw-wizard__steps::-webkit-scrollbar { display: none; }
.sw-wizard__step { flex: 0 0 auto; display: inline-flex; align-items: center; gap: .45rem; padding: .4rem .7rem;
  border: 1px solid var(--sw-border); border-radius: 999px; background: var(--sw-surface); color: var(--sw-text-2);
  font: inherit; font-size: .85rem; cursor: pointer; }
.sw-wizard__step--current { border-color: var(--sw-primary); color: var(--sw-primary); background: var(--sw-primary-tint); }
.sw-wizard__step--done .sw-wizard__num { background: var(--sw-success); color: #fff; }
.sw-wizard__num { display: inline-flex; align-items: center; justify-content: center; width: 1.4rem; height: 1.4rem;
  border-radius: 999px; background: var(--sw-surface-sunken); color: var(--sw-text); font-size: .75rem; font-weight: 600; }
.sw-wizard__missing { margin: .5rem 0 0; padding-left: 1.2rem; color: var(--sw-danger); font-size: .9rem; }
.sw-wizard__terms { white-space: pre-wrap; font: inherit; font-size: .9rem; max-height: 14rem; overflow: auto;
  padding: .75rem; border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-surface-sunken); }
.sw-wizard__list { display: flex; flex-direction: column; gap: .4rem; margin: .5rem 0; }
.sw-wizard__row { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .5rem .75rem;
  border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-surface); font-size: .9rem; }
.sw-wizard__row small { color: var(--sw-muted); }
.sw-ok { color: var(--sw-success); font-size: .9rem; margin: .5rem 0; }
.sw-gate { position: fixed; inset: 0; z-index: 1000; background: rgba(10, 25, 47, .6); display: flex; align-items: center;
  justify-content: center; padding: 1rem; }
.sw-gate__card { width: min(560px, 100%); max-height: 90vh; overflow: auto; background: var(--sw-surface); border-radius: 16px;
  padding: 1.25rem; box-shadow: 0 20px 60px rgba(0,0,0,.3); }
.sw-gate__title { margin: .25rem 0 .5rem; }
.sw-gate__body { white-space: pre-wrap; font: inherit; font-size: .9rem; max-height: 40vh; overflow: auto; padding: .75rem;
  border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-surface-sunken); }
.sw-gate__consent { display: flex; gap: .6rem; align-items: flex-start; margin: .5rem 0; font-size: .9rem; }

/* Signup (CLAUDE.md §21): the club link with its QR code, and the pending list. */
.sw-signup-link { display: flex; gap: 1rem; align-items: flex-start; flex-wrap: wrap; }
.sw-signup-link__qr { width: 180px; flex: 0 0 auto; }
.sw-signup-link__qr svg { width: 100%; height: auto; display: block; border: 1px solid var(--sw-border); border-radius: 12px; }
.sw-signup-link__text { flex: 1 1 220px; min-width: 0; }
.sw-signup-link__text .sw-invite-active__link { word-break: break-all; }
.sw-signup-row__actions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }

/* Billing (CLAUDE.md §22): the lines under an invoice row. */
.sw-billing__lines { margin: .2rem 0 .8rem 1rem; padding-left: .8rem; border-left: 2px solid var(--sw-border); }

/* ── Notifications (CLAUDE.md §23) ──
   The inbox reuses the dashboard's attention rows, so only three things are new: an unread row
   carries the surface a little brighter and its title heavier, a chip can be shown as chosen, and
   the mute switches sit inline with their words. A read row is deliberately plain: the list is
   meant to empty itself visually as a person works down it. */
button.sw-attn { width: 100%; text-align: left; cursor: pointer; font: inherit; }
button.sw-attn:hover:not(:disabled) { background: var(--sw-surface-sunken); }
.sw-attn--unread { background: var(--sw-surface); box-shadow: 0 1px 2px rgba(10, 25, 47, .06); }
.sw-attn--unread .sw-attn__title { font-weight: 800; }
.sw-attn:not(.sw-attn--unread) .sw-attn__title { font-weight: 600; color: var(--sw-text-2); }

.sw-chip--on { background: var(--sw-primary); color: #fff; border-color: var(--sw-primary); }
.sw-chip--accent { background: var(--sw-accent-tint); color: #7c4a03; border-color: var(--sw-accent); }
.sw-inline-label { display: inline-flex; align-items: center; gap: .3rem; font-size: .8rem; color: var(--sw-text-2); }
.sw-inline-label input { accent-color: var(--sw-primary); }
/* The composer's message box and its preview: a message is written in paragraphs and must be read
   back in them, so the preview keeps the line breaks the writer typed. */
.sw-field textarea.sw-composer__body, textarea.sw-composer__body { width: 100%; border-radius: 12px; min-height: 8rem; }
.sw-composer__preview { white-space: pre-wrap; }

/* The inbox bell in the top bar, and the count on it. The badge sits on the corner of the icon and
   is capped at 99+, so a long-neglected inbox cannot widen the bar (§12 item 10's lesson). */
.sw-topbar__bell { position: relative; display: inline-flex; align-items: center; color: var(--sw-text-2); flex-shrink: 0; }
.sw-topbar__bell:hover { color: var(--sw-primary); }
.sw-topbar__badge {
  position: absolute; top: -.35rem; right: -.45rem;
  min-width: 1.05rem; padding: 0 .2rem;
  background: var(--sw-danger); color: #fff;
  border-radius: 999px; font-size: .62rem; font-weight: 800; line-height: 1.05rem; text-align: center;
}

/* ── Settings (CLAUDE.md §24) ──
   A settings row is words on the left and one control on the right, and it saves itself: there is
   no Save button, because a screen full of pending edits is how a club ends up not knowing what
   its own settings are. A change still waiting out its notice period says so in the row. */
.sw-setting { display: flex; align-items: flex-start; gap: 1rem; padding: .7rem 0; border-bottom: 1px solid var(--sw-border); }
.sw-setting:last-child { border-bottom: 0; }
.sw-setting__words { flex: 1; min-width: 0; }
.sw-setting__label { font-weight: 700; color: var(--sw-navy); }
.sw-setting__help { font-size: .8rem; color: var(--sw-muted); margin-top: .1rem; }
.sw-setting__meta { font-size: .72rem; color: var(--sw-muted-2); margin-top: .2rem; display: block; }
.sw-setting__pending { font-size: .78rem; color: #7c4a03; background: var(--sw-accent-tint); border-radius: 8px; padding: .3rem .5rem; margin-top: .3rem; }
.sw-setting__control { flex-shrink: 0; width: 13rem; max-width: 45%; text-align: right; }
.sw-setting__control .sw-control { width: 100%; }
@media (max-width: 560px) {
  .sw-setting { flex-direction: column; gap: .35rem; }
  .sw-setting__control { width: 100%; max-width: 100%; text-align: left; }
}

/* ── The inbox as a journal (Gideon, 2026-09-29, after Cyberpunk 2077's) ─────────────────────
   Tabs down the side, the messages beside them, the one picked read in full on the right. On a
   phone the list and the message take turns: .sw-journal--reading shows only the message. */
.sw-journal__push {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap;
  padding: .7rem 1rem; margin-bottom: 1rem;
  background: var(--sw-primary-tint); color: var(--sw-navy); border-radius: var(--sw-radius-sm); font-size: .9rem;
}
.sw-journal {
  display: grid; grid-template-columns: 11rem minmax(0, 1fr) minmax(0, 1.35fr);
  gap: 1rem; align-items: start;
}
.sw-journal__tabs { display: flex; flex-direction: column; gap: .2rem; position: sticky; top: 1rem; }
.sw-journal__tab {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  width: 100%; padding: .55rem .75rem; border: 0; border-left: 3px solid transparent; border-radius: 0 10px 10px 0;
  background: transparent; font: inherit; font-size: .78rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--sw-text-2); cursor: pointer; text-align: left;
}
.sw-journal__tab:hover { background: var(--sw-surface-sunken); }
.sw-journal__tab.is-on { background: var(--sw-surface); border-left-color: var(--sw-primary); color: var(--sw-primary); box-shadow: var(--sw-shadow-sm); }
.sw-journal__tab b {
  min-width: 1.4rem; padding: .05rem .4rem; border-radius: var(--sw-radius-pill);
  background: var(--sw-primary); color: #fff; font-size: .7rem; letter-spacing: 0; text-align: center;
}
.sw-journal__list, .sw-journal__read {
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius);
  box-shadow: var(--sw-shadow-sm);
}
.sw-journal__list { overflow: hidden; }
.sw-journal__row {
  display: grid; grid-template-columns: .6rem minmax(0, 1fr) auto; gap: .65rem; align-items: start;
  width: 100%; padding: .8rem 1rem; border: 0; border-bottom: 1px solid var(--sw-border);
  border-left: 3px solid var(--sw-muted-2); background: transparent; font: inherit; text-align: left;
  color: var(--sw-text); cursor: pointer;
}
.sw-journal__row:last-child { border-bottom: 0; }
.sw-journal__row:hover { background: var(--sw-surface-sunken); }
.sw-journal__row--info { border-left-color: var(--sw-primary); }
.sw-journal__row--danger { border-left-color: var(--sw-danger); }
.sw-journal__row--warning { border-left-color: var(--sw-border); }
.sw-journal__row.is-on { background: var(--sw-primary-tint); }
.sw-journal__dot { width: .5rem; height: .5rem; margin-top: .4rem; border-radius: 50%; background: transparent; }
.sw-journal__row.is-unread .sw-journal__dot { background: var(--sw-primary); }
.sw-journal__row-body { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.sw-journal__row-title { font-weight: 500; color: var(--sw-navy); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-journal__row.is-unread .sw-journal__row-title { font-weight: 700; }
.sw-journal__row-meta { display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; font-size: .8rem; color: var(--sw-muted); }
.sw-journal__row-meta .sw-chip { padding: 0 .45rem; font-size: .7rem; }
.sw-journal__row-when { font-size: .75rem; color: var(--sw-muted-2); white-space: nowrap; padding-top: .15rem; }
.sw-journal__read { padding: 1.5rem 1.6rem; position: sticky; top: 1rem; min-height: 14rem; }
.sw-journal__read--preview { position: static; min-height: 0; margin-top: 1rem; box-shadow: none; }
.sw-journal__back {
  display: none; align-items: center; gap: .25rem; margin: -.4rem 0 .8rem -.4rem; padding: .3rem .4rem;
  border: 0; background: transparent; font: inherit; font-size: .85rem; font-weight: 600; color: var(--sw-primary); cursor: pointer;
}
.sw-journal__kicker {
  display: flex; align-items: center; gap: .5rem;
  font-size: .72rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--sw-primary);
}
.sw-journal__subject { margin: .35rem 0 .3rem; font-size: 1.35rem; font-weight: 700; line-height: 1.3; color: var(--sw-navy); }
.sw-journal__byline { padding-bottom: .9rem; margin-bottom: 1rem; border-bottom: 1px solid var(--sw-border); font-size: .85rem; color: var(--sw-muted); }
.sw-journal__text { white-space: pre-line; line-height: 1.6; color: var(--sw-text); overflow-wrap: anywhere; }
.sw-journal__tags {
  display: flex; flex-wrap: wrap; gap: .5rem;
  margin-top: 1.25rem; padding-top: 1rem; border-top: 1px dashed var(--sw-border);
}
.sw-journal__tag {
  display: inline-flex; align-items: center; gap: .4rem; max-width: 100%;
  padding: .4rem .75rem; border: 1px solid var(--sw-border); border-radius: 10px;
  background: var(--sw-surface-sunken); color: var(--sw-text); font-size: .85rem; text-decoration: none;
}
.sw-journal__tag span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-journal__tag .sw-icon { color: var(--sw-primary); flex-shrink: 0; }
a.sw-journal__tag:hover { background: var(--sw-primary-tint); border-color: var(--sw-primary); color: var(--sw-primary); }
.sw-journal__go { margin-top: 1.25rem; }
.sw-journal__go .btn { display: inline-flex; align-items: center; gap: .3rem; }
.sw-journal__empty { padding: 2rem 1rem; text-align: center; color: var(--sw-muted); font-size: .9rem; }
.sw-composer__link { align-items: end; }

@media (max-width: 900px) {
  .sw-journal { grid-template-columns: minmax(0, 1fr); }
  .sw-journal__tabs { flex-direction: row; overflow-x: auto; position: static; gap: .35rem; padding-bottom: .15rem; }
  .sw-journal__tab { width: auto; flex-shrink: 0; border-left: 0; border-radius: var(--sw-radius-pill); border: 1px solid var(--sw-border); background: var(--sw-surface); }
  .sw-journal__tab.is-on { border-color: var(--sw-primary); }
  .sw-journal__read { display: none; position: static; padding: 1.1rem 1rem; }
  .sw-journal__read--preview { display: block; }
  .sw-journal--reading .sw-journal__tabs, .sw-journal--reading .sw-journal__list { display: none; }
  .sw-journal--reading .sw-journal__read { display: block; }
  .sw-journal__back { display: inline-flex; }
}

/* The settings hub: its groups side by side where there is room, so none hides below the fold. */
.sw-settings-hub { display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); gap: 1rem 1.25rem; align-items: start; }
.sw-settings-hub__group { display: flex; flex-direction: column; gap: .5rem; min-width: 0; }

/* A best-time row with swims behind it opens its progression chart underneath (Gideon, 2026-10-01). */
.sw-pbrow--opens { cursor: pointer; }
.sw-pbrow--opens:hover, .sw-pbrow--open { background: var(--sw-surface-sunken); }
.sw-pbrow--opens .sw-pbrow__event .sw-icon { color: var(--sw-muted-2); vertical-align: -2px; transition: transform .15s; }
.sw-pbrow--open .sw-pbrow__event .sw-icon { transform: rotate(90deg); }
.sw-prog--docked { margin: 0; padding: .6rem 1rem 1rem; border-top: 1px solid var(--sw-border); background: var(--sw-surface-sunken); }

/* The time chart's hover / tap label (Gideon, 2026-10-01). The hit circle is invisible and wide. */
.sw-chart__hit { fill: transparent; cursor: pointer; }
.sw-chart__dot--on { fill: var(--sw-navy); }
.sw-chart__tip rect { fill: var(--sw-navy); }
.sw-chart__tip text { fill: #fff; font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* Phone: the schedule row now says "expected" and "here" beside the two numbers, which no longer
   fit on one line — let the row wrap — and a two-column sheet (Messages' link and channels) stacks. */
@media (max-width: 520px) {
  .sw-plancal__row.sw-sess { flex-wrap: wrap; row-gap: .25rem; }
  .sw-sheet__cols { grid-template-columns: 1fr; }
}

/* Parent home — several children (Roadmap Phase 6) */
.sw-switcher { margin-top: 0; }
.sw-weekday { padding: .8rem 1rem; }
.sw-weekday__name { font-weight: 700; color: var(--sw-navy); margin-bottom: .3rem; }
.sw-weekrow { display: flex; align-items: center; gap: .8rem; padding: .45rem 0; border-top: 1px solid var(--sw-border); text-decoration: none; color: var(--sw-text); }
.sw-weekrow:first-of-type { border-top: 0; }
.sw-weekrow__time { font-weight: 700; color: var(--sw-primary); min-width: 3rem; }
.sw-weekrow__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-weekrow__title { font-weight: 600; }
.sw-weekrow__sub { font-size: .85rem; color: var(--sw-muted); }
.sw-weekrow--off .sw-weekrow__title { text-decoration: line-through; color: var(--sw-muted); }
.sw-bests { padding: .8rem 1rem; }
.sw-bests__name { font-weight: 700; color: var(--sw-navy); text-decoration: none; display: block; margin-bottom: .3rem; }
.sw-bests__row { display: flex; justify-content: space-between; gap: .6rem; padding: .3rem 0; border-top: 1px solid var(--sw-border); font-size: .92rem; }
.sw-bests__row b { color: var(--sw-primary); }


/* ═══════════════════════════════════════════════════════════════
   DESKTOP SIDE MENU (Phase 8, locked in 2026-10-08)
   Coaches and admins only. Wider than 900px the navy side menu replaces the top bar; narrower, the top bar
   and the bottom tabs stay exactly as they were. Every row is one height, so the
   sliding highlight is placed by index (SwTopBar.SideList) with no script.
   ═══════════════════════════════════════════════════════════════ */

:root { --sw-side-w: 248px; --sw-side-row: 38px; --sw-side-gap: 2px; --sw-side-pitch: calc(var(--sw-side-row) + var(--sw-side-gap)); }

.sw-side { display: none; }

@media (min-width: 901px) {
  body:has(.sw-side) :is(.sw-topbar, .sw-drawer, .sw-drawer-backdrop) { display: none !important; }
  .sw-side ~ .sw-main { margin-left: var(--sw-side-w); }
  .sw-side ~ .sw-main .sw-page { max-width: 1240px; padding: 1.5rem 2rem 2.5rem; }

  .sw-side {
    position: fixed; inset: 0 auto 0 0; width: var(--sw-side-w); z-index: 2000;
    display: flex; flex-direction: column; gap: 4px; padding: 18px 12px 12px;
    background: linear-gradient(180deg, var(--sw-navy) 0%, #10264a 100%);
    color: #cbd5e1; overflow: hidden; box-sizing: border-box;
  }
}

.sw-side__waves { position: absolute; left: -20px; right: -20px; bottom: 50px; height: 120px; width: calc(100% + 40px); opacity: .07; pointer-events: none; }
.sw-side__brand { display: flex; align-items: center; gap: 10px; padding: 2px 8px 16px; color: #fff; font-weight: 700; font-size: 17px; text-decoration: none; }
.sw-side__brand:hover { color: #fff; }

.sw-side__club { all: unset; cursor: pointer; display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 12px; background: rgba(255,255,255,.07); margin-bottom: 10px; transition: background .15s ease; }
.sw-side__club:hover { background: rgba(255,255,255,.12); }
.sw-side__club:focus-visible { outline: 2px solid var(--sw-primary-tint); }
.sw-side__crest { flex: 0 0 30px; width: 30px; height: 30px; border-radius: 50%; background: #fff; color: var(--sw-navy); display: grid; place-items: center; font-weight: 700; font-size: 11px; }
.sw-side__clubtext { min-width: 0; display: flex; flex-direction: column; }
.sw-side__clubtext b { color: #fff; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-side__clubtext span { font-size: 12px; color: var(--sw-muted-2); }

.sw-side__switch { display: flex; flex-direction: column; gap: 4px; padding: 0 4px 10px; animation: sw-side-in .2s ease; }
.sw-side__switch label { font-size: 11px; font-weight: 600; color: var(--sw-muted-2); text-transform: uppercase; letter-spacing: .05em; margin-top: 4px; }
.sw-side__switch select { width: 100%; }
.sw-side__switch .sw-side__check { display: flex; align-items: center; gap: 6px; text-transform: none; letter-spacing: 0; font-size: 12px; }

.sw-side__scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.15) transparent; margin: 0 -4px; padding: 0 4px; position: relative; }
.sw-side__label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--sw-muted-2); padding: 14px 12px 6px; }
.sw-side__sep { height: 1px; background: rgba(255,255,255,.1); margin: 12px 4px; }

.sw-side__list { position: relative; display: flex; flex-direction: column; gap: var(--sw-side-gap); }
.sw-side__pill { position: absolute; left: 0; right: 0; top: 0; height: var(--sw-side-row); border-radius: 10px; background: var(--sw-primary); box-shadow: 0 4px 14px rgba(3,105,161,.45); transition: transform .32s cubic-bezier(.2,.8,.2,1), opacity .2s ease; pointer-events: none; }
.sw-side__link { position: relative; display: flex; align-items: center; gap: 10px; height: var(--sw-side-row); padding: 0 12px; border-radius: 10px; color: #cbd5e1; font-size: 14px; font-weight: 500; text-decoration: none; box-sizing: border-box; transition: background .15s ease, color .15s ease; }
.sw-side__link:hover { background: rgba(255,255,255,.07); color: #fff; }
.sw-side__link--active, .sw-side__link--active:hover { color: #fff; font-weight: 600; background: transparent; }
.sw-side__link:focus-visible { outline: 2px solid var(--sw-primary-tint); outline-offset: -2px; }
.sw-side__link svg { flex: 0 0 auto; transition: transform .2s ease; }
.sw-side__link:hover svg { transform: scale(1.12); }
.sw-side__badge { margin-left: auto; font-size: 11px; font-weight: 700; background: var(--sw-accent); color: var(--sw-navy); border-radius: 999px; padding: 1px 7px; }

.sw-side__me { display: flex; align-items: center; gap: 10px; padding: 10px 8px 2px; margin-top: 6px; border-top: 1px solid rgba(255,255,255,.08); font-size: 13px; }
.sw-side__av { flex: 0 0 28px; width: 28px; height: 28px; border-radius: 50%; background: var(--sw-navy-lt); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 11px; }
.sw-side__name { flex: 1; min-width: 0; color: #cbd5e1; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-side__name:hover { color: #fff; }
.sw-side__out { all: unset; cursor: pointer; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; color: var(--sw-muted-2); }
.sw-side__out:hover { background: rgba(255,255,255,.08); color: #fff; }

@keyframes sw-side-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes sw-side-shine { 0%, 70% { background-position: 200% 0; } 100% { background-position: -100% 0; } }
@keyframes sw-side-swell { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-14px); } }

@media (prefers-reduced-motion: no-preference) {
  .sw-side__pill { background-image: linear-gradient(110deg, transparent 30%, rgba(255,255,255,.22) 50%, transparent 70%); background-size: 200% 100%; animation: sw-side-shine 6s ease-in-out infinite; }
  .sw-side__waves path { animation: sw-side-swell 9s ease-in-out infinite; }
  .sw-side__waves path + path { animation-duration: 12s; animation-direction: reverse; }
}
@media (prefers-reduced-motion: reduce) {
  .sw-side__pill, .sw-side__link svg { transition: none; }
}


/* ═══════════════════════════════════════════════════════════════
   OVERVIEW (Phase 8 part 2, locked in 2026-10-08 from the prototype)
   Slim attention bars, today's sessions as bars, Coming up beside per-squad charts,
   Money last. Movement is gentle and stops under reduced motion.
   ═══════════════════════════════════════════════════════════════ */

.sw-home__section { display: inline-flex; align-items: center; gap: .4rem; }
.sw-strike { text-decoration: line-through; opacity: .7; }

/* Header */
.sw-ov-hero { position: relative; display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: .75rem; padding: .25rem 0 1.1rem; margin-bottom: .5rem; overflow: hidden; }
.sw-ov-hero h1 { margin: .1rem 0 0; }
.sw-ov-hero__eyebrow { font-size: .8rem; font-weight: 600; color: var(--sw-muted); }
.sw-ov-hero__btns { display: flex; gap: .5rem; flex-wrap: wrap; position: relative; }
.sw-ov-hero__btns .btn { display: inline-flex; align-items: center; gap: .35rem; }
.sw-ov-hero__water { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 18px; pointer-events: none; }
.sw-ov-hero__water path { fill: var(--sw-primary); opacity: .07; }
.sw-ov-hero__water path + path { opacity: .05; }

/* Shared slim bar list */
.sw-abars { display: flex; flex-direction: column; gap: 0; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm); overflow: hidden; }

/* Needs your attention */
.sw-abars .sw-attn { border: 0; border-left: 3px solid transparent; border-radius: 0; box-shadow: none; margin: 0; padding: .55rem 1rem; min-height: 50px; display: flex; align-items: center; gap: .75rem; background: transparent; }
.sw-abars .sw-attn + .sw-attn, .sw-abars .sw-attn-rows + .sw-attn { border-top: 1px solid var(--sw-surface-sunken); }
.sw-abars .sw-attn:hover { background: #f8fbff; }
.sw-abars .sw-attn--open { background: var(--sw-primary-tint); }
.sw-abars .sw-attn__body { display: flex; align-items: baseline; gap: .6rem; overflow: hidden; }
.sw-abars .sw-attn__title { white-space: nowrap; font-size: .95rem; flex-wrap: nowrap; }
.sw-abars .sw-attn__detail { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-abar__ic { flex: 0 0 30px; width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-abars .sw-attn .sw-abar__ic .sw-icon, .sw-abar__ic svg { color: inherit; }
.sw-attn--warning .sw-abar__ic { background: var(--sw-accent-tint); color: var(--sw-warning); }
.sw-attn--danger .sw-abar__ic { background: var(--sw-danger-tint); color: var(--sw-danger); }
.sw-abar__n { flex: 0 0 auto; min-width: 3.2rem; font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--sw-navy); }
.sw-attn--danger .sw-abar__n { color: var(--sw-danger); }
.sw-attn--warning .sw-abar__n { color: var(--sw-warning); }
.sw-abars .sw-attn-rows { border: 0; border-radius: 0; margin: 0; padding: .25rem 1rem .9rem 3.6rem; background: linear-gradient(180deg, var(--sw-primary-tint), var(--sw-surface) 40px); }
@media (max-width: 700px) {
  .sw-abars .sw-attn__body { flex-direction: column; gap: 0; align-items: flex-start; }
  .sw-abar__n { min-width: 2.4rem; }
  .sw-abars .sw-attn-rows { padding-left: 1rem; }
}

/* Today's schedule */
.sw-sbar-item + .sw-sbar-item { border-top: 1px solid var(--sw-surface-sunken); }
.sw-sbar { all: unset; box-sizing: border-box; cursor: pointer; width: 100%; display: flex; align-items: center; gap: .75rem; padding: .55rem 1rem; min-height: 54px; }
.sw-sbar:hover { background: #f8fbff; }
.sw-sbar:focus-visible { outline: 2px solid var(--sw-primary); outline-offset: -2px; }
.sw-sbar-item--open .sw-sbar { background: var(--sw-primary-tint); }
.sw-sbar__time { flex: 0 0 3.3rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--sw-navy); }
.sw-sbar__state { flex: 0 0 auto; font-size: .72rem; font-weight: 700; padding: .15rem .55rem; border-radius: 999px; background: var(--sw-surface-sunken); color: var(--sw-muted); min-width: 3.6rem; text-align: center; }
.sw-sbar--live .sw-sbar__state { background: var(--sw-success-tint); color: var(--sw-success); }
.sw-sbar--next .sw-sbar__state { background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-sbar--done .sw-sbar { opacity: .6; }
.sw-sbar--live .sw-sbar { background: linear-gradient(90deg, var(--sw-success-tint) var(--p), transparent var(--p)); }
.sw-sbar__who { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-sbar__who b { font-size: .92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--sw-navy); }
/* The family's Overview (SwParentHome). Each child wears one colour (--kid) on every piece of the page. */
.sw-kidav { width: 40px; height: 40px; border-radius: 999px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: .85rem; color: #fff; background: var(--kid, var(--sw-primary)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--kid, var(--sw-primary)) 22%, transparent); }
.sw-kidav--xs { width: 22px; height: 22px; font-size: .6rem; box-shadow: none; }
.sw-famchips .sw-check { padding: .25rem .75rem .25rem .3rem; }
.sw-famchips__stack { display: inline-flex; }
.sw-famchips__stack .sw-kidav + .sw-kidav { margin-left: -7px; }
.sw-famchips__stack .sw-kidav { border: 2px solid var(--sw-surface); }
.sw-child { border-top: 3px solid var(--kid, transparent); }

/* The week strip: seven days, today first, a dot per session in its child's colour; the chosen day lifts. */
.sw-weekstrip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .45rem; }
.sw-wday { font: inherit; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: .15rem; padding: .55rem .2rem .5rem; border-radius: 14px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2); transition: transform .15s ease, box-shadow .15s ease, background .15s ease; min-width: 0; }
.sw-wday:hover { transform: translateY(-2px); box-shadow: var(--sw-shadow-sm); }
.sw-wday:focus-visible { outline: 2px solid var(--sw-primary); outline-offset: 2px; }
.sw-wday__name { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--sw-muted); }
.sw-wday__num { font-size: 1.25rem; font-weight: 700; color: var(--sw-navy); font-variant-numeric: tabular-nums; line-height: 1.1; }
.sw-wday__dots { display: flex; gap: 3px; min-height: 8px; flex-wrap: wrap; justify-content: center; }
.sw-wday__dot { width: 7px; height: 7px; border-radius: 999px; background: var(--kid); }
.sw-wday__dot--off { background: transparent; box-shadow: inset 0 0 0 1.5px var(--kid); }
.sw-wday--rest { background: var(--sw-surface-sunken); }
.sw-wday--on { background: var(--sw-navy); border-color: var(--sw-navy); box-shadow: 0 6px 16px rgba(10, 25, 47, .18); transform: translateY(-2px); }
.sw-wday--on .sw-wday__name { color: rgba(255,255,255,.7); }
.sw-wday--on .sw-wday__num { color: #fff; }
.sw-wday--on .sw-wday__dot--off { box-shadow: inset 0 0 0 1.5px #fff; }
@media (max-width: 420px) { .sw-weekstrip { gap: .25rem; } .sw-wday__num { font-size: 1.05rem; } }

/* A gala bar that opens in place to each child's standing. */
.sw-upmeet--btn { width: 100%; font: inherit; text-align: left; cursor: pointer; transition: box-shadow .15s ease; }
.sw-upmeet--btn:hover { box-shadow: var(--sw-shadow-sm); }
.sw-upmeet--open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; background: var(--sw-primary-tint); }
.sw-upmeet-list .sw-attn-row { align-items: center; gap: .6rem; }
.sw-bests__name { display: flex; align-items: center; gap: .45rem; }
.sw-bests__row--new { background: linear-gradient(90deg, var(--sw-success-tint), transparent 70%); margin: 0 -.5rem; padding-left: .5rem; padding-right: .5rem; border-radius: 6px; }
.sw-bests__row--new .sw-chip { margin-left: .4rem; }
@media (prefers-reduced-motion: no-preference) {
  .sw-wday { animation: sw-ov-rise .35s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i, 0) * 35ms); }
  .sw-wday--on .sw-wday__dot { animation: sw-ov-ripple-dot 2.4s ease-in-out infinite; }
  .sw-child, .sw-bests, .sw-upmeet { animation: sw-ov-rise .4s cubic-bezier(.2,.8,.2,1) both; }
}
/* The family's swimmer page (AthleteDetail, Tabbed): tiles that draw their figure and open their part. */
.sw-ptiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .6rem; }
.sw-ptile { font: inherit; cursor: pointer; text-align: left; display: flex; flex-direction: column; gap: .35rem; padding: .8rem .9rem; border-radius: 16px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text); min-width: 0; transition: transform .15s ease, box-shadow .15s ease; }
.sw-ptile:hover { transform: translateY(-2px); box-shadow: var(--sw-shadow-sm); }
.sw-ptile:focus-visible { outline: 2px solid var(--sw-primary); outline-offset: 2px; }
.sw-ptile__label { display: inline-flex; align-items: center; gap: .35rem; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--sw-muted); }
.sw-ptile__big { font-size: 1.7rem; font-weight: 800; color: var(--sw-navy); line-height: 1.1; font-variant-numeric: tabular-nums; min-height: 56px; display: flex; align-items: center; }
.sw-ptile__sub { font-size: .78rem; color: var(--sw-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-ptile--on { background: var(--sw-navy); border-color: var(--sw-navy); box-shadow: 0 8px 20px rgba(10, 25, 47, .2); transform: translateY(-2px); }
.sw-ptile--on .sw-ptile__label, .sw-ptile--on .sw-ptile__sub { color: rgba(255,255,255,.72); }
.sw-ptile--on .sw-ptile__big { color: #fff; }
.sw-ptile__faces { display: flex; min-height: 56px; align-items: center; }
.sw-ptile__face { width: 40px; height: 40px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: .8rem; background: var(--sw-primary-tint); color: var(--sw-primary); border: 2px solid var(--sw-surface); }
.sw-ptile__face + .sw-ptile__face { margin-left: -10px; }
.sw-tier--lg { font-size: 1.35rem; padding: .3rem .75rem; border-radius: 12px; }
/* A ring drawn from one percentage (--p) in one colour (--c). */
.sw-pring { width: 56px; height: 56px; border-radius: 999px; display: grid; place-items: center; background: conic-gradient(var(--c, var(--sw-primary)) calc(var(--p, 0) * 1%), var(--sw-surface-sunken) 0); }
.sw-pring > span { width: 44px; height: 44px; border-radius: 999px; background: var(--sw-surface); display: grid; place-items: center; font-size: .8rem; font-weight: 800; color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-ptile--on .sw-pring { background: conic-gradient(var(--c, var(--sw-primary)) calc(var(--p, 0) * 1%), rgba(255,255,255,.18) 0); }
.sw-ptile--on .sw-pring > span { background: var(--sw-navy); color: #fff; }
@media (prefers-reduced-motion: no-preference) {
  .sw-ptile { animation: sw-ov-rise .35s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i, 0) * 45ms); }
}
.sw-attstrip { display: flex; flex-wrap: wrap; gap: 5px; margin: .2rem 0 .3rem; }
.sw-attstrip__day { width: 22px; height: 22px; border-radius: 6px; background: var(--sw-surface-sunken); transition: transform .12s ease; }
.sw-attstrip__day:hover { transform: scale(1.2); }
.sw-attstrip__day--present { background: var(--sw-att-good); }
.sw-attstrip__day--late { background: var(--sw-att-fair); }
.sw-attstrip__day--excused { background: var(--sw-primary-tint); box-shadow: inset 0 0 0 1.5px var(--sw-primary); }
.sw-attstrip__day--absent { background: var(--sw-att-poor); }
.sw-attstrip__key { display: flex; flex-wrap: wrap; gap: .8rem; font-size: .75rem; color: var(--sw-muted); margin-bottom: .6rem; }
.sw-attstrip__key i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; vertical-align: -1px; margin-right: .25rem; }
@keyframes sw-ov-ripple-dot { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.35); } }
.sw-sbar__dots { display: flex; gap: 4px; margin-top: 3px; }
.sw-sbar__dots .sw-dot { width: 8px; height: 8px; }
.sw-sbar__num { font-size: .82rem; color: var(--sw-muted); white-space: nowrap; }
.sw-sbar__chev, .sw-abars .sw-attn__chev { color: var(--sw-muted-2); display: inline-flex; transition: transform .2s ease; }
.sw-sbar-item--open .sw-sbar__chev { transform: rotate(180deg); }
.sw-sbar__drawer { padding: .3rem 1rem .8rem 4.3rem; display: flex; flex-direction: column; gap: .35rem; background: linear-gradient(180deg, var(--sw-primary-tint), var(--sw-surface) 40px); }
.sw-sbar__row { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; padding: .35rem 0; }
.sw-sbar__row b { color: var(--sw-navy); font-size: .9rem; }
.sw-sbar__sub { font-size: .8rem; color: var(--sw-muted); flex: 1; min-width: 8rem; }
.sw-sbar__go { margin-left: auto; }
@media (max-width: 700px) {
  .sw-sbar__num { display: none; }
  .sw-sbar__drawer { padding-left: 1rem; }
}

/* Coming up beside attendance */
.sw-ov-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 1.1rem; align-items: start; }
.sw-ov-card { display: flex; flex-direction: column; gap: .6rem; min-width: 0; }
@media (max-width: 420px) { .sw-ov-cols { grid-template-columns: 1fr; } }

/* Attendance by squad, one small chart each */
.sw-sq-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .6rem; }
.sw-sq { display: flex; flex-direction: column; gap: 2px; padding: .6rem .75rem .35rem; border-radius: 12px; background: var(--sw-surface); border: 1px solid var(--sw-border); text-decoration: none; color: var(--sw-text); min-width: 0; transition: transform .15s ease, box-shadow .15s ease; }
.sw-sq:hover { transform: translateY(-2px); box-shadow: var(--sw-shadow-sm); color: var(--sw-text); }
.sw-sq__name { display: flex; align-items: center; gap: 6px; font-size: .82rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-sq__value { font-size: 1.25rem; font-weight: 700; color: var(--sw-navy); font-variant-numeric: tabular-nums; display: flex; align-items: baseline; gap: .45rem; }
.sw-sq__value em { font-style: normal; font-size: .72rem; font-weight: 600; }
.sw-sq__up { color: var(--sw-success); }
.sw-sq__down { color: var(--sw-danger); }
.sw-sq__sub { font-size: .75rem; color: var(--sw-muted); padding-bottom: .3rem; }
.sw-sq__spark { width: 100%; height: 42px; overflow: visible; }
.sw-sq__ref { stroke: var(--sw-border); stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.sw-sq__area { fill: var(--sq); opacity: .12; }
.sw-sq__line { fill: none; stroke: var(--sq); stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.sw-sq__end { fill: #fff; stroke: var(--sq); stroke-width: 2; vector-effect: non-scaling-stroke; }
.sw-sq__halo { fill: var(--sq); opacity: 0; transform-box: fill-box; transform-origin: center; }

/* Money sits last, in its own box */
.sw-ov-money { margin-top: .2rem; }

/* Movement: arrival, then a few gentle loops */
@keyframes sw-ov-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes sw-ov-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes sw-ov-ripple { 0% { opacity: .45; transform: scale(1); } 70%, 100% { opacity: 0; transform: scale(2.8); } }
@keyframes sw-ov-breathe { 0%, 100% { box-shadow: 0 0 0 0 rgba(3,105,161,0); } 50% { box-shadow: 0 0 0 4px rgba(3,105,161,.15); } }
@keyframes sw-ov-glowbar { 0%, 100% { border-left-color: var(--sw-warning); } 50% { border-left-color: var(--sw-accent-tint); } }
@keyframes sw-ov-water { from { transform: translateX(0); } to { transform: translateX(-25%); } }

@media (prefers-reduced-motion: no-preference) {
  .sw-abars .sw-attn, .sw-sbar-item, .sw-sq { animation: sw-ov-rise .35s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i, 0) * 45ms); }
  .sw-sq__line { stroke-dasharray: 1; animation: sw-ov-draw .9s ease-out both; animation-delay: calc(var(--i, 0) * 60ms + 150ms); }
  .sw-sq__halo { animation: sw-ov-ripple 2.6s ease-out infinite; animation-delay: calc(var(--i, 0) * 300ms); }
  .sw-sbar--next .sw-sbar__state, .sw-sbar--live .sw-sbar__state { animation: sw-ov-breathe 3s ease-in-out infinite; }
  .sw-abars .sw-attn--danger:not(.sw-attn--open) { animation: sw-ov-rise .35s cubic-bezier(.2,.8,.2,1) both, sw-ov-glowbar 3.6s ease-in-out 1s infinite; animation-delay: calc(var(--i, 0) * 45ms), 1s; }
  .sw-ov-hero__water { width: 140%; animation: sw-ov-water 14s ease-in-out infinite alternate; }
  .sw-ov-hero__water path + path { animation: none; }
  .sw-sbar__drawer, .sw-abars .sw-attn-rows { animation: sw-ov-rise .25s ease both; }
}

/* Motion off (Settings → This device) stops every animation and transition. */
html.sw-calm *, html.sw-calm *::before, html.sw-calm *::after { animation: none !important; transition: none !important; }
.sw-setrow--switch { cursor: default; }
.sw-setrow--switch .sw-switchrow { margin-left: auto; }


/* ═══════════════════════════════════════════════════════════════
   MEMBERS (Phase 8 part 3): squad filter chips, and the swimmer beside the list
   on a wide screen. A phone keeps the list and goes to the profile.
   ═══════════════════════════════════════════════════════════════ */

.sw-mfilter { display: flex; flex-wrap: wrap; gap: .4rem; }
.sw-mfilter__chip { display: inline-flex; align-items: center; gap: .35rem; padding: .35rem .75rem; border-radius: 999px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2); font: inherit; font-size: .82rem; font-weight: 600; cursor: pointer; }
.sw-mfilter__chip:hover { background: var(--sw-surface-sunken); color: var(--sw-navy); }
.sw-mfilter__chip[aria-pressed="true"] { background: var(--sw-primary-tint); border-color: var(--sw-primary); color: var(--sw-primary); }

.sw-members { display: block; }
.sw-members__list { display: flex; flex-direction: column; gap: .75rem; min-width: 0; }
.sw-ath--selected { background: var(--sw-primary-tint); }

.sw-mpanel { display: none; }
@media (min-width: 901px) {
  .sw-members--panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 380px); gap: 1.1rem; align-items: start; }
  .sw-mpanel {
    display: flex; flex-direction: column; gap: .8rem; position: sticky; top: 1rem;
    max-height: calc(100vh - 2rem); overflow-y: auto; padding: 1rem 1.1rem;
    background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow);
  }
}
.sw-mpanel__head { display: flex; align-items: center; gap: .75rem; }
.sw-mpanel__av { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; color: #fff; font-weight: 700; }
.sw-mpanel__who { flex: 1; min-width: 0; }
.sw-mpanel__who h2 { margin: 0; font-size: 1.1rem; }
.sw-mpanel__sub { font-size: .82rem; color: var(--sw-muted); }
.sw-mpanel__x { all: unset; cursor: pointer; width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; color: var(--sw-muted); }
.sw-mpanel__x:hover { background: var(--sw-surface-sunken); color: var(--sw-navy); }
.sw-mpanel__chips { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.sw-mpanel__tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--sw-border); overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.sw-mpanel__tab { all: unset; cursor: pointer; display: inline-flex; flex: none; white-space: nowrap; align-items: center; gap: .3rem; padding: .45rem .6rem; font-size: .85rem; font-weight: 600; color: var(--sw-muted); border-bottom: 2px solid transparent; margin-bottom: -1px; }
.sw-mpanel__tab[aria-selected="true"] { color: var(--sw-primary); border-bottom-color: var(--sw-primary); }
.sw-mpanel__rows { display: flex; flex-direction: column; }
.sw-mpanel__row { display: grid; grid-template-columns: 1fr auto; gap: .1rem .6rem; padding: .45rem 0; border-bottom: 1px solid var(--sw-surface-sunken); font-size: .88rem; align-items: center; }
.sw-mpanel__row small { color: var(--sw-muted); font-size: .75rem; grid-column: 1 / -1; }
.sw-mpanel__row--stack { grid-template-columns: 1fr; }
.sw-mpanel__full { align-self: flex-start; display: inline-flex; align-items: center; gap: .3rem; }
@media (prefers-reduced-motion: no-preference) {
  .sw-mpanel { animation: sw-ov-rise .25s cubic-bezier(.2,.8,.2,1) both; }
}


/* ═══════════════════════════════════════════════════════════════
   SESSIONS WEEK (Phase 8 part 4): a column a day, a card per session time.
   Wide screens only; the phone keeps the day-by-day list.
   ═══════════════════════════════════════════════════════════════ */

.sw-wide-only { display: none; }
@media (min-width: 901px) {
  .sw-wide-only { display: block; }
  .sw-narrow-only { display: none !important; }
}

.sw-wk { display: flex; flex-direction: column; gap: .7rem; }
.sw-wk__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem; }
.sw-wk__nav, .sw-wk__btns { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.sw-wk__btns .btn { display: inline-flex; align-items: center; gap: .3rem; }
.sw-wk__label { font-weight: 700; color: var(--sw-navy); padding: 0 .3rem; }
.sw-wk__wrap { display: block; }
.sw-wk__wrap--panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 330px); gap: 1rem; align-items: start; }
.sw-wk__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); overflow: hidden; min-width: 0; }
.sw-wk__day { display: flex; flex-direction: column; gap: .4rem; padding: .7rem .55rem; border-right: 1px solid var(--sw-surface-sunken); min-width: 0; min-height: 160px; }
.sw-wk__day:last-child { border-right: 0; }
.sw-wk__day--today { background: #f0f9ff; }
.sw-wk__day--past .sw-wk__card { opacity: .65; }
.sw-wk__dayname { font-size: .8rem; font-weight: 700; color: var(--sw-text-2); white-space: nowrap; }
.sw-wk__day--today .sw-wk__dayname { color: var(--sw-primary); }
.sw-wk__none { color: var(--sw-muted-2); font-size: .85rem; padding: .2rem .1rem; }
.sw-wk__card { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-direction: column; gap: 2px; padding: .45rem .55rem; border-radius: 10px; background: var(--sw-surface-sunken); border: 1px solid transparent; min-width: 0; transition: transform .15s ease, box-shadow .15s ease, background .15s ease; }
.sw-wk__day--today .sw-wk__card { background: var(--sw-surface); border-color: #bae6fd; }
.sw-wk__card:hover { transform: translateY(-1px); box-shadow: var(--sw-shadow-sm); }
.sw-wk__card:focus-visible { outline: 2px solid var(--sw-primary); }
.sw-wk__card--open { background: var(--sw-primary-tint) !important; border-color: var(--sw-primary) !important; }
.sw-wk__card--off { opacity: .55; }
.sw-wk__card--off .sw-wk__squads { text-decoration: line-through; }
.sw-wk__card b { font-size: .8rem; color: var(--sw-primary); font-variant-numeric: tabular-nums; }
.sw-wk__squads { font-size: .8rem; color: var(--sw-text); line-height: 1.25; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }
.sw-wk__dots { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 2px; }
.sw-wk__dots .sw-dot { width: 7px; height: 7px; }
.sw-wk__panel { display: flex; flex-direction: column; gap: .6rem; position: sticky; top: 1rem; padding: 1rem; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow); }
.sw-wk__slot { display: flex; align-items: center; gap: .55rem; padding: .45rem 0; border-top: 1px solid var(--sw-surface-sunken); }
.sw-wk__slotwho { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-wk__slotwho b { font-size: .9rem; color: var(--sw-navy); }
.sw-wk__slotwho small { font-size: .75rem; color: var(--sw-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-sessions__week { margin-bottom: .5rem; }
@media (prefers-reduced-motion: no-preference) {
  .sw-wk__card { animation: sw-ov-rise .3s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i, 0) * 35ms); }
  .sw-wk__panel { animation: sw-ov-rise .25s cubic-bezier(.2,.8,.2,1) both; }
}


/* ═══════════════════════════════════════════════════════════════
   MEETS (Phase 8 part 5): galas as a list, the chosen one beside it.
   Wide screens, coaches and admins; everyone else keeps the cards.
   ═══════════════════════════════════════════════════════════════ */

.sw-meetsplit { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); gap: 1.1rem; align-items: start; }
.sw-meetlist { display: flex; flex-direction: column; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); overflow: hidden; }
.sw-meetlist__row { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: .8rem; padding: .7rem 1rem; border-top: 1px solid var(--sw-surface-sunken); }
.sw-meetlist__row:first-child { border-top: 0; }
.sw-meetlist__row:hover { background: #f8fbff; }
.sw-meetlist__row[aria-current="true"] { background: var(--sw-primary-tint); box-shadow: inset 3px 0 0 var(--sw-primary); }
.sw-meetlist__row:focus-visible { outline: 2px solid var(--sw-primary); outline-offset: -2px; }
.sw-meetlist__cal { flex: 0 0 44px; height: 46px; border-radius: 10px; background: var(--sw-surface); border: 1px solid var(--sw-border); display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1.05; }
.sw-meetlist__cal span { font-size: .62rem; font-weight: 700; color: var(--sw-danger); }
.sw-meetlist__cal b { font-size: 1.05rem; color: var(--sw-navy); }
.sw-meetlist__tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-meetlist__tx b { color: var(--sw-navy); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-meetlist__tx small { color: var(--sw-muted); font-size: .8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-meetpanel { display: flex; flex-direction: column; gap: .9rem; position: sticky; top: 1rem; padding: 1.1rem; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow); }
.sw-meetpanel__countdown { display: flex; align-items: center; gap: .8rem; padding: .7rem; border-radius: 12px; background: var(--sw-accent-tint); }
.sw-meetpanel__countdown b { color: var(--sw-sunflower-ink, #92400e); }
.sw-ring { width: 56px; height: 56px; flex: 0 0 56px; }
.sw-ring__bg { fill: none; stroke: rgba(146,64,14,.15); stroke-width: 5; }
.sw-ring__fg { fill: none; stroke: var(--sw-warning); stroke-width: 5; stroke-linecap: round; }
.sw-ring text { font-size: 15px; font-weight: 700; fill: #92400e; }
.sw-meetpanel__facts { display: grid; grid-template-columns: auto 1fr; gap: .45rem .9rem; margin: 0; font-size: .88rem; }
.sw-meetpanel__facts dt { display: flex; align-items: center; gap: .35rem; color: var(--sw-muted); font-weight: 600; }
.sw-meetpanel__facts dd { margin: 0; color: var(--sw-text); }
.sw-meetpanel__btns .btn { display: inline-flex; align-items: center; gap: .35rem; }
@keyframes sw-ring-in { from { stroke-dashoffset: 151; } }
@media (prefers-reduced-motion: no-preference) {
  .sw-meetlist__row { animation: sw-ov-rise .3s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i, 0) * 40ms); }
  .sw-meetpanel { animation: sw-ov-rise .25s cubic-bezier(.2,.8,.2,1) both; }
  .sw-ring__fg { animation: sw-ring-in .9s ease-out both; }
}

/* Coach presets (Performance P1): "Custom" is a state, not a button. */
span.sw-mfilter__chip { cursor: default; }
span.sw-mfilter__chip:hover { background: var(--sw-surface); color: var(--sw-text-2); }
span.sw-mfilter__chip[aria-pressed="true"]:hover { background: var(--sw-primary-tint); color: var(--sw-primary); }

/* Training zones (Performance P1) — a workout's distance by zone, under the per-squad figures. */
.sw-zones { margin-top: .75rem; display: grid; gap: .55rem; }
.sw-zones__row { display: grid; gap: .3rem; }
.sw-zones__who { font-size: .8rem; font-weight: 600; color: var(--sw-text-2); }
.sw-zones__bar { display: flex; height: 10px; border-radius: 999px; overflow: hidden; background: var(--sw-surface-sunken); gap: 2px; }
.sw-zones__bar > span { min-width: 3px; }
.sw-zones__rest { background: var(--sw-border); }
.sw-zones__keys { display: flex; flex-wrap: wrap; gap: .25rem .8rem; font-size: .78rem; color: var(--sw-text-2); }
.sw-zones__keys > span { display: inline-flex; align-items: center; gap: .3rem; }
.sw-zones__keys i { width: .6rem; height: .6rem; border-radius: 3px; display: inline-block; }
.sw-zones__keys b { color: var(--sw-text); font-weight: 600; }
.sw-zones__restkey i { background: var(--sw-border); }

/* The daily check-in in the app (Performance P2). Big targets: a child answers this on a phone. */
.sw-daily { display: grid; gap: .8rem; padding: 1rem; }
.sw-daily--embedded { padding: .75rem 1rem; border-top: 1px solid var(--sw-border); }
.sw-daily__head { display: flex; gap: .7rem; align-items: center; width: 100%; padding: 0; border: 0; background: none; font: inherit; text-align: left; cursor: pointer; color: var(--sw-muted); }
.sw-daily__who { display: grid; flex: 1; min-width: 0; }
.sw-daily__icon { display: inline-grid; place-items: center; width: 2.1rem; height: 2.1rem; border-radius: 10px; background: var(--sw-primary-tint); color: var(--sw-primary); flex-shrink: 0; }
.sw-daily__title { font-weight: 700; color: var(--sw-navy); }
.sw-daily__sub, .sw-daily__hint { font-size: .8rem; color: var(--sw-muted); }
.sw-daily__q { display: grid; gap: .3rem; }
.sw-daily__qtext { font-size: .88rem; font-weight: 600; color: var(--sw-text); }
.sw-daily__scale { display: grid; grid-template-columns: repeat(5, 1fr); gap: .35rem; }
.sw-daily__scale--ten { grid-template-columns: repeat(10, 1fr); gap: .25rem; }
.sw-daily__pick { min-height: 2.6rem; border-radius: 12px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2); font: inherit; font-weight: 700; cursor: pointer; }
.sw-daily__pick:hover { background: var(--sw-surface-sunken); }
.sw-daily__pick[aria-pressed="true"] { background: var(--sw-primary); border-color: var(--sw-primary); color: #fff; }
.sw-daily__ends { display: flex; justify-content: space-between; font-size: .72rem; color: var(--sw-muted); }
.sw-daily__done { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; font-size: .88rem; font-weight: 600; color: var(--sw-success); }
.sw-daily__effort { padding-top: .6rem; border-top: 1px solid var(--sw-border); }
.sw-daily__chev { display: inline-flex; transition: transform .2s; }
.sw-daily__chev--open { transform: rotate(180deg); }

/* Race ready (Performance P3): one row per swimmer, the light on the left, the reasons in words. */
.sw-rr__summary { display: flex; gap: .5rem; margin-bottom: .8rem; flex-wrap: wrap; }
.sw-rr__count { padding: .25rem .7rem; border-radius: 999px; font-size: .8rem; font-weight: 700; }
.sw-rr__count--red { background: var(--sw-danger-tint, #fee2e2); color: var(--sw-danger); }
.sw-rr__count--amber { background: var(--sw-accent-tint); color: color-mix(in srgb, var(--sw-accent) 70%, var(--sw-navy)); }
.sw-rr__count--green { background: var(--sw-success-tint, #d1fae5); color: var(--sw-success); }
.sw-rr { display: grid; gap: .5rem; margin-top: .8rem; }
.sw-rr__row { display: grid; grid-template-columns: auto minmax(8rem, 14rem) 1fr auto; gap: .8rem; align-items: center; padding: .8rem 1rem; border-radius: 14px; background: var(--sw-surface); border: 1px solid var(--sw-border); color: inherit; text-decoration: none; }
.sw-rr__row:hover { border-color: var(--sw-primary); }
.sw-rr__light { width: .8rem; height: .8rem; border-radius: 50%; background: var(--sw-success); box-shadow: 0 0 0 4px color-mix(in srgb, var(--sw-success) 18%, transparent); }
.sw-rr__row--amber .sw-rr__light { background: var(--sw-accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--sw-accent) 22%, transparent); }
.sw-rr__row--red .sw-rr__light { background: var(--sw-danger); box-shadow: 0 0 0 4px color-mix(in srgb, var(--sw-danger) 20%, transparent); }
.sw-rr__who, .sw-rr__why { display: grid; gap: .15rem; min-width: 0; }
.sw-rr__who b { color: var(--sw-navy); }
.sw-rr__who small, .sw-rr__why small { color: var(--sw-muted); font-size: .76rem; }
.sw-rr__why > span { font-size: .86rem; color: var(--sw-text); }
@media (max-width: 640px) {
  .sw-rr__row { grid-template-columns: auto 1fr auto; }
  .sw-rr__why { grid-column: 2 / 3; }
}
.sw-daily__ready { display: flex; align-items: center; gap: .4rem; font-size: .84rem; font-weight: 600; color: var(--sw-text-2); }
.sw-daily__ready--on { color: var(--sw-success); }

/* Goals interview (Performance P3). */
.sw-gi__events { display: grid; gap: .6rem; }
.sw-gi__event { display: grid; grid-template-columns: 1fr 7rem auto; gap: .6rem; align-items: center; padding: .55rem 0; border-bottom: 1px solid var(--sw-border); }
.sw-gi__event:last-child { border-bottom: 0; }
.sw-gi__race { display: grid; gap: .1rem; min-width: 0; }
.sw-gi__race b { color: var(--sw-navy); }
.sw-gi__race small { color: var(--sw-muted); font-size: .78rem; }
.sw-gi__time { text-align: center; font-variant-numeric: tabular-nums; }
.sw-gi__quick { display: flex; gap: .3rem; flex-wrap: wrap; }
@media (max-width: 560px) { .sw-gi__event { grid-template-columns: 1fr 6rem; } .sw-gi__quick { grid-column: 1 / -1; } }


/* ═══════════════════════════════════════════════════════════════
   BILLING (2026-10-09): laid out like an accounting package — an overview of
   what is owed and what came in, invoices as a table with status tabs and the
   invoice read beside it, and families as contacts. Phones stack and drop the
   minor columns.
   ═══════════════════════════════════════════════════════════════ */

.sw-titlebar .sw-bill__new { margin-left: auto; display: flex; gap: .4rem; }
.sw-bill__new .btn { display: inline-flex; align-items: center; gap: .3rem; }
.sw-bill__tabs { overflow-x: auto; scrollbar-width: none; }
.sw-bill__tabs .sw-mpanel__tab { white-space: nowrap; font-size: .92rem; padding: .55rem .8rem; }

.sw-bill__cards { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 901px) { .sw-bill__cards { grid-template-columns: 1fr 1fr; } .sw-bill__cards--three { grid-template-columns: repeat(3, 1fr); } }
.sw-bill__card { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm); padding: 1rem 1.15rem; display: flex; flex-direction: column; gap: .85rem; min-width: 0; }
.sw-bill__cardhead { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }
.sw-bill__cardhead h2 { margin: 0; font-size: 1.15rem; font-weight: 800; color: var(--sw-navy); }
.sw-bill__figs { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
.sw-bill__fig { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-direction: column; gap: .15rem; padding: .65rem .8rem; border-radius: 12px; background: var(--sw-surface-sunken); border-left: 4px solid var(--sw-primary); }
.sw-bill__fig:hover { background: var(--sw-primary-tint); }
.sw-bill__fig span { font-size: .8rem; color: var(--sw-text-2); }
.sw-bill__fig b { font-size: 1.35rem; color: var(--sw-navy); letter-spacing: -.01em; }
.sw-bill__fig--bad { border-left-color: var(--sw-danger); }
.sw-bill__fig--bad b { color: var(--sw-danger); }
.sw-bill__fig--plain { cursor: default; border-left-color: var(--sw-success); }
.sw-bill__fig--plain:hover { background: var(--sw-surface-sunken); }

.sw-bill__aged { display: flex; flex-direction: column; gap: .35rem; }
.sw-bill__agedrow { display: grid; grid-template-columns: 90px 1fr 80px; align-items: center; gap: .6rem; font-size: .84rem; color: var(--sw-text-2); }
.sw-bill__agedrow b { text-align: right; color: var(--sw-navy); }
.sw-bill__agedbar { height: 10px; border-radius: 999px; background: var(--sw-surface-sunken); overflow: hidden; }
.sw-bill__agedbar > span { display: block; height: 100%; border-radius: 999px; background: var(--sw-primary); transition: width .4s ease; }
.sw-bill__agedbar > span.sw-bill__agedbar--late { background: var(--sw-danger); }

.sw-bill__legend { display: inline-flex; align-items: center; gap: .35rem; font-size: .78rem; color: var(--sw-muted); }
.sw-bill__key { display: inline-block; width: 10px; height: 10px; border-radius: 3px; background: #bae6fd; margin-left: .4rem; }
.sw-bill__key--in { background: var(--sw-primary); }
.sw-bill__chart { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: .5rem; height: 150px; align-items: end; }
.sw-bill__col { display: flex; flex-direction: column; align-items: center; gap: .3rem; height: 100%; }
.sw-bill__col small { font-size: .75rem; color: var(--sw-muted); }
.sw-bill__bars { flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; gap: 3px; }
.sw-bill__bar { width: 38%; max-width: 22px; border-radius: 5px 5px 0 0; background: #bae6fd; transition: height .4s ease; }
.sw-bill__bar--in { background: var(--sw-primary); }

.sw-bill__stat { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); padding: .8rem 1rem; display: flex; flex-direction: column; gap: .15rem; }
.sw-bill__stat span { font-size: .8rem; color: var(--sw-muted); }
.sw-bill__stat b { font-size: 1.25rem; color: var(--sw-navy); }

.sw-bill__toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.sw-bill__search { display: flex; align-items: center; gap: .4rem; flex: 1 1 260px; max-width: 420px; padding: .45rem .75rem; border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-surface); color: var(--sw-muted); }
.sw-bill__search input { all: unset; flex: 1; color: var(--sw-text); font-size: .9rem; }
.sw-bill__sum { margin-left: auto; font-size: .84rem; color: var(--sw-muted); }
.sw-bill__chipx { all: unset; cursor: pointer; margin-left: .3rem; font-size: .75rem; }
.sw-bill__bulk { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: .55rem .8rem; border-radius: 12px; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-bill__bulk input { width: 200px; }

.sw-bill__wrap { display: block; }
@media (min-width: 901px) { .sw-bill__wrap--panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 380px); gap: 1rem; align-items: start; } }
.sw-bill__panel { display: flex !important; flex-direction: column; gap: .75rem; padding: 1rem 1.1rem; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow); margin-top: 1rem; }
@media (min-width: 901px) { .sw-bill__panel { margin-top: 0; position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; } }

.sw-bill__table { display: flex; flex-direction: column; background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); overflow: hidden; min-width: 0; }
.sw-bill__card .sw-bill__table { border: 0; border-radius: 0; }
.sw-bill__th, .sw-bill__tr { display: grid; align-items: center; gap: .6rem; padding: .55rem .85rem; font-size: .88rem; }
.sw-bill__th { background: var(--sw-surface-sunken); font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--sw-muted); }
.sw-bill__tr { all: unset; box-sizing: border-box; display: grid; align-items: center; gap: .6rem; padding: .6rem .85rem; font-size: .88rem; border-top: 1px solid var(--sw-surface-sunken); cursor: pointer; color: var(--sw-text); }
.sw-bill__tr:hover { background: #f8fbff; }
.sw-bill__tr--on { background: var(--sw-primary-tint) !important; }
.sw-bill__tr small, .sw-bill__tr span > small { display: block; font-size: .74rem; color: var(--sw-muted); }
.sw-bill__table--invoices .sw-bill__th, .sw-bill__table--invoices .sw-bill__tr { grid-template-columns: 22px 90px minmax(0, 1.4fr) minmax(0, 1.2fr) 100px 110px 90px 100px 130px; }
.sw-bill__table--fam .sw-bill__th, .sw-bill__table--fam .sw-bill__tr { grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr) 100px 100px 100px 110px; }
.sw-bill__table--families .sw-bill__tr { grid-template-columns: minmax(0, 1fr) 90px 100px; }
.sw-bill__num { text-align: right; font-variant-numeric: tabular-nums; }
.sw-bill__no { font-weight: 600; color: var(--sw-primary); font-variant-numeric: tabular-nums; }
.sw-bill__who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-bill__late { color: var(--sw-danger) !important; font-weight: 600; }
.sw-bill__empty, .sw-bill__more { padding: .8rem .85rem; }
@media (max-width: 900px) {
  .sw-bill__hide { display: none !important; }
  .sw-bill__table--invoices .sw-bill__th, .sw-bill__table--invoices .sw-bill__tr { grid-template-columns: 22px 70px minmax(0, 1fr) 82px 80px; }
  .sw-bill__table--invoices .sw-bill__th > :last-child, .sw-bill__table--invoices .sw-bill__tr > :last-child { display: none; }
  .sw-bill__table--fam .sw-bill__th, .sw-bill__table--fam .sw-bill__tr { grid-template-columns: minmax(0, 1fr) 80px 80px; }
  .sw-bill__sum { margin-left: 0; }
}

.sw-bill__meta { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
.sw-bill__meta div { display: flex; flex-direction: column; gap: .1rem; }
.sw-bill__meta span { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--sw-muted); font-weight: 700; }
.sw-bill__meta b { font-size: .88rem; color: var(--sw-navy); }
.sw-bill__lines { display: flex; flex-direction: column; border: 1px solid var(--sw-border); border-radius: 12px; overflow: hidden; }
.sw-bill__line { display: flex; justify-content: space-between; gap: .6rem; padding: .45rem .7rem; font-size: .86rem; border-top: 1px solid var(--sw-surface-sunken); font-variant-numeric: tabular-nums; }
.sw-bill__line:first-child { border-top: 0; }
.sw-bill__line small { display: block; font-size: .72rem; color: var(--sw-muted); }
.sw-bill__line--total { font-weight: 700; border-top: 1px solid var(--sw-border); }
.sw-bill__line--due { font-weight: 800; background: var(--sw-surface-sunken); color: var(--sw-navy); }
.sw-bill__split { padding: .4rem .7rem; font-size: .74rem; color: var(--sw-muted); background: var(--sw-bg); }
.sw-bill__actions { display: flex; flex-wrap: wrap; gap: .4rem; }
/* With an invoice open beside it, the table keeps only what identifies and prices an invoice. */
@media (min-width: 901px) {
  .sw-bill__wrap--panel .sw-bill__hide { display: none !important; }
  .sw-bill__wrap--panel .sw-bill__table--invoices .sw-bill__th, .sw-bill__wrap--panel .sw-bill__table--invoices .sw-bill__tr { grid-template-columns: 22px 92px minmax(0, 1fr) 110px 100px 120px; }
}

/* Needs your decision: the accounts whose second attempt failed (Gideon, 2026-10-09). */
.sw-bill__decide { border-left: 4px solid var(--sw-danger); }
.sw-bill__decide .sw-hint { margin: -.4rem 0 0; }
.sw-bill__decrow { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem 1rem; align-items: center; padding: .65rem 0; border-top: 1px solid var(--sw-surface-sunken); }
.sw-bill__decwho small, .sw-bill__decrow .sw-bill__num small { display: block; font-size: .76rem; color: var(--sw-muted); }
.sw-bill__decbtns { display: flex; flex-wrap: wrap; gap: .4rem; grid-column: 1 / -1; }
@media (min-width: 901px) { .sw-bill__decrow { grid-template-columns: minmax(0, 1fr) 110px auto; } .sw-bill__decrow .sw-bill__decbtns { grid-column: auto; } }
.sw-bill__decform { display: flex; flex-direction: column; gap: .5rem; padding: .75rem .85rem; margin-bottom: .4rem; border-radius: 12px; background: var(--sw-surface-sunken); font-size: .88rem; }
.sw-bill__decdate { display: flex; align-items: center; gap: .6rem; }
.sw-bill__decdate input { width: auto; }

/* A family behind on payment (Gideon, 2026-10-09): the banner on their home and billing page. */
.sw-billalert { display: flex; gap: .8rem; align-items: flex-start; padding: .9rem 1rem; border-radius: var(--sw-radius); background: var(--sw-accent-tint); border: 1px solid #fcd34d; color: var(--sw-navy); }
.sw-billalert--suspended, .sw-billalert--behind { background: var(--sw-danger-tint); border-color: #fca5a5; }
.sw-billalert--arrangement { background: var(--sw-primary-tint); border-color: #bae6fd; }
.sw-billalert__icon { flex: 0 0 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; background: var(--sw-surface); color: var(--sw-warning); }
.sw-billalert--suspended .sw-billalert__icon, .sw-billalert--behind .sw-billalert__icon { color: var(--sw-danger); }
.sw-billalert--arrangement .sw-billalert__icon { color: var(--sw-primary); }
.sw-billalert__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .3rem; }
.sw-billalert__body > span { font-size: .88rem; color: var(--sw-text-2); }
.sw-billalert__btns { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center; margin-top: .25rem; }
.sw-billalert__form { display: flex; flex-direction: column; gap: .45rem; margin-top: .3rem; }
.sw-billalert__form label { display: flex; align-items: center; gap: .6rem; }
.sw-billalert__form input[type=date] { width: auto; }
.sw-billalert__err { color: var(--sw-danger); }
.sw-bill__request { margin-top: .35rem; display: inline-flex; align-items: center; gap: .35rem; padding: .3rem .6rem; border-radius: 8px; background: var(--sw-primary-tint); color: var(--sw-primary); font-size: .8rem; }

/* ── Training blocks (Performance P4) ── */
.sw-blocktile { border-left-color: var(--sw-phase-other); }
.sw-blocktile--base { border-left-color: var(--sw-phase-base); }
.sw-blocktile--build { border-left-color: var(--sw-phase-build); }
.sw-blocktile--race { border-left-color: var(--sw-phase-race); }
.sw-blocktile--taper { border-left-color: var(--sw-phase-taper); }
.sw-blocktile__squads { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .35rem; }
.sw-block__meta { margin: -.4rem 0 .9rem; }

.sw-blockband { display: flex; gap: .35rem; align-items: flex-end; }
.sw-blockband__phase { min-width: 0; }
.sw-blockband__name { font-size: .78rem; font-weight: 700; color: var(--sw-navy); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: .25rem; }
.sw-blockband__name small { font-weight: 500; color: var(--sw-muted); }
.sw-blockband__weeks { display: flex; gap: 2px; }
.sw-blockband__week { flex: 1; min-width: 4px; height: 22px; border: 0; padding: 0; border-radius: 4px; cursor: pointer; opacity: .55; background: var(--sw-phase-other); }
.sw-blockband__week:hover { opacity: .85; }
.sw-blockband__week--base { background: var(--sw-phase-base); }
.sw-blockband__week--build { background: var(--sw-phase-build); }
.sw-blockband__week--race { background: var(--sw-phase-race); }
.sw-blockband__week--taper { background: var(--sw-phase-taper); }
.sw-blockband__week--now { opacity: 1; outline: 2px solid var(--sw-navy); outline-offset: 1px; }

.sw-blockweek .sw-attn-rows { margin-top: 0; padding: .9rem 1rem 1rem; }
.sw-blockweek--now { box-shadow: 0 0 0 2px var(--sw-primary-tint); }
.sw-blockbar { height: 6px; border-radius: 999px; background: var(--sw-surface-sunken); margin-top: .45rem; overflow: hidden; max-width: 22rem; }
.sw-blockbar span { display: block; height: 100%; background: var(--sw-primary); border-radius: 999px; }

.sw-blockform { display: grid; grid-template-columns: 2fr 1fr; gap: .8rem; }
.sw-blockform label { display: block; }
.sw-blockform__actions { display: flex; align-items: center; gap: .8rem; margin-top: .8rem; }
.sw-blockzones { display: grid; grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr)); gap: .5rem; margin-top: .3rem; }
.sw-blockzones__cell { display: flex; flex-direction: column; gap: .2rem; font-size: .82rem; font-weight: 600; color: var(--sw-navy); }
.sw-blockzones__cell small { font-weight: 500; color: var(--sw-muted); }
.sw-blockdays { display: grid; gap: .3rem; margin-top: .3rem; }
.sw-blockdays__row { display: grid; grid-template-columns: 2.6rem 1fr; align-items: center; gap: .5rem; font-size: .85rem; }
.sw-blockdays__row > span:first-child { font-weight: 700; color: var(--sw-navy); }
.sw-blockactual { margin-top: 1rem; padding-top: .8rem; border-top: 1px solid var(--sw-border); display: grid; gap: .25rem; }

.sw-blockphases { display: grid; gap: .4rem; }
.sw-blockphases__row { display: grid; grid-template-columns: auto 1fr 4.5rem auto auto; align-items: center; gap: .45rem; }
.sw-blockphases__tools { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }
.sw-blockphase-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--sw-phase-other); }
.sw-blockphase-dot--base { background: var(--sw-phase-base); }
.sw-blockphase-dot--build { background: var(--sw-phase-build); }
.sw-blockphase-dot--race { background: var(--sw-phase-race); }
.sw-blockphase-dot--taper { background: var(--sw-phase-taper); }

/* The week's focus on a session and on the family's check-in card */
.sw-weekfocus { display: flex; align-items: center; gap: .4rem; font-size: .85rem; color: var(--sw-text-2); }
.sw-weekfocus .sw-icon { color: var(--sw-primary); flex-shrink: 0; }

@media (max-width: 600px) {
  .sw-blockform { grid-template-columns: 1fr; }
  .sw-blockband__name small { display: none; }
}
.sw-blockweek .sw-control, .sw-blocksheet .sw-control { width: 100%; box-sizing: border-box; }
.sw-blockweek .sw-label, .sw-blocksheet .sw-label { display: block; }
.sw-blockphases__row .sw-control { width: 100%; }

/* ── The season schedule ── */
.sw-season__form { display: grid; gap: .45rem; }
.sw-season__row { display: grid; grid-template-columns: minmax(10rem, 2fr) 9.5rem 9.5rem minmax(7rem, 1fr) 8.5rem auto; gap: .45rem; align-items: center; }
.sw-season__row .sw-control { width: 100%; box-sizing: border-box; }
.sw-season__row--head { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--sw-muted); }
.sw-season__err { grid-column: 1 / -1; }
.sw-season__month { padding: .3rem; }
.sw-season__gala { display: flex; align-items: center; gap: .8rem; }
.sw-season__date { width: 7.5rem; flex-shrink: 0; font-weight: 700; color: var(--sw-navy); font-size: .88rem; }
.sw-season__name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sw-season__name small { color: var(--sw-muted); }
@media (max-width: 760px) {
  .sw-season__row { grid-template-columns: 1fr 1fr; }
  .sw-season__row > :first-child { grid-column: 1 / -1; }
  .sw-season__row--head { display: none; }
  .sw-season__date { width: 5.5rem; }
}
.sw-blockband__week--gala { display: inline-flex; align-items: center; justify-content: center; color: var(--sw-surface); opacity: .9; }
.sw-blockgalas { display: flex; flex-direction: column; gap: .35rem; margin-top: .8rem; }
.sw-blockgala { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-size: .88rem; color: var(--sw-text-2); text-decoration: none; }
.sw-blockgala:hover b { text-decoration: underline; }
.sw-blockgala .sw-icon { color: var(--sw-accent); }
.sw-blockgala--target b { color: var(--sw-navy); }
.sw-chip--gala { display: inline-flex; align-items: center; gap: .25rem; background: var(--sw-accent-tint); color: var(--sw-sunflower-ink); }

/* Results across a training block (2026-10-10): the training per phase, then each gala's swims against the best before. */
.sw-blockres__work { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: .2rem 0 .7rem; font-size: .85rem; }
.sw-blockres__phase { display: inline-flex; align-items: center; gap: .35rem; }
.sw-blockres__dot { width: .55rem; height: .55rem; border-radius: 50%; background: var(--sw-phase-other); }
.sw-blockres__dot--base { background: var(--sw-phase-base); }
.sw-blockres__dot--build { background: var(--sw-phase-build); }
.sw-blockres__dot--race { background: var(--sw-phase-race); }
.sw-blockres__dot--taper { background: var(--sw-phase-taper); }
.sw-blockres__swimmer { display: flex; flex-direction: column; gap: .3rem; padding: .55rem 0; border-bottom: 1px solid var(--sw-border); }
.sw-blockres__swimmer:last-child { border-bottom: 0; }
.sw-blockres__swimmer a { color: var(--sw-text); text-decoration: none; }
.sw-blockres__swims { display: flex; flex-direction: column; gap: .2rem; }
.sw-blockres__swim { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; font-size: .86rem; }
.sw-blockres__event { min-width: 7.5rem; color: var(--sw-text-2); }

/* Reports (Performance P5) */
.sw-report__weeks { display: flex; align-items: flex-end; gap: 3px; height: 120px; margin: .25rem 0 .75rem; }
.sw-report__week { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: .2rem; }
.sw-report__wkbar { width: 100%; max-width: 28px; min-height: 2px; background: var(--sw-primary); border-radius: 4px 4px 0 0; }
.sw-report__week small { font-size: .62rem; color: var(--sw-muted); white-space: nowrap; }
.sw-report__weeks:has(.sw-report__week:nth-child(16)) .sw-report__week small { visibility: hidden; }
.sw-report__rows { display: flex; flex-direction: column; margin-top: .5rem; }
.sw-report__row { display: grid; grid-template-columns: minmax(0, 1.4fr) 1fr .8fr .9fr auto; gap: .5rem; align-items: center; padding: .5rem 0; border-bottom: 1px solid var(--sw-surface-sunken); color: var(--sw-text); text-decoration: none; font-size: .88rem; }
.sw-report__row:hover { background: var(--sw-surface-sunken); }
.sw-report__row b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-report__row small { display: block; color: var(--sw-muted); font-size: .72rem; }
.sw-report__std { font-size: .75rem; color: var(--sw-primary); font-weight: 600; }
.sw-report__event { display: flex; flex-wrap: wrap; gap: .3rem 1rem; font-size: .85rem; color: var(--sw-text-2); margin-top: .5rem; }
.sw-report__stds { margin-top: 1rem; display: grid; gap: .35rem; }
.sw-report__std-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: .6rem; font-size: .85rem; padding: .3rem 0; border-bottom: 1px solid var(--sw-surface-sunken); }
.sw-report__std-row b { color: var(--sw-accent); }
@media (max-width: 560px) {
  .sw-report__row { grid-template-columns: minmax(0, 1fr) auto auto; }
  .sw-report__row > span:nth-child(4), .sw-report__std { display: none; }
  .sw-report__std-row { grid-template-columns: minmax(0, 1fr) auto; }
  .sw-report__std-row > span:nth-child(2) { display: none; }
}
.sw-child__links { display: flex; flex-wrap: wrap; gap: .4rem 1rem; padding: .5rem 1rem .6rem; font-size: .85rem; font-weight: 600; }

/* ── Roadmap Phase 9: incidents, medical information, coach certificates ── */
.sw-incident { padding: 0; margin-bottom: .6rem; overflow: hidden; }
.sw-incident--safeguarding { border-left: 3px solid var(--sw-danger); }
.sw-incident__head { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .7rem; width: 100%; padding: .75rem 1rem; background: none; border: 0; text-align: left; color: var(--sw-text); font: inherit; cursor: pointer; }
.sw-incident__body { padding: 0 1rem 1rem; display: grid; gap: .5rem; font-size: .9rem; }
.sw-incident__body p { margin: 0; white-space: pre-line; }
.sw-incident__body .sw-label, .sw-medical .sw-label { display: block; }
.sw-medical { display: grid; gap: .7rem; font-size: .9rem; margin-bottom: .6rem; white-space: pre-line; }
.sw-cert { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: .6rem; align-items: center; padding: .5rem 0; border-bottom: 1px solid var(--sw-surface-sunken); font-size: .9rem; }
.sw-cert__actions { display: flex; gap: .6rem; }
.sw-row-gap { display: flex; gap: .5rem; margin-top: .6rem; }
@media (max-width: 560px) {
  .sw-cert { grid-template-columns: minmax(0, 1fr) auto; }
  .sw-cert__actions { grid-column: 1 / -1; }
}

/* ── Roadmap Phase 12: gala helpers and the psych sheet ── */
.sw-helper { padding: .6rem 0; border-bottom: 1px solid var(--sw-surface-sunken); display: grid; gap: .35rem; }
.sw-helper:last-child { border-bottom: 0; }
.sw-helper__head { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .7rem; }
.sw-helper__people { display: flex; flex-wrap: wrap; gap: .35rem; }
.sw-helper__people .sw-chip { display: inline-flex; align-items: center; gap: .3rem; }
.sw-chip__x { border: 0; background: none; color: inherit; font-size: 1rem; line-height: 1; padding: 0 .1rem; cursor: pointer; }
.sw-psych { padding: .75rem 1rem; margin-bottom: .6rem; }
.sw-psych__head { margin-bottom: .4rem; }
.sw-psych__row { display: grid; grid-template-columns: 2rem minmax(0, 1fr) 2.5rem auto; gap: .5rem; padding: .3rem 0; border-bottom: 1px solid var(--sw-surface-sunken); font-size: .9rem; }
.sw-psych__row:last-child { border-bottom: 0; }
.sw-psych__seed { color: var(--sw-muted); }
@media print {
  .sw-psych { break-inside: avoid; box-shadow: none; }
}

/* ── Roadmap Phase 12: branches ── */
.sw-branches { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); }
.sw-branch { padding: 1rem; display: grid; gap: .4rem; }
.sw-branch__head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.sw-branch__facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .4rem .8rem; font-size: .85rem; color: var(--sw-text-2); margin-top: .3rem; }
.sw-branch__facts b { display: block; color: var(--sw-text); font-size: 1rem; }

/* A page part that failed to load — one bar instead of a section that quietly vanishes (SwLoadProblem, 2026-10-20). */
.sw-loadproblem {
  display: flex; align-items: center; gap: .6rem; margin-bottom: .9rem; padding: .6rem .8rem;
  background: var(--sw-accent-tint); color: var(--sw-text); border: 1px solid var(--sw-border);
  border-radius: var(--sw-radius-sm); font-size: .88rem;
}
.sw-loadproblem__text { flex: 1; min-width: 0; }


/* ── Building blocks (declutter plan step 2, 2026-10-20) ─────────────────────────────────────
   Layout classes on the spacing scale, to use in place of inline styles. .sw-stack (a column, 16px)
   already exists above; .sw-inline is its row, wrapping. .sw-gap-N sets either one's gap. */
.sw-inline { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sw-space-2); }
.sw-gap-1 { gap: var(--sw-space-1); }
.sw-gap-2 { gap: var(--sw-space-2); }
.sw-gap-3 { gap: var(--sw-space-3); }
.sw-gap-4 { gap: var(--sw-space-4); }
.sw-gap-5 { gap: var(--sw-space-5); }

/* SwSection — a bold heading, a summary line and a warning chip; folds when asked to. */
.sw-sec { display: flex; flex-direction: column; gap: var(--sw-space-3); min-width: 0; }
.sw-sec__head { display: flex; align-items: center; gap: var(--sw-space-3); }
.sw-sec__toggle {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--sw-space-2);
  padding: 0; border: 0; background: none; font: inherit; color: var(--sw-navy); text-align: left;
}
button.sw-sec__toggle { cursor: pointer; }
.sw-sec__toggle > svg:last-child { margin-left: auto; color: var(--sw-muted); transition: transform .2s ease; }
.sw-sec.is-open .sw-sec__toggle > svg:last-child { transform: rotate(180deg); }
.sw-sec__titles { display: flex; flex-direction: column; min-width: 0; }
.sw-sec__title { font-size: 1.1rem; font-weight: 800; letter-spacing: -0.01em; line-height: 1.25; }
.sw-sec__sum { font-size: .85rem; font-weight: 500; color: var(--sw-muted); }
.sw-sec__actions { display: flex; align-items: center; gap: var(--sw-space-3); flex-shrink: 0; }
.sw-sec--fold {
  padding: var(--sw-space-4); background: var(--sw-surface); border: 1px solid var(--sw-border);
  border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm);
}

/* SwMoreMenu — the "···" button and the list under it. */
.sw-more { position: relative; display: inline-flex; }
.sw-more__shade { position: fixed; inset: 0; z-index: 2100; }
.sw-more__list {
  position: absolute; top: calc(100% + var(--sw-space-1)); right: 0; z-index: 2101;
  display: flex; flex-direction: column; min-width: 11rem; padding: var(--sw-space-1);
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius-sm);
  box-shadow: var(--sw-shadow);
}
.sw-more__item {
  display: flex; align-items: center; gap: var(--sw-space-2); width: 100%;
  padding: var(--sw-space-2) var(--sw-space-3); border: 0; border-radius: 8px; background: none;
  font: inherit; font-size: .88rem; color: var(--sw-text); text-align: left; text-decoration: none; cursor: pointer;
}
.sw-more__item:hover { background: var(--sw-surface-sunken); }
.sw-more__item--danger { color: var(--sw-danger); }

/* SwSplitView — the list, and the picked item beside it above 900px; stacked below. */
.sw-split { display: block; }
.sw-split__detail {
  margin-top: var(--sw-space-4); padding: var(--sw-space-4); background: var(--sw-surface);
  border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow);
}
.sw-split__list { min-width: 0; }
@media (min-width: 901px) {
  .sw-split--open { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 380px); gap: var(--sw-space-4); align-items: start; }
  .sw-split__detail { margin-top: 0; position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; }
}

/* The swimmer page (declutter plan step 3, 2026-10-20) — Edit, Report absence and "···" at the card's corner; a
   season column beside the all-time best; WhatsApp beside each guardian's number. */
.sw-profile__actions { display: flex; align-items: flex-start; gap: var(--sw-space-2); flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.sw-pbhead.sw-pbrow--season, .sw-pbrow.sw-pbrow--season { grid-template-columns: 1.5fr 1fr 1fr .8fr .9fr; }
.sw-pbrow__season { color: var(--sw-text-2); }
.sw-pbrow__pbmark { margin-left: .3rem; padding: 0 .3rem; border-radius: 6px; background: var(--sw-accent-tint); color: var(--sw-warning); font-size: .65rem; font-weight: 800; vertical-align: 1px; }
@media (max-width: 560px) {
  .sw-pbhead.sw-pbrow--season, .sw-pbrow.sw-pbrow--season { grid-template-columns: 1.3fr 1fr 1fr .7fr; }
  .sw-pbrow--season > :last-child { display: none; }
}
.sw-guardian { align-items: flex-start; }
.sw-guardian__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sw-guardian__links { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sw-space-2) var(--sw-space-3); margin-top: var(--sw-space-1); }
.sw-guardian__links .sw-guardians__link { display: inline-flex; align-items: center; gap: 4px; }
.btn.sw-wa { background: #dcfce7; color: #166534; border-color: transparent; }
.btn.sw-wa:hover { background: #bbf7d0; }

/* The session page's Register / Workout tabs, with the main button and "···" on the right (declutter plan step 4). */
.sw-sesstabs { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sw-space-3); border-bottom: 1px solid var(--sw-border); }
.sw-sesstabs__tabs { border-bottom: 0; }
.sw-sesstabs__tabs .sw-mpanel__tab { font-size: 1rem; font-weight: 700; padding: .55rem .9rem; }
.sw-sesstabs__n { min-width: 1.3rem; padding: 0 .35rem; border-radius: var(--sw-radius-pill); background: var(--sw-surface-sunken); color: var(--sw-text-2); font-size: .72rem; text-align: center; }
.sw-sesstabs__actions { display: flex; align-items: center; gap: var(--sw-space-2); padding-bottom: var(--sw-space-2); margin-left: auto; }
.sw-key--meet { background: transparent; box-shadow: inset 0 -3px 0 var(--sw-sunflower); border-radius: 2px; }
.sw-plancal__row--meet { border-left: 4px solid var(--sw-sunflower); }

/* The overview (declutter plan step 5): the three money figures in one row, the families behind folded under them,
   and this week from the block plan drawn as a "Coming up" card. */
@media (min-width: 561px) { .sw-ov-money .sw-stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.sw-ov-money { display: flex; flex-direction: column; gap: var(--sw-space-3); }
.sw-ov-overdue .sw-overdue-list { margin: 0; }
.sw-ovblock {
  display: flex; flex-direction: column; gap: var(--sw-space-4); padding: var(--sw-space-4);
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: var(--sw-radius); box-shadow: var(--sw-shadow-sm);
}
.sw-ovblock__top { display: flex; align-items: center; gap: var(--sw-space-4); }
.sw-ovblock__top .sw-upmeet__count { flex: none; }
.sw-ovblock__where { display: flex; flex-direction: column; gap: var(--sw-space-1); min-width: 0; }
.sw-ovblock__phase { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sw-space-2); font-size: .88rem; color: var(--sw-text-2); }
.sw-ovblock__pill { padding: 2px 10px; border-radius: var(--sw-radius-pill); color: #fff; font-weight: 800; font-size: .8rem; background: var(--sw-phase-other); }
.sw-ovblock__pill--base { background: var(--sw-phase-base); }
.sw-ovblock__pill--build { background: var(--sw-phase-build); }
.sw-ovblock__pill--race { background: var(--sw-phase-race); }
.sw-ovblock__pill--taper { background: var(--sw-phase-taper); }
.sw-ovblock__gala { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; color: var(--sw-text-2); text-decoration: none; }
.sw-ovblock__gala svg { color: var(--sw-sunflower); }
.sw-ovblock__gala b { color: var(--sw-navy); }
.sw-ovblock__band .sw-blockband__week { cursor: default; height: 16px; }
.sw-ovblock__band .sw-ovblock__done { opacity: .9; }
.sw-ovblock__squads { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: var(--sw-space-3); }
.sw-ovblock__squad {
  display: flex; flex-direction: column; gap: var(--sw-space-1); padding: var(--sw-space-3);
  border: 1px solid var(--sw-border); border-left: 4px solid var(--chip-colour); border-radius: var(--sw-radius-sm);
  background: color-mix(in srgb, var(--chip-colour) 5%, var(--sw-surface)); color: var(--sw-text); text-decoration: none;
}
.sw-ovblock__squad:hover { box-shadow: var(--sw-shadow-sm); }
.sw-ovblock__name { display: flex; align-items: center; gap: var(--sw-space-2); }
.sw-ovblock__name b { color: var(--sw-navy); }
.sw-ovblock__name small { margin-left: auto; color: var(--sw-muted); font-size: .72rem; }
.sw-ovblock__name .sw-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--chip-colour); flex: none; }
.sw-ovblock__focus { font-size: .88rem; font-weight: 600; color: var(--sw-text-2); }
.sw-ovblock__today { font-size: .8rem; color: var(--sw-primary); }
.sw-ovblock__bar { height: 8px; margin-top: var(--sw-space-1); border-radius: var(--sw-radius-pill); background: var(--sw-surface-sunken); overflow: hidden; }
.sw-ovblock__bar span { display: block; height: 100%; border-radius: inherit; background: var(--chip-colour); }
.sw-ovblock__km { font-size: .78rem; color: var(--sw-muted); font-variant-numeric: tabular-nums; }
.sw-ovblock__km b { color: var(--sw-navy); }
.sw-ovblock__zones { display: flex; height: 6px; gap: 1px; border-radius: var(--sw-radius-pill); overflow: hidden; margin-top: 2px; }
@media (max-width: 560px) { .sw-ovblock__squads { grid-template-columns: 1fr; } }

/* Small helpers that replace repeated inline styles (declutter plan step 10). */
.sw-cell--center { text-align: center; }
.sw-wellness__legend { margin-top: var(--sw-space-3); }
.sw-mt-1 { margin-top: var(--sw-space-1); }
.sw-mt-2 { margin-top: var(--sw-space-2); }
.sw-mt-3 { margin-top: var(--sw-space-3); }
.sw-mt-4 { margin-top: var(--sw-space-4); }

/* ═══════════════════════════════════════════════════════════════
   PUBLIC PAGES — the front page and starting a club (Gideon, 2026-10-21). PublicLayout, no app chrome.
   ═══════════════════════════════════════════════════════════════ */
.sw-pub { min-height: 100dvh; background: var(--sw-bg); color: var(--sw-text); overflow-x: hidden; }
.sw-pub-wait { min-height: 100dvh; }
.sw-pub__nav { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 1rem clamp(1rem, 4vw, 3rem); max-width: 1200px; margin: 0 auto; }
.sw-pub__brand { display: inline-flex; align-items: center; gap: .6rem; text-decoration: none; }
.sw-pub__brand img { height: 36px; width: auto; }
.sw-pub__brand .sw-pub__word { height: 22px; }
.sw-pub__links { display: flex; align-items: center; gap: .6rem; }
.sw-pub__links > a:not(.btn) { color: var(--sw-text-2); font-weight: 600; text-decoration: none; margin-right: .4rem; }
.btn-lg { padding: .8rem 1.4rem; font-size: 1rem; }

.sw-pub__hero { position: relative; display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(1.5rem, 4vw, 4rem); align-items: center; max-width: 1200px; margin: 0 auto; padding: clamp(1.5rem, 5vw, 4rem) clamp(1rem, 4vw, 3rem) clamp(3rem, 7vw, 6rem); }
.sw-pub__water { position: absolute; left: calc(50% - 50vw); bottom: 0; width: 140vw; height: 90px; pointer-events: none; z-index: 0; }
.sw-pub__water path { fill: var(--sw-primary); opacity: .07; }
.sw-pub__water path + path { opacity: .05; }
.sw-pub__hero-text, .sw-pub__phone { position: relative; z-index: 1; }
.sw-pub__eyebrow { display: inline-flex; align-items: center; gap: .4rem; font-size: .8rem; font-weight: 700; color: var(--sw-primary); background: var(--sw-primary-tint); padding: .3rem .7rem; border-radius: 999px; }
.sw-pub__hero h1 { font-size: clamp(2rem, 5vw, 3.4rem); line-height: 1.05; letter-spacing: -.02em; color: var(--sw-navy); margin: .9rem 0 .8rem; }
.sw-pub__hero p { font-size: clamp(1rem, 1.6vw, 1.15rem); color: var(--sw-text-2); max-width: 34rem; line-height: 1.55; }
.sw-pub__ctas { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1.4rem 0 1.2rem; }
.sw-pub__join { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-size: .9rem; color: var(--sw-muted); }
.sw-pub__join label { font-weight: 600; }
.sw-pub__join .sw-control { width: 11rem; }

.sw-pub__phone { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 28px; padding: 1.1rem; box-shadow: 0 30px 60px rgba(10, 25, 47, .16); display: flex; flex-direction: column; gap: .7rem; transform: rotate(1.5deg); max-width: 420px; justify-self: center; width: 100%; }
.sw-pub__phone-top { font-size: .72rem; font-weight: 600; color: var(--sw-muted); }
.sw-pub__phone-title { font-size: 1.4rem; font-weight: 800; color: var(--sw-navy); margin-top: -.4rem; }
.sw-pub__phone .sw-wday { cursor: default; padding: .4rem .1rem; }
.sw-pub__phone .sw-wday__num { font-size: 1rem; }
.sw-pub__phone-bar { display: flex; align-items: center; gap: .6rem; padding: .55rem .7rem; border: 1px solid var(--sw-border); border-radius: 12px; font-size: .85rem; color: var(--sw-text-2); }
.sw-pub__phone-bar b { color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-pub__pill { font-size: .7rem; font-weight: 700; padding: .12rem .5rem; border-radius: 999px; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-pub__pill--later { background: var(--sw-surface-sunken); color: var(--sw-muted); }
.sw-pub__phone-row { display: flex; align-items: center; gap: .7rem; padding: .3rem .2rem; }
.sw-pub__phone-row div { flex: 1; display: flex; flex-direction: column; }
.sw-pub__phone-row b { color: var(--sw-navy); }
.sw-pub__phone-row small { color: var(--sw-muted); font-size: .78rem; }

.sw-pub__band { max-width: 1200px; margin: 0 auto; padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1rem, 4vw, 3rem); }
.sw-pub__band--alt { max-width: none; background: var(--sw-surface); border-top: 1px solid var(--sw-border); border-bottom: 1px solid var(--sw-border); }
.sw-pub__band--alt > * { max-width: 1200px; margin-left: auto; margin-right: auto; }
.sw-pub__band h2 { font-size: clamp(1.5rem, 3vw, 2.1rem); color: var(--sw-navy); letter-spacing: -.01em; margin: 0 0 1.6rem; text-align: center; }
.sw-pub__roles { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }
.sw-pub__role { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 20px; padding: 1.4rem; transition: transform .2s ease, box-shadow .2s ease; }
.sw-pub__role:hover { transform: translateY(-4px); box-shadow: 0 16px 32px rgba(10, 25, 47, .1); }
.sw-pub__role h3 { margin: .8rem 0 .5rem; color: var(--sw-navy); }
.sw-pub__role ul { margin: 0; padding-left: 1.1rem; color: var(--sw-text-2); line-height: 1.6; font-size: .93rem; }
.sw-pub__icon { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-pub__icon--sm { width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0; }
.sw-pub__features { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.2rem 2rem; }
.sw-pub__feature { display: flex; gap: .9rem; align-items: flex-start; }
.sw-pub__feature b { color: var(--sw-navy); }
.sw-pub__feature p { margin: .2rem 0 0; color: var(--sw-text-2); font-size: .92rem; line-height: 1.5; }
.sw-pub__steps { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; counter-reset: none; }
.sw-pub__steps li { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 20px; padding: 1.3rem; }
.sw-pub__steps li span { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 999px; background: var(--sw-navy); color: #fff; font-weight: 800; margin-bottom: .7rem; }
.sw-pub__steps li b { display: block; color: var(--sw-navy); font-size: 1.05rem; }
.sw-pub__steps li p { margin: .3rem 0 0; color: var(--sw-text-2); font-size: .92rem; line-height: 1.5; }
.sw-pub__cta { background: var(--sw-navy); color: #fff; text-align: center; padding: clamp(2.5rem, 6vw, 4rem) 1rem; }
.sw-pub__cta h2 { color: #fff; margin: 0 0 1.2rem; font-size: clamp(1.4rem, 3vw, 2rem); }
.sw-pub__cta-btn { background: #fff; color: var(--sw-navy); border-color: #fff; }
.sw-pub__foot { display: flex; justify-content: space-between; align-items: center; max-width: 1200px; margin: 0 auto; padding: 1.2rem clamp(1rem, 4vw, 3rem); font-size: .85rem; color: var(--sw-muted); }

@media (max-width: 820px) {
  .sw-pub__hero { grid-template-columns: 1fr; }
  .sw-pub__phone { transform: none; }
  .sw-pub__links > a:not(.btn) { display: none; }
}
@media (max-width: 420px) {
  .sw-pub__links .btn-primary { display: none; }
  .sw-pub__brand .sw-pub__word { display: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .sw-pub__water { animation: sw-ov-water 14s ease-in-out infinite alternate; }
  .sw-pub__hero-text, .sw-pub__phone, .sw-pub__role, .sw-pub__steps li { animation: sw-ov-rise .5s cubic-bezier(.2,.8,.2,1) both; }
  .sw-pub__phone { animation-delay: .12s; }
}

/* Starting a club */
.sw-start { max-width: 560px; margin: 0 auto; padding: 1rem 1rem 4rem; }
.sw-start h1 { color: var(--sw-navy); margin: .5rem 0 1rem; }
.sw-start__steps { list-style: none; display: flex; gap: .5rem; padding: 0; margin: 0 0 1.2rem; flex-wrap: wrap; }
.sw-start__steps li { display: inline-flex; align-items: center; gap: .4rem; font-size: .85rem; font-weight: 600; color: var(--sw-muted); padding: .3rem .7rem .3rem .3rem; border-radius: 999px; background: var(--sw-surface); border: 1px solid var(--sw-border); }
.sw-start__steps li span { width: 22px; height: 22px; border-radius: 999px; display: grid; place-items: center; background: var(--sw-surface-sunken); font-size: .75rem; }
.sw-start__steps li.is-on { color: var(--sw-primary); border-color: var(--sw-primary); }
.sw-start__steps li.is-on span { background: var(--sw-primary); color: #fff; }
.sw-start__steps li.is-done span { background: var(--sw-success); color: #fff; }
.sw-start__card { padding: 1.4rem; display: flex; flex-direction: column; gap: .9rem; }
.sw-start__card h2 { margin: 0; color: var(--sw-navy); font-size: 1.2rem; }
.sw-start__card p { margin: 0; color: var(--sw-text-2); line-height: 1.5; }
.sw-start__go { width: 100%; }
.sw-start__alt { text-align: center; font-size: .88rem; color: var(--sw-muted); }

/* ═══════════════════════════════════════════════════════════════
   MEETS — a new meet in one guided sheet, moving one, and a cancelled one struck through (Gideon, 2026-10-21)
   ═══════════════════════════════════════════════════════════════ */
/* Cancelled: kept on the calendar so families see it is off, but plainly not on. */
.sw-cal__day--galaoff { box-shadow: inset 0 -3px 0 var(--sw-border); text-decoration: line-through; color: var(--sw-muted); }
.sw-plancal__row--off, .sw-sched__card--off, .sw-meet--off { opacity: .7; }
.sw-plancal__row--off .sw-plancal__time, .sw-sched__card--off { filter: grayscale(.6); }
.sw-meet--off .sw-meet__name, .sw-meet--off h3 { text-decoration: line-through; }
.sw-meetoff { display: flex; gap: .7rem; align-items: flex-start; padding: .8rem 1rem; border-radius: 14px; background: var(--sw-danger-tint); color: var(--sw-danger); margin-bottom: .6rem; }
.sw-meetoff div { display: flex; flex-direction: column; gap: .1rem; }
.sw-meetoff b { color: var(--sw-danger); }
.sw-meetoff span { color: var(--sw-text-2); font-size: .88rem; }

/* The chooser: how is the meet arriving? */
.sw-newmeet { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: .7rem; }
.sw-newmeet__tile { font: inherit; cursor: pointer; text-align: left; display: flex; flex-direction: column; gap: .35rem; padding: 1rem; border-radius: 16px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text); transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.sw-newmeet__tile:hover { transform: translateY(-3px); box-shadow: 0 12px 24px rgba(10, 25, 47, .1); border-color: var(--sw-primary); }
.sw-newmeet__tile:focus-visible { outline: 2px solid var(--sw-primary); outline-offset: 2px; }
.sw-newmeet__tile b { color: var(--sw-navy); font-size: 1rem; margin-top: .3rem; }
.sw-newmeet__tile small { color: var(--sw-muted); font-size: .82rem; line-height: 1.45; }
.sw-newmeet__icon { width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-newmeet__icon--amber { background: var(--sw-accent-tint); color: var(--sw-warning); }
.sw-newmeet__icon--green { background: var(--sw-success-tint); color: var(--sw-success); }
.sw-newmeet__icon--violet { background: color-mix(in srgb, var(--sw-zone-8) 14%, transparent); color: var(--sw-zone-8); }
.sw-newmeet__back { display: inline-flex; align-items: center; gap: .2rem; align-self: flex-start; }
.sw-newmeet__targets { display: flex; flex-direction: column; gap: .45rem; }
.sw-newmeet__target { font: inherit; cursor: pointer; text-align: left; display: flex; align-items: center; gap: .7rem; padding: .55rem .8rem; border-radius: 12px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text); }
.sw-newmeet__target span:last-child { display: flex; flex-direction: column; }
.sw-newmeet__target small { color: var(--sw-muted); font-size: .78rem; }
.sw-newmeet__target.is-on { border-color: var(--sw-primary); background: var(--sw-primary-tint); box-shadow: inset 0 0 0 1px var(--sw-primary); }

/* The pool, drawn: three lanes whose length is the pool's. */
.sw-newmeet__pools { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: .5rem; }
.sw-newmeet__pool { font: inherit; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: .4rem; padding: .7rem .5rem; border-radius: 14px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text-2); }
.sw-newmeet__pool b { font-size: .85rem; }
.sw-newmeet__pool.is-on { border-color: var(--sw-primary); background: var(--sw-primary-tint); color: var(--sw-primary); box-shadow: inset 0 0 0 1px var(--sw-primary); }
.sw-newmeet__lanes { display: flex; flex-direction: column; gap: 3px; width: calc(var(--len, 50) * 1.4px); height: 30px; justify-content: center; padding: 3px; border-radius: 5px; background: color-mix(in srgb, var(--sw-zone-2) 30%, transparent); }
.sw-newmeet__lanes i { display: block; height: 2px; background: color-mix(in srgb, var(--sw-primary) 55%, transparent); border-radius: 2px; }
.sw-newmeet__lanes--open { width: 70px; align-items: center; color: var(--sw-primary); background: color-mix(in srgb, var(--sw-zone-2) 22%, transparent); }
.sw-newmeet__more { border: 1px solid var(--sw-border); border-radius: 12px; padding: .6rem .8rem; background: var(--sw-surface); }
.sw-newmeet__more summary { cursor: pointer; font-weight: 700; color: var(--sw-navy); display: flex; align-items: center; gap: .4rem; }
.sw-newmeet__more summary small { font-weight: 500; color: var(--sw-muted); margin-left: auto; }
.sw-newmeet__more[open] summary { margin-bottom: .6rem; }
.sw-newmeet__preview { display: flex; flex-direction: column; gap: .35rem; }
.sw-newmeet__nudge { display: flex; justify-content: space-between; gap: .5rem; margin-bottom: .5rem; }
.sw-newmeet__nudge .btn { display: inline-flex; align-items: center; gap: .25rem; }
.sw-newmeet__was { display: flex; flex-wrap: wrap; gap: .4rem 1.2rem; font-size: .9rem; color: var(--sw-muted); }
.sw-newmeet__was b { color: var(--sw-navy); }

/* The month picker */
.sw-drange { border: 1px solid var(--sw-border); border-radius: 16px; padding: .7rem; background: var(--sw-surface); }
.sw-drange__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .4rem; }
.sw-drange__head b { color: var(--sw-navy); }
.sw-drange__nav { font: inherit; cursor: pointer; border: 0; background: var(--sw-surface-sunken); width: 32px; height: 32px; border-radius: 999px; display: grid; place-items: center; color: var(--sw-text-2); }
.sw-drange__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px 0; }
.sw-drange__dow { font-size: .68rem; font-weight: 700; color: var(--sw-muted); text-align: center; padding: .2rem 0; text-transform: uppercase; }
.sw-drange__day { position: relative; font: inherit; font-size: .88rem; cursor: pointer; border: 0; background: transparent; height: 38px; color: var(--sw-text); font-variant-numeric: tabular-nums; }
.sw-drange__day:hover { background: var(--sw-surface-sunken); border-radius: 10px; }
.sw-drange__day.is-out { color: var(--sw-muted-2); }
.sw-drange__day.is-weekend:not(.is-in) { color: var(--sw-text-2); font-weight: 600; }
.sw-drange__day.is-today { box-shadow: inset 0 0 0 1.5px var(--sw-border); border-radius: 10px; }
.sw-drange__day.is-in { background: var(--sw-primary-tint); color: var(--sw-primary); border-radius: 0; font-weight: 700; }
.sw-drange__day.is-start { border-top-left-radius: 10px; border-bottom-left-radius: 10px; }
.sw-drange__day.is-end { border-top-right-radius: 10px; border-bottom-right-radius: 10px; }
.sw-drange__day.is-start, .sw-drange__day.is-end { background: var(--sw-primary); color: #fff; }
.sw-drange__dot { position: absolute; left: 50%; bottom: 4px; width: 5px; height: 5px; margin-left: -2.5px; border-radius: 999px; background: var(--sw-sunflower, var(--sw-accent)); }
.sw-drange__day.is-start .sw-drange__dot, .sw-drange__day.is-end .sw-drange__dot { background: #fff; }
.sw-drange__read { display: flex; justify-content: space-between; gap: .6rem; flex-wrap: wrap; margin-top: .6rem; font-size: .9rem; }
.sw-drange__read b { color: var(--sw-navy); }
.sw-drange__read span { color: var(--sw-primary); font-weight: 700; }
.sw-drange__hint { font-size: .78rem; color: var(--sw-muted); margin-top: .2rem; }
.sw-drange__clash { display: flex; align-items: center; gap: .35rem; margin-top: .45rem; padding: .4rem .6rem; border-radius: 10px; background: var(--sw-accent-tint); color: var(--sw-warning); font-size: .82rem; font-weight: 600; }
@media (prefers-reduced-motion: no-preference) {
  .sw-newmeet__tile { animation: sw-ov-rise .35s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i, 0) * 50ms); }
}
.sw-newmeet-form .sw-sheet__section > input.sw-control, .sw-newmeet-form .sw-sheet__cols input.sw-control, .sw-newmeet-form .sw-newmeet__more input.sw-control { width: 100%; }

/* Sessions: the everyday actions as tiles, their panel under them, and Week | Month in place (Gideon, 2026-10-21). */
.sw-qa { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: .6rem; }
/* Six tiles sit as two rows of three rather than five and one left alone (Meets, 2026-10-24). */
.sw-qa--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 760px) { .sw-qa--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 420px) { .sw-qa--3 { grid-template-columns: 1fr; } }
.sw-qa__tile { font: inherit; cursor: pointer; text-align: left; text-decoration: none; display: flex; align-items: center; gap: .7rem; padding: .8rem .9rem; border-radius: 16px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text); transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.sw-qa__tile:hover { transform: translateY(-2px); box-shadow: var(--sw-shadow-sm); border-color: var(--sw-primary); color: var(--sw-text); }
.sw-qa__tile > span:last-child { display: flex; flex-direction: column; min-width: 0; }
.sw-qa__tile b { color: var(--sw-navy); font-size: .95rem; }
.sw-qa__tile small { color: var(--sw-muted); font-size: .78rem; line-height: 1.35; }
.sw-qa__tile.is-on { border-color: var(--sw-primary); background: var(--sw-primary-tint); box-shadow: inset 0 0 0 1px var(--sw-primary); }
.sw-qa__ic { flex-shrink: 0; width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-qa__ic--amber { background: var(--sw-accent-tint); color: var(--sw-warning); }
.sw-qa__ic--green { background: var(--sw-success-tint); color: var(--sw-success); }
.sw-qa__ic--violet { background: color-mix(in srgb, var(--sw-zone-8) 14%, transparent); color: var(--sw-zone-8); }
.sw-qa__panel { border: 1px solid var(--sw-primary); border-radius: 16px; background: var(--sw-surface); padding: .8rem 1rem 1rem; box-shadow: var(--sw-shadow-sm); }
.sw-qa__panelhead { display: flex; align-items: center; justify-content: space-between; margin-bottom: .5rem; }
.sw-qa__panelhead b { color: var(--sw-navy); font-size: 1.05rem; }
.sw-viewswitch { display: inline-flex; padding: 3px; border-radius: 999px; background: var(--sw-surface-sunken); border: 1px solid var(--sw-border); }
.sw-viewswitch button { font: inherit; font-weight: 700; font-size: .88rem; cursor: pointer; border: 0; background: transparent; color: var(--sw-muted); padding: .4rem 1.1rem; border-radius: 999px; }
.sw-viewswitch button.is-on { background: var(--sw-surface); color: var(--sw-navy); box-shadow: var(--sw-shadow-sm); }
.sw-wk__meet { display: flex; align-items: center; gap: .3rem; flex-wrap: wrap; padding: .35rem .5rem; margin-bottom: .35rem; border-radius: 10px; background: var(--sw-accent-tint); color: var(--sw-text); text-decoration: none; font-size: .78rem; font-weight: 700; border-left: 3px solid var(--sw-warning); }
.sw-wk__meet span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-wk__meet small { flex-basis: 100%; font-weight: 500; color: var(--sw-muted); font-size: .7rem; }
.sw-wk__meet--off { background: var(--sw-surface-sunken); border-left-color: var(--sw-border); opacity: .8; }
@media (prefers-reduced-motion: no-preference) {
  .sw-qa__tile { animation: sw-ov-rise .35s cubic-bezier(.2,.8,.2,1) both; animation-delay: calc(var(--i, 0) * 45ms); }
  .sw-qa__panel { animation: sw-ov-rise .25s ease both; }
}

/* ── The clearance letter (Gideon, 2026-10-21): printable on its own ── */
.sw-clr-letter { border: 1px solid var(--sw-border); border-radius: 16px; padding: 1rem 1.1rem; background: var(--sw-surface); display: grid; gap: .6rem; }
.sw-clr-letter p { margin: 0; }
.sw-clr-letter__head { display: flex; gap: .7rem; align-items: center; }
.sw-clr-letter__head div { display: grid; }
.sw-clr-letter__head span { color: var(--sw-muted); font-size: .85rem; }
.sw-clr-letter__badge { width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; background: var(--sw-primary-tint); color: var(--sw-primary); flex: none; }
.sw-clr-letter__ids { display: flex; flex-wrap: wrap; gap: .6rem; }
.sw-clr-letter__ids div { display: grid; gap: .1rem; padding: .55rem .8rem; border-radius: 12px; background: var(--sw-surface-sunken); min-width: 9rem; }
.sw-clr-letter__ids span { font-size: .75rem; color: var(--sw-muted); text-transform: uppercase; letter-spacing: .04em; }
.sw-clr-letter__ids b { font-size: 1.15rem; letter-spacing: .06em; font-variant-numeric: tabular-nums; }
.sw-clr-letter__code { color: var(--sw-primary); }
@media print {
  html.sw-print-letter body * { visibility: hidden; }
  html.sw-print-letter .sw-clr-letter, html.sw-print-letter .sw-clr-letter * { visibility: visible; }
  html.sw-print-letter .sw-clr-letter { position: absolute; left: 0; top: 0; width: 100%; border: none; }
}
.sw-attn-note { display: flex; gap: .5rem; align-items: flex-start; padding: .65rem .8rem; border-radius: 12px; background: var(--sw-accent-tint); color: var(--sw-text); }
.sw-attn-note .sw-icon, .sw-attn-note svg { flex: none; color: var(--sw-accent); margin-top: .15rem; }
.sw-sessions__hint { display: flex; align-items: center; gap: .4rem; margin: 0 0 .5rem; }

/* ── The session page without tabs (Gideon, 2026-10-21): tiles under the hero, workout and register side by side ── */
.sw-sstats { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: .6rem; }
.sw-sstat { font: inherit; text-align: left; color: var(--sw-text); display: flex; gap: .7rem; align-items: center; padding: .75rem .9rem; border-radius: 16px; border: 1px solid var(--sw-border); background: var(--sw-surface); min-width: 0; }
.sw-sstat div { display: grid; min-width: 0; }
.sw-sstat b { font-size: 1rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-sstat small { color: var(--sw-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sw-sstat--link { cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
.sw-sstat--link:hover { transform: translateY(-2px); box-shadow: var(--sw-shadow-sm); }
.sw-sstat--live { border-color: var(--sw-success); background: color-mix(in srgb, var(--sw-success) 8%, var(--sw-surface)); }
.sw-sstat--live .sw-sstat__icon { background: var(--sw-success); color: #fff; animation: sw-pulse 1.8s ease-in-out infinite; }
.sw-sstat__icon { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; flex: none; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-sstat__icon--sea { background: color-mix(in srgb, var(--sw-zone-3, #0ea5e9) 18%, var(--sw-surface)); color: var(--sw-zone-3, #0ea5e9); }
.sw-sstat__icon--sun { background: var(--sw-accent-tint); color: var(--sw-accent); }
.sw-sstat .sw-pring { width: 40px; height: 40px; flex: none; }
@keyframes sw-pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--sw-success) 45%, transparent); } 50% { box-shadow: 0 0 0 6px transparent; } }
.sw-sessgrid { display: flex; flex-direction: column; gap: 1.25rem; }
.sw-sessgrid--regfirst .sw-sesscol--register { order: -1; }
.sw-sesscol { min-width: 0; display: flex; flex-direction: column; gap: .75rem; scroll-margin-top: 1rem; }
@media (min-width: 1100px) {
  .sw-sessgrid--two { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(320px, 1fr); align-items: start; }
  .sw-sessgrid--two .sw-sesscol--register { order: 0; position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow: auto; padding: .9rem; border: 1px solid var(--sw-border); border-radius: 16px; background: var(--sw-surface); }
}

/* ── The session as a poster (Gideon, 2026-10-21): squad-coloured water, a countdown, a progress track ── */
.sw-shero { position: relative; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.25rem; align-items: end;
  padding: 1.4rem 1.5rem 2.2rem; border-radius: 20px; color: var(--squad-ink, #fff);
  /* The squad's own colour, exactly as picked in the workout editor, deepening to a darker shade of the same hue
     (SquadColour.Style) — never towards navy, which changed how the colour read (Gideon, 2026-10-24). */
  background: linear-gradient(135deg, var(--squad-deep, var(--squad)) 0%, var(--squad) 70%); }
.sw-shero__water { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 56px; pointer-events: none; }
.sw-shero__water path:first-child { fill: rgba(255,255,255,.10); }
.sw-shero__water path:last-child { fill: rgba(255,255,255,.16); }
.sw-shero__main, .sw-shero__clock { position: relative; z-index: 1; min-width: 0; }
.sw-shero__kicker { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; font-size: .9rem; opacity: .95; }
.sw-shero__pill { padding: .15rem .6rem; border-radius: 999px; background: color-mix(in srgb, currentColor 16%, transparent); font-weight: 700; font-size: .75rem; letter-spacing: .05em; text-transform: uppercase; }
.sw-shero__pill--soft { background: rgba(255,255,255,.12); }
.sw-shero__title { font-size: clamp(1.6rem, 3.2vw, 2.3rem); font-weight: 800; line-height: 1.1; margin-top: .45rem; }
.sw-shero__sub { opacity: .85; margin-top: .15rem; }
.sw-shero__meta { display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; margin-top: .7rem; font-size: .95rem; }
.sw-shero__meta span { display: inline-flex; gap: .35rem; align-items: center; }
.sw-shero__clock { text-align: right; display: grid; gap: .25rem; justify-items: end; min-width: 11rem; }
.sw-shero__clocklabel { font-size: .75rem; text-transform: uppercase; letter-spacing: .08em; opacity: .85; }
.sw-shero__clockbig { font-size: clamp(1.5rem, 3vw, 2.2rem); font-weight: 800; font-variant-numeric: tabular-nums; }
.sw-shero__track { width: 11rem; height: 8px; border-radius: 999px; background: color-mix(in srgb, currentColor 22%, transparent); overflow: hidden; }
.sw-shero__track i { display: block; height: 100%; border-radius: inherit; background: currentColor; }
.sw-shero--live .sw-shero__clocklabel::before { content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #4ade80; margin-right: .4rem; animation: sw-pulse 1.8s infinite; }
.sw-shero--off { filter: grayscale(.7); }
@media (max-width: 640px) { .sw-shero { grid-template-columns: 1fr; } .sw-shero__clock { justify-items: start; text-align: left; } }

/* ── Workout: three ways in ── */
.sw-wstart { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: .75rem; }
.sw-wstart__card { font: inherit; cursor: pointer; text-align: left; display: grid; gap: .3rem; padding: 1rem; border-radius: 18px; border: 0; color: #fff; min-height: 9rem; align-content: start;
  transition: transform .15s ease, box-shadow .15s ease; box-shadow: var(--sw-shadow-sm); }
.sw-wstart__card:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(10,25,47,.18); }
.sw-wstart__card b { font-size: 1.05rem; }
.sw-wstart__card small { opacity: .9; line-height: 1.35; }
.sw-wstart__icon { width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; background: rgba(255,255,255,.2); margin-bottom: .35rem; }
.sw-wstart__card--write { background: linear-gradient(135deg, var(--sw-primary), #0ea5e9); }
.sw-wstart__card--copy { background: linear-gradient(135deg, #0f766e, #14b8a6); }
.sw-wstart__card--lib { background: linear-gradient(135deg, #b45309, var(--sw-accent)); }

/* ── Register: a bar that fills as the squad arrives, and a card per swimmer ── */
.sw-rbar { display: flex; height: 12px; border-radius: 999px; overflow: hidden; background: var(--sw-surface-sunken); gap: 2px; }
.sw-rbar i { display: block; min-width: 0; transition: flex .3s ease; }
.sw-rbar__here { background: var(--sw-success); }
.sw-rbar__late { background: var(--sw-accent); }
.sw-rbar__away { background: var(--sw-danger); }
.sw-rbar__open { background: var(--sw-border); }
.sw-rkey { display: flex; flex-wrap: wrap; gap: .3rem 1rem; font-size: .85rem; color: var(--sw-text-2); }
.sw-rkey span { display: inline-flex; gap: .35rem; align-items: center; }
.sw-rkey i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.sw-rkey__here { background: var(--sw-success); } .sw-rkey__away { background: var(--sw-danger); } .sw-rkey__open { background: var(--sw-border); }
.sw-rhint { margin: 0; font-size: .85rem; }
.sw-rgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: .6rem; }
.sw-rcard { position: relative; border-radius: 16px; border: 2px solid var(--sw-border); background: var(--sw-surface); transition: background .15s ease, border-color .15s ease, transform .1s ease; }
.sw-rcard:active { transform: scale(.97); }
.sw-rcard__tap { font: inherit; color: inherit; width: 100%; background: none; border: 0; cursor: pointer; display: grid; justify-items: center; gap: .3rem; padding: .85rem .5rem .7rem; text-align: center; }
.sw-rcard__tap:disabled { cursor: default; }
.sw-rcard__av { position: relative; width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; font-weight: 800; font-size: .95rem; color: #fff; background: var(--av); }
.sw-rcard__badge { position: absolute; right: -4px; bottom: -4px; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; color: #fff; border: 2px solid var(--sw-surface); font-style: normal; }
.sw-rcard__name { font-weight: 700; font-size: .9rem; line-height: 1.15; }
.sw-rcard__name span { display: block; font-weight: 500; color: var(--sw-text-2); font-size: .8rem; }
.sw-rcard__line { font-size: .72rem; color: var(--sw-muted); min-height: 1em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.sw-rcard__more { position: absolute; top: 4px; right: 4px; border: 0; background: transparent; color: var(--sw-muted); font: inherit; font-weight: 800; letter-spacing: 1px; cursor: pointer; border-radius: 8px; padding: 0 .35rem; }
.sw-rcard__more:hover, .sw-rcard__more.is-filled { background: var(--sw-surface-sunken); color: var(--sw-text); }
.sw-rcard__flag { position: absolute; top: 8px; left: 8px; width: 9px; height: 9px; border-radius: 50%; background: var(--sw-primary); }
.sw-rcard__flag--danger { background: var(--sw-danger); }
.sw-rcard--here { border-color: var(--sw-success); background: color-mix(in srgb, var(--sw-success) 10%, var(--sw-surface)); }
.sw-rcard--here .sw-rcard__badge { background: var(--sw-success); }
.sw-rcard--here .sw-rcard__line { color: var(--sw-success); font-weight: 600; }
.sw-rcard--late { border-color: var(--sw-accent); background: var(--sw-accent-tint); }
.sw-rcard--late .sw-rcard__badge { background: var(--sw-accent); }
.sw-rcard--late .sw-rcard__line { color: #b45309; font-weight: 600; }
.sw-rcard--away { border-color: color-mix(in srgb, var(--sw-danger) 55%, var(--sw-border)); background: color-mix(in srgb, var(--sw-danger) 7%, var(--sw-surface)); }
.sw-rcard--away .sw-rcard__av { filter: grayscale(.8); opacity: .6; }
.sw-rcard--away .sw-rcard__badge { background: var(--sw-danger); }
.sw-rcard--away .sw-rcard__line { color: var(--sw-danger); font-weight: 600; }
.sw-sessgrid--two .sw-sesscol--register .sw-rgrid { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }

/* ── Individual session: picking the swimmers (2026-10-21) ── */
.sw-indiv { display: grid; gap: .6rem; }
.sw-indiv__picked { display: flex; flex-wrap: wrap; gap: .4rem; }
.sw-indiv__chip { font: inherit; display: inline-flex; align-items: center; gap: .45rem; padding: .25rem .6rem .25rem .25rem; border-radius: 999px; border: 1px solid var(--sw-primary); background: var(--sw-primary-tint); color: var(--sw-text); cursor: pointer; font-weight: 600; }
.sw-indiv__chip .sw-rcard__av { width: 28px; height: 28px; font-size: .7rem; }
.sw-indiv__list { max-height: 15rem; overflow: auto; }
.sw-indiv__squads { display: flex; flex-wrap: wrap; gap: .4rem; }
.sw-indiv__squad { font: inherit; cursor: pointer; display: inline-flex; align-items: center; gap: .4rem; padding: .35rem .75rem; border-radius: 999px; border: 1px solid var(--sw-border); background: var(--sw-surface); color: var(--sw-text); font-weight: 600; font-size: .9rem; }
.sw-indiv__squad i { width: 10px; height: 10px; border-radius: 50%; background: var(--sq, var(--sw-primary)); }
.sw-indiv__squad span { font-weight: 500; color: var(--sw-muted); font-size: .8rem; }
.sw-indiv__squad.is-on { border-color: var(--sq, var(--sw-primary)); background: color-mix(in srgb, var(--sq, var(--sw-primary)) 16%, var(--sw-surface)); }

/* ── The zone editor (2026-10-21) ── */
.sw-zed { display: grid; gap: .6rem; }
.sw-zed__row { display: grid; grid-template-columns: auto minmax(7rem, 1fr) auto auto minmax(10rem, 1.6fr) auto; gap: .6rem; align-items: center; padding: .7rem .8rem; border-radius: 14px; border: 1px solid var(--sw-border); border-left: 6px solid var(--zc); background: var(--sw-surface); }
.sw-zed__swatch { width: 34px; height: 34px; border-radius: 10px; background: var(--zc); }
.sw-zed__hr { display: inline-flex; align-items: center; gap: .3rem; color: var(--sw-muted); font-size: .85rem; }
.sw-zed__hr input { width: 4.2rem; }
.sw-zed__colours { display: flex; flex-wrap: wrap; gap: .3rem; }
.sw-zed__dot { width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent; background: var(--zc); cursor: pointer; padding: 0; }
.sw-zed__dot.is-on { border-color: var(--sw-text); box-shadow: 0 0 0 2px var(--sw-surface) inset; }
.sw-zed__move { display: flex; gap: .2rem; }
.sw-zed__scale { display: flex; height: 14px; border-radius: 999px; overflow: hidden; }
.sw-zed__scale i { display: block; }
@media (max-width: 900px) { .sw-zed__row { grid-template-columns: auto 1fr auto; } .sw-zed__row > :nth-child(n+4) { grid-column: 1 / -1; } }

/* ── Polar: the link card and the planned-against-actual heart-rate chart (2026-10-22) ── */
.sw-polar { display: flex; flex-direction: column; gap: var(--sw-space-2); padding: var(--sw-space-3) var(--sw-space-4); margin: var(--sw-space-3) 0;
  background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 12px; box-shadow: var(--sw-shadow-sm); }
.sw-polar__head { display: flex; align-items: center; gap: var(--sw-space-3); }
.sw-polar__mark { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 10px; background: #fee2e2; color: #dc2626; flex-shrink: 0; }
.sw-polar__title { flex: 1; min-width: 0; }
.sw-polar__sub { font-size: .85rem; color: var(--sw-text-2); }
.sw-polar__list { display: flex; flex-direction: column; gap: 4px; }
.sw-polar__row { display: flex; align-items: center; gap: var(--sw-space-2); width: 100%; padding: .45rem .6rem; border-radius: 10px; border: 1px solid var(--sw-border);
  background: var(--sw-surface); font: inherit; font-size: .85rem; color: var(--sw-text); text-align: left; cursor: pointer; }
.sw-polar__row:hover { background: var(--sw-surface-sunken); }
.sw-polar__row--loose { cursor: default; color: var(--sw-muted); }
.sw-polar__when { min-width: 8.5rem; color: var(--sw-text-2); }
.sw-polar__what { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-polar__nums { color: var(--sw-muted); white-space: nowrap; }
.sw-polar__ask { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sw-space-2); font-size: .85rem; }
.sw-hist__hr { display: inline-flex; align-items: center; gap: 6px; margin: -2px 0 6px .9rem; padding: .2rem .6rem; border-radius: 999px; border: 0;
  background: #fee2e2; color: #b91c1c; font: inherit; font-size: .78rem; font-weight: 600; cursor: pointer; }
.sw-hrchart { display: grid; gap: var(--sw-space-3); }
.sw-hrchart__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: end; gap: var(--sw-space-3); }
.sw-hrchart__when { font-size: .85rem; color: var(--sw-text-2); }
.sw-hrchart__score { display: flex; flex-wrap: wrap; gap: var(--sw-space-5); }
.sw-hrchart__score div { display: grid; }
.sw-hrchart__score b { font-size: 1.6rem; line-height: 1; font-weight: 700; color: var(--sw-navy); font-variant-numeric: tabular-nums; }
.sw-hrchart__score span { font-size: .78rem; color: var(--sw-muted); }
.sw-hrchart svg { width: 100%; height: auto; display: block; }
.sw-hrchart__grid { stroke: var(--sw-border); stroke-width: 1; }
.sw-hrchart__axis { font-size: 11px; fill: var(--sw-muted); font-variant-numeric: tabular-nums; }
.sw-hrchart__band { fill-opacity: .32; }
.sw-hrchart__edge { stroke-width: 2; }
.sw-hrchart__line { fill: none; stroke: var(--sw-navy); stroke-width: 1.6; stroke-linejoin: round; }
.sw-hrchart__key { display: flex; flex-wrap: wrap; gap: 8px 16px; font-size: .85rem; color: var(--sw-muted); }
.sw-hrchart__key i { display: inline-block; width: 12px; height: 12px; border-radius: 2px; margin-right: 6px; vertical-align: -1px; }
.sw-hrchart__keyline { width: 18px !important; height: 2px !important; border-radius: 0 !important; background: var(--sw-navy); vertical-align: 3px !important; }
.sw-hrchart__note { margin: 0; font-size: .8rem; color: var(--sw-muted); font-style: italic; }
.sw-hrtable { overflow-x: auto; }
.sw-hrtable table { border-collapse: collapse; width: 100%; font-size: .9rem; font-variant-numeric: tabular-nums; }
.sw-hrtable th { font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--sw-muted); text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--sw-border); white-space: nowrap; }
.sw-hrtable td { padding: 9px 10px; border-bottom: 1px solid var(--sw-border); white-space: nowrap; }
.sw-hrtable__set { font-family: ui-monospace, Menlo, monospace; font-size: .84rem; max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.sw-hrtable__chip { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: .76rem; font-weight: 600; line-height: 1.5; }
.sw-hrtable__verdict { font-weight: 600; }
.sw-hrtable__verdict.is-good { color: var(--sw-success); }
.sw-hrtable__verdict.is-over { color: var(--sw-danger); }
.sw-hrtable__verdict.is-under { color: #b86a00; }
.sw-sheet--wide { max-width: 960px; }

/* The workout box's bubbles (Gideon, 2026-10-23): each zone's distance and each squad's, inside the box, not folded under it. */
.sw-wbubbles { margin-top: .35rem; }
.sw-wbubble { display: inline-flex; align-items: center; gap: .4rem; padding: .3rem .7rem; border-radius: 999px; border: 1px solid var(--sw-border); background: var(--sw-surface-sunken); font-size: .85rem; font-weight: 600; color: var(--sw-text); }
.sw-wbubble i { width: .65rem; height: .65rem; border-radius: 50%; flex: none; }
.sw-wbubble--rest i { background: var(--sw-border); }

/* The squad heart-rate card's swimmer list — each row opens that swimmer's own graph on their profile. */
.sw-hrsquad { display: grid; gap: .25rem; margin-top: .4rem; }
.sw-hrsquad__row { display: grid; grid-template-columns: minmax(0, 1.4fr) auto minmax(0, 1fr) 16px; gap: .75rem; align-items: center; padding: .5rem .6rem; border-radius: 10px; color: var(--sw-text); text-decoration: none; font-size: .9rem; }
.sw-hrsquad__row:hover { background: var(--sw-surface-sunken); }
.sw-hrsquad__name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 520px) { .sw-hrsquad__row { grid-template-columns: minmax(0, 1fr) auto 16px; } .sw-hrsquad__row > .sw-muted-text { display: none; } }

/* The season-calendar import's review list (Gideon, 2026-10-23): one block per gala read, unticked ones faded. */
.sw-simport { display: grid; gap: .5rem; }
.sw-simport__row { border: 1px solid var(--sw-border); border-radius: 12px; padding: .6rem .7rem; display: grid; gap: .45rem; background: var(--sw-surface); }
.sw-simport__row.is-off { opacity: .55; }
.sw-simport__top { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.sw-simport__name { flex: 1 1 14rem; min-width: 0; font-weight: 600; }
.sw-simport__fields { display: grid; grid-template-columns: 9.5rem 9.5rem minmax(7rem, 1fr) 11rem; gap: .45rem; }
.sw-simport__fields .sw-control { width: 100%; box-sizing: border-box; }
.sw-simport__levels { margin-top: 0; }
.sw-simport__levels .sw-check { padding: .25rem .6rem; font-size: .8rem; }
@media (max-width: 700px) { .sw-simport__fields { grid-template-columns: 1fr 1fr; } }

/* Universal results waiting for a coach (2026-10-23): who and which swim, ours against the file's, then the answer. */
.sw-uresult { display: grid; grid-template-columns: minmax(0, 1.4fr) auto auto; gap: .9rem; align-items: center; padding: .7rem .8rem; border-bottom: 1px solid var(--sw-border); }
.sw-uresult:last-child { border-bottom: 0; }
.sw-uresult__who { display: flex; flex-direction: column; min-width: 0; }
.sw-uresult__who small { color: var(--sw-muted); }
.sw-uresult__times { display: flex; align-items: center; gap: .6rem; font-variant-numeric: tabular-nums; }
.sw-uresult__times span { display: flex; flex-direction: column; }
.sw-uresult__times small { font-size: .7rem; color: var(--sw-muted); text-transform: uppercase; letter-spacing: .04em; }
@media (max-width: 640px) { .sw-uresult { grid-template-columns: 1fr; } }

/* The workout writer's Options panel and tidy note (Gideon, 2026-10-24). */
.sw-writeropts { display: grid; gap: .25rem; padding: .75rem .9rem; border: 1px solid var(--sw-border); border-radius: 12px; background: var(--sw-surface); }
.sw-writertoggle--idle, .sw-writertoggle:disabled { opacity: .45; cursor: default; }
.sw-writer__tidy { display: flex; gap: .75rem; align-items: center; flex-wrap: wrap; padding: .45rem .8rem; border-radius: 10px; background: var(--sw-success-tint, #d1fae5); color: var(--sw-success); font-size: .88rem; font-weight: 600; }
.sw-writer__tidy--held { background: var(--sw-surface-sunken); color: var(--sw-text-2); }
/* The symbol row above a phone's keyboard (J). */
.sw-symrow { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; display: flex; gap: .3rem; padding: .35rem .5rem calc(.35rem + env(safe-area-inset-bottom, 0px)); background: var(--sw-surface-sunken); border-top: 1px solid var(--sw-border); overflow-x: auto; }
.sw-symrow button { flex: 1 0 2.4rem; min-height: 2.4rem; border: 0; border-radius: 8px; background: var(--sw-primary-tint); color: var(--sw-primary); font: 600 1rem ui-monospace, Menlo, monospace; }
/* Suggestions and saved blocks (F, G): a short list just under the caret. */
.sw-suggest { position: absolute; z-index: 30; min-width: 14rem; max-width: min(22rem, 90vw); background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 10px; box-shadow: 0 8px 24px rgba(10, 25, 47, .14); overflow: hidden; font-size: .88rem; }
.sw-suggest__item { display: flex; justify-content: space-between; gap: 1rem; padding: .4rem .7rem; cursor: pointer; }
.sw-suggest__item + .sw-suggest__item { border-top: 1px solid var(--sw-border); }
.sw-suggest__item { align-items: baseline; }
.sw-suggest__item small { display: inline; color: var(--sw-muted); white-space: nowrap; font-size: .78rem; }
.sw-suggest__item--on, .sw-suggest__item:hover { background: var(--sw-primary-tint); }
/* Lines Tidy just rewrote, in green until the coach types again (2026-10-24). */
.sw-wtext__row--tidied { background: var(--sw-success-tint); border-radius: 4px; }
.sw-wtext__row--tidied .sw-wtext__say { color: var(--sw-success); }
.sw-audiencechip--finished { opacity: .6; }

/* ── The page rules' parts (Gideon, 2026-10-24; CLAUDE.md §7 "The ten page rules") ───────────────── */
@property --ring { syntax: '<number>'; inherits: false; initial-value: 0; }
.sw-dial { width: var(--ring-size, 56px); aspect-ratio: 1; flex: none; border-radius: 50%; display: inline-grid; place-items: center;
  background: conic-gradient(var(--ring-c) calc(var(--ring) * 1%), var(--sw-surface-sunken) 0); animation: sw-dial-sweep 1.3s cubic-bezier(.2,.8,.2,1) both; }
.sw-dial__label { width: 78%; aspect-ratio: 1; border-radius: 50%; background: var(--sw-surface); display: grid; place-items: center;
  font-weight: 800; font-size: calc(var(--ring-size, 56px) * .2); color: var(--sw-navy); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sw-dial--dark { background: conic-gradient(currentColor calc(var(--ring) * 1%), color-mix(in srgb, currentColor 22%, transparent) 0); }
.sw-dial--dark .sw-dial__label { background: color-mix(in srgb, var(--squad-deep, #0a192f) 85%, transparent); color: inherit; }
@keyframes sw-dial-sweep { from { --ring: 0; } }
.sw-faces { display: inline-flex; align-items: center; }
.sw-faces__f { width: 30px; height: 30px; border-radius: 50%; margin-left: -8px; border: 2px solid var(--sw-surface); background: var(--face, var(--sw-muted));
  color: var(--face-ink, #fff); display: grid; place-items: center; font-size: .66rem; font-weight: 800; text-decoration: none; transition: transform .15s ease; }
.sw-faces__f:first-child { margin-left: 0; }
a.sw-faces__f:hover { transform: translateY(-2px); z-index: 1; color: var(--face-ink, #fff); }
.sw-faces__f--more { background: var(--sw-surface-sunken); color: var(--sw-text-2); }
/* What needs you (rule 2): a count and a tap each. */
.sw-attnstrip { display: flex; flex-wrap: wrap; gap: .5rem; }
.sw-attnstrip__item { flex: 1 1 13rem; display: flex; align-items: center; gap: .65rem; padding: .6rem .8rem; border-radius: 14px; font-weight: 600; font-size: .88rem;
  text-decoration: none; border: 0; text-align: left; font-family: inherit; cursor: pointer; background: var(--sw-primary-tint); color: var(--sw-primary); }
.sw-attnstrip__item b { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.sw-attnstrip__item--warn { background: var(--sw-accent-tint); color: #b45309; }
.sw-attnstrip__item--bad { background: var(--sw-danger-tint, #fee2e2); color: var(--sw-danger); }
.sw-attnstrip__item:hover { filter: brightness(.97); }
/* A bar that fills once (rules 3 and 6). */
.sw-fill { height: 9px; border-radius: 999px; background: var(--sw-surface-sunken); overflow: hidden; }
.sw-fill > i { display: block; height: 100%; border-radius: inherit; background: var(--fill-c, var(--sw-primary)); transform-origin: left; animation: sw-fill-grow 1.1s cubic-bezier(.2,.8,.2,1) both; }
@keyframes sw-fill-grow { from { transform: scaleX(0); } }
/* The posters' water drifts (rule 6). */
.sw-shero__water { animation: sw-water-bob 7s ease-in-out infinite alternate; }
@keyframes sw-water-bob { from { transform: translateY(0) scaleX(1.02); } to { transform: translateY(5px) scaleX(1.06); } }
@media (prefers-reduced-motion: reduce) {
  .sw-dial, .sw-fill > i, .sw-shero__water { animation: none; }
}
/* The Meets page's poster is a link to the gala; its clock carries a ring beside the countdown. */
a.sw-shero--link { text-decoration: none; color: var(--squad-ink, #fff); transition: transform .15s ease, box-shadow .15s ease; }
a.sw-shero--link:hover { transform: translateY(-2px); box-shadow: var(--sw-shadow-sm); color: var(--squad-ink, #fff); }
.sw-shero__clock--row { display: flex; align-items: center; gap: 1rem; }
.sw-shero__clocktext { display: grid; justify-items: end; gap: .2rem; }
/* The season as a timeline (rule 3). */
.sw-tline { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 16px; overflow-x: auto; }
.sw-tline__inner { position: relative; min-width: 720px; height: 112px; }
.sw-tline__axis { position: absolute; left: 2%; right: 2%; top: 68px; height: 2px; background: var(--sw-border); }
.sw-tline__month { position: absolute; top: 88px; transform: translateX(-50%); font-size: .68rem; color: var(--sw-muted); text-transform: uppercase; letter-spacing: .05em; }
.sw-tline__now { position: absolute; top: 8px; height: 76px; width: 2px; background: var(--sw-danger); border-radius: 2px; }
.sw-tline__gala { position: absolute; top: 0; transform: translateX(-50%); display: grid; justify-items: center; text-decoration: none; color: var(--sw-text); }
.sw-tline__gala span { order: -1; font-size: .7rem; font-weight: 700; white-space: nowrap; padding: 1px 6px; border-radius: 6px; background: var(--sw-surface); }
.sw-tline__gala--lane1 span { margin-top: 4px; } .sw-tline__gala--lane2 span { margin-top: 20px; } .sw-tline__gala--lane0 span { margin-top: 36px; }
.sw-tline__gala i { width: 16px; height: 16px; border-radius: 50%; border: 3px solid var(--sw-surface); box-shadow: 0 0 0 2px var(--g); background: var(--g); position: absolute; top: 61px; }
.sw-tline__gala--past { --g: #94a3b8; color: var(--sw-muted); }
.sw-tline__gala--open { --g: var(--sw-primary); }
.sw-tline__gala--later { --g: var(--sw-accent); }
.sw-tline__gala--next { --g: var(--sw-primary); }
.sw-tline__gala--next i { animation: sw-pulse 1.8s infinite; }
.sw-tline__gala:hover span { color: var(--sw-primary); }
@media (prefers-reduced-motion: reduce) { .sw-tline__gala--next i { animation: none; } }
/* A meet's entries at a glance (rules 3 and 7): a ring with a bar per squad, and the faces of who is missing. */
.sw-meetfill { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: .75rem; }
@media (max-width: 760px) { .sw-meetfill { grid-template-columns: 1fr; } }
.sw-meetfill__card { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 16px; padding: 1rem; display: grid; gap: .6rem; align-content: start; min-width: 0; }
.sw-meetfill__card .btn { justify-self: start; }
.sw-meetfill__row { display: flex; gap: 1.1rem; align-items: center; min-width: 0; }
.sw-meetfill__squads { flex: 1; display: grid; gap: .3rem; min-width: 0; }
.sw-meetfill__head { display: flex; justify-content: space-between; gap: .5rem; margin-bottom: .2rem; }
.sw-meetfill__head span, .sw-meetfill__sq span:last-child { color: var(--sw-muted); font-size: .82rem; font-variant-numeric: tabular-nums; }
.sw-meetfill__sq { display: flex; justify-content: space-between; font-size: .82rem; font-weight: 600; }
/* The Squads page: each squad a small poster in its own colour (rules 1, 3, 5, 7). */
.sw-sqgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: .75rem; }
.sw-sqposter { display: grid; border-radius: 18px; overflow: hidden; background: var(--sw-surface); border: 1px solid var(--sw-border); text-decoration: none; color: var(--sw-text);
  transition: transform .15s ease, box-shadow .15s ease; }
.sw-sqposter:hover { transform: translateY(-3px); box-shadow: var(--sw-shadow-sm); color: var(--sw-text); }
.sw-sqposter__top { position: relative; overflow: hidden; color: var(--squad-ink, #fff); padding: .85rem 1rem 1.3rem;
  background: linear-gradient(120deg, var(--squad) 30%, var(--squad-deep, var(--squad))); }
.sw-sqposter__top .sw-shero__water { height: 26px; }
.sw-sqposter__top .sw-shero__water path { fill: rgba(255,255,255,.16); }
.sw-sqposter__name { position: relative; font-size: 1.25rem; font-weight: 800; line-height: 1.15; }
.sw-sqposter__when { position: relative; font-size: .82rem; opacity: .92; margin-top: .15rem; }
.sw-sqposter__when--live span::before { content: ""; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #4ade80; margin-right: .4rem; animation: sw-pulse 1.8s infinite; }
.sw-sqposter__body { display: flex; gap: .9rem; align-items: center; padding: .85rem 1rem 1rem; min-width: 0; }
.sw-sqposter__facts { flex: 1; display: grid; gap: .35rem; min-width: 0; }
.sw-sqposter__line { display: flex; justify-content: space-between; gap: .5rem; font-size: .8rem; color: var(--sw-text-2); }
.sw-sqposter__line span:last-child { color: var(--sw-muted); text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-sqposter__line span:first-child { white-space: nowrap; flex: none; }
.sw-sqposter__line span:last-child { min-width: 0; }
@media (prefers-reduced-motion: reduce) { .sw-sqposter__when--live span::before { animation: none; } }
/* Status chips by meaning (rule 5). */
.sw-chip--ok { background: var(--sw-success-tint); color: var(--sw-success); }
.sw-chip--warn { background: var(--sw-accent-tint); color: #b45309; }
.sw-chip--bad { background: var(--sw-danger-tint); color: var(--sw-danger); }
/* A squad's week as a strip (rules 3 and 6). */
.sw-weekstrip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .4rem; }
.sw-weekstrip__day { background: var(--sw-surface); border: 1px solid var(--sw-border); border-radius: 14px; padding: .5rem .35rem; display: grid; gap: .3rem; justify-items: center; align-content: start; min-height: 6.5rem; min-width: 0; }
.sw-weekstrip__day b { font-size: .95rem; color: var(--sw-navy); }
.sw-weekstrip__dow { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--sw-muted); }
.sw-weekstrip__day--today { border-color: var(--squad); box-shadow: 0 0 0 2px color-mix(in srgb, var(--squad) 35%, transparent); }
.sw-weekstrip__s { width: 100%; text-align: center; font-size: .72rem; font-weight: 700; padding: .3rem 0; border-radius: 8px; text-decoration: none;
  border: 2px solid var(--squad); color: var(--sw-navy); font-variant-numeric: tabular-nums; animation: sw-pop .4s ease both; }
.sw-weekstrip__s--done { background: var(--squad); color: var(--squad-ink, #fff); }
.sw-weekstrip__s--live { background: color-mix(in srgb, var(--squad) 25%, var(--sw-surface)); animation: sw-pulse 1.8s infinite; }
.sw-weekstrip__s--off { border-style: dashed; border-color: var(--sw-border); color: var(--sw-muted); text-decoration: line-through; }
.sw-weekstrip__s:hover { filter: brightness(1.05); transform: translateY(-1px); }
@keyframes sw-pop { from { opacity: 0; transform: translateY(4px); } }
@media (max-width: 560px) { .sw-weekstrip { gap: .2rem; } .sw-weekstrip__s { font-size: .62rem; } }
/* Race ready counted for a squad. */
.sw-lights { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; padding: .7rem .9rem; border-radius: 14px; background: var(--sw-surface); border: 1px solid var(--sw-border); text-decoration: none; color: var(--sw-text); }
.sw-lights .sw-label { margin-right: .3rem; }
.sw-lights__go { margin-left: auto; display: inline-flex; align-items: center; gap: .2rem; font-size: .82rem; font-weight: 600; color: var(--sw-primary); }
.sw-lights:hover { border-color: var(--sw-primary); color: var(--sw-text); }
/* A squad's swimmers as faces with an attendance ring each (rules 3 and 7). */
.sw-swgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: .5rem; }
.sw-swcard { display: flex; align-items: center; gap: .7rem; padding: .6rem .75rem; border-radius: 14px; background: var(--sw-surface); border: 1px solid var(--sw-border); text-decoration: none; color: var(--sw-text); min-width: 0;
  transition: transform .15s ease, border-color .15s ease; }
.sw-swcard:hover { transform: translateY(-2px); border-color: var(--squad); color: var(--sw-text); }
.sw-swcard__face { width: 38px; height: 38px; flex: none; border-radius: 50%; display: grid; place-items: center; background: var(--squad); color: var(--squad-ink, #fff); font-size: .78rem; font-weight: 800; }
.sw-swcard__who { flex: 1; display: grid; min-width: 0; }
.sw-swcard__who b { font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sw-swcard__who small { color: var(--sw-muted); font-size: .76rem; }
@media (prefers-reduced-motion: reduce) { .sw-weekstrip__s, .sw-weekstrip__s--live { animation: none; } }
/* The invoice as a document (billing plan phase 1): paper-white in either theme, as an invoice is, and printed alone. */
.sw-invdoc { background: #fff; color: #0a192f; border-radius: 8px; box-shadow: 0 10px 30px rgba(10,25,47,.12); padding: 2rem 2.1rem; display: grid; gap: 1.2rem;
  max-width: 46rem; width: 100%; margin: 0 auto; font-size: .9rem; }
.sw-invdoc__top { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.sw-invdoc__seller { display: flex; gap: .8rem; align-items: flex-start; }
.sw-invdoc__seller > div { display: grid; gap: .1rem; }
.sw-invdoc__seller b { font-size: 1.05rem; }
.sw-invdoc__seller small, .sw-invdoc__muted { color: #64748b; font-size: .78rem; }
.sw-invdoc__logo { width: 46px; height: 46px; border-radius: 12px; background: #0a192f; color: #fff; display: grid; place-items: center; font-weight: 800; flex: none; }
.sw-invdoc__head { text-align: right; }
.sw-invdoc__head h2 { margin: 0 0 .3rem; font-size: 1.4rem; letter-spacing: -.01em; }
.sw-invdoc__head dl { display: grid; grid-template-columns: auto auto; gap: .1rem .8rem; margin: 0; font-size: .82rem; justify-content: end; }
.sw-invdoc__head dt { color: #64748b; } .sw-invdoc__head dd { margin: 0; }
.sw-invdoc__box { background: #f8fafc; border-radius: 8px; padding: .7rem .85rem; display: grid; gap: .15rem; font-size: .84rem; }
.sw-invdoc__lines { width: 100%; border-collapse: collapse; font-size: .86rem; }
.sw-invdoc__lines th { background: #f1f5f9; color: #64748b; font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; text-align: left; padding: .5rem .6rem; }
.sw-invdoc__lines td { padding: .5rem .6rem; border-bottom: 1px solid #e2e8f0; }
.sw-invdoc__lines .r { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sw-invdoc__minus td { color: #475569; }
.sw-invdoc__lines tfoot td { font-weight: 800; font-size: .95rem; border-top: 2px solid #0a192f; border-bottom: 0; }
.sw-invdoc__due td { color: #b45309; font-size: .88rem; border-top: 0; }
.sw-invdoc__pay { display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; }
.sw-invdoc__pay > .sw-invdoc__box { flex: 1; min-width: 16rem; }
.sw-invdoc__stamp { border: 2px solid #059669; color: #059669; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; padding: .3rem .8rem; border-radius: 6px; transform: rotate(-4deg); }
.sw-invdoc__foot { color: #64748b; font-size: .76rem; border-top: 1px solid #e2e8f0; padding-top: .7rem; }
@media (max-width: 560px) { .sw-invdoc { padding: 1.2rem; } .sw-invdoc__head { text-align: left; } .sw-invdoc__head dl { justify-content: start; } }
@media print {
  html.sw-print-invoice body * { visibility: hidden; }
  html.sw-print-invoice .sw-invdoc, html.sw-print-invoice .sw-invdoc * { visibility: visible; }
  html.sw-print-invoice .sw-invdoc { position: absolute; left: 0; top: 0; box-shadow: none; max-width: none; }
}
.sw-invdoc__credits { display: grid; gap: .2rem; font-size: .84rem; }
.sw-invdoc__credits a { color: #0369a1; font-weight: 600; text-decoration: none; }
