/* H40/50 Finest Planner design system — hand-written, mobile-first, light mode only.
   No build step. Sections:
   01 tokens        02 base/reset     03 app header     04 admin bar
   05 flash         06 main/footer    07 tab bar        08 typography
   09 icons         10 cards          11 status/pills   12 banner
   13 buttons       14 forms          15 name picker    16 poll list
   17 date lists    18 tables         19 season grid    20 courts
   21 segmented     22 utilities      23 desktop     27 pool grid */

/* 01 — tokens */
:root {
  color-scheme: light;
  /* brand */
  --brand: #10331f;
  --brand-2: #1d5c38;
  --accent: #cdea3f;
  --on-accent: #1e2b07;
  --sage: #9db3a4;      /* inactive on dark green */
  /* surfaces */
  --bg: #f1f4ef;
  --surface: #ffffff;
  --surface-2: #e9efe7;
  --line: #e3e9e1;
  /* text */
  --text: #17211a;
  --dim: #647167;
  /* status */
  --ok: #177d3a;
  --warn: #b35900;
  --bad: #b3261e;
  --dot: #ff7d70;       /* action-needed badge */
  /* soft fills */
  --ok-soft: color-mix(in srgb, var(--ok) 13%, transparent);
  --warn-soft: color-mix(in srgb, var(--warn) 13%, transparent);
  --bad-soft: color-mix(in srgb, var(--bad) 11%, transparent);
  --act-soft: color-mix(in srgb, var(--brand-2) 12%, transparent);
  /* type scale */
  --fs-xs: 0.75rem;
  --fs-sm: 0.875rem;
  --fs-md: 1rem;
  --fs-lg: 1.25rem;
  --fs-xl: 1.6rem;
  --fs-2xl: 1.75rem;
  /* spacing */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px;
  /* radii */
  --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-full: 999px;
  /* elevation */
  --shadow-1: 0 1px 2px rgba(15, 35, 22, .06), 0 6px 16px rgba(15, 35, 22, .06);
  --shadow-seg: 0 1px 3px rgba(10, 25, 15, .12);
  /* chrome */
  --tap: 44px;
  --tabbar-h: 64px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}

/* 02 — base/reset */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 16px;
  line-height: 1.45;
}
a { color: var(--brand-2); }

/* 03 — app header */
.appheader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: calc(var(--sp-2) + var(--safe-t)) var(--sp-4) var(--sp-2);
}
.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--text);
  text-decoration: none;
  min-width: 0;
}
.logoimg { border-radius: var(--r-full); display: block; object-fit: cover; }
.brandname {
  font-size: 17px; font-weight: 800; letter-spacing: -0.01em; white-space: nowrap;
  /* Shrinkable + clipped: the wordmark used to spill over the name chip and the
     desktop nav instead of giving way. Guard, not the primary fit — see 03b. */
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
/* 03b — wordmark length. „H40/50 Finest Planner" is 184px at 17px, which does not
   fit beside logo + name chip + shield on a phone, nor beside the desktop nav
   until ~900px. Short mark „H40/50" in both tight bands, full name where it fits. */
.brandfull { display: none; }
@media (min-width: 420px) {
  .brandshort { display: none; }
  .brandfull { display: inline; }
}
@media (min-width: 760px) and (max-width: 899px) {
  .brandshort { display: inline; }
  .brandfull { display: none; }
}
.appnav { display: none; }  /* desktop only, see 23 */
.headright { display: flex; align-items: center; gap: var(--sp-2); }
.whochip {
  background: var(--surface-2);
  border-radius: var(--r-full);
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  max-width: 40vw;
  overflow: hidden;
  text-overflow: ellipsis;
}
.shieldbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  color: var(--dim);
  border-radius: var(--r-full);
}
.shieldbtn .ic { width: 24px; height: 24px; }
.shieldbtn.active { color: var(--warn); }
.shieldbtn.active .ic { fill: var(--warn-soft); }

/* 04 — admin mode bar */
.adminbar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  background: var(--warn-soft);
  color: var(--warn);
  padding: 9px var(--sp-4);
  font-size: 13px;
  font-weight: 700;
}
.adminbar .ic { width: 16px; height: 16px; }
.adminbar a { flex: 1; color: inherit; text-decoration: none; }
.adminbar form { display: contents; }
.adminbar button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: 0;
  padding: 4px 0;
  color: inherit;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

/* 06 — main + footer */
main {
  max-width: 720px;
  margin: 0 auto;
  padding: var(--sp-1) var(--sp-4) var(--sp-5);
}
.footer {
  text-align: center;
  color: var(--dim);
  font-size: var(--fs-xs);
  padding: var(--sp-3) var(--sp-4) calc(var(--tabbar-h) + var(--safe-b) + var(--sp-3));
}

/* 07 — bottom tab bar (mobile) */
.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  background: var(--brand);
  height: calc(var(--tabbar-h) + var(--safe-b));
  padding-bottom: var(--safe-b);
}
.tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--sage);
  font-size: 10.5px;
  font-weight: 600;
  text-decoration: none;
  position: relative;
}
.tab .ic { width: 24px; height: 24px; }
.tab.on { color: var(--accent); }
.tab.on::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -12px;
  width: 24px;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--accent);
}
.tab.off { opacity: .35; pointer-events: none; }
.tab .dot {
  position: absolute;
  top: 8px;
  left: 50%;
  margin-left: 9px;
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--dot);
  border: 2px solid var(--brand);
}

/* 08 — typography */
h1, .page-title { font-size: var(--fs-2xl); font-weight: 800; letter-spacing: -0.02em; margin: 0 0 var(--sp-2); }
h2 { font-size: var(--fs-md); font-weight: 700; margin: var(--sp-4) 0 var(--sp-1); }
h3 { font-size: var(--fs-sm); font-weight: 700; margin: var(--sp-3) 0 var(--sp-1); }
.eyebrow {
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--dim);
}
.dim { color: var(--dim); }
.error { color: var(--bad); font-weight: 600; }
.note { color: var(--warn); }
.open { color: var(--warn); font-weight: 600; }
.names { margin: 2px 0 6px; }
.center { text-align: center; }
:focus-visible { outline: 2px solid var(--brand-2); outline-offset: 2px; }
.tab:focus-visible { outline-color: var(--accent); outline-offset: -2px; }

/* 09 — icons */
.ic { width: 1.25em; height: 1.25em; vertical-align: -0.22em; flex: none; }

/* 10 — cards */
.card {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: var(--sp-4);
  margin: var(--sp-3) 0;
}
.card.narrow { max-width: 420px; margin-left: auto; margin-right: auto; }
.card.center { text-align: center; }
.card.wide { padding: var(--sp-3); }
.card.admin { border-left: 4px solid var(--warn); }
.cardhead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }

/* 11 — status colors, pills, tags */
.st-in { color: var(--ok); }
.st-sit_out { color: var(--dim); }
.st-unavailable { color: var(--bad); }
.st-cancelled { color: var(--warn); }
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--r-full);
  font-size: 13px;
  font-weight: 600;
}
.pill.ok { color: var(--ok); background: var(--ok-soft); }
.pill.warn { color: var(--warn); background: var(--warn-soft); }
.pill.bad { color: var(--bad); background: var(--bad-soft); }
.pill.dim { color: var(--dim); background: var(--surface-2); }
.tag {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: var(--r-full);
  background: var(--surface-2);
  color: var(--dim);
  vertical-align: middle;
}
.tag.ok { background: var(--ok-soft); color: var(--ok); }
.tag.warn { background: var(--warn-soft); color: var(--warn); }

/* 12 — poll banner / callout */
.banner {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  background: var(--accent);
  color: var(--on-accent);
  border-radius: var(--r-lg);
  padding: var(--sp-3) 14px;
  margin: var(--sp-3) 0;
  text-decoration: none;
}
.banner > .ic { width: 22px; height: 22px; }
.bannerbody { flex: 1; display: flex; flex-direction: column; gap: 1px; font-size: 0.85rem; }
.bannerbody strong { font-size: 0.95rem; }
.duecallout {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  background: var(--warn-soft);
  color: var(--warn);
  border-radius: var(--r-md);
  padding: 10px 12px;
  font-size: var(--fs-sm);
}
.duecallout a { color: inherit; text-decoration: underline; }

/* 13 — buttons: ONE action style (tonal green), red = destructive,
   grey = disabled only. Solid brand green is reserved for the tab bar. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap);
  padding: 10px 16px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--act-soft);
  color: var(--brand-2);
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.btn.primary { background: var(--act-soft); color: var(--brand-2); }
.btn.danger { background: var(--bad-soft); color: var(--bad); }
.btn.block { display: flex; width: 100%; margin-top: 10px; }
.btn.small { min-height: 36px; padding: 4px 12px; font-size: 0.85rem; }
.btn:disabled, .btn.off { background: var(--surface-2); color: var(--dim); opacity: .6; cursor: default; }
.actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-3); }
.iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: var(--r-full);
  background: var(--surface-2);
  color: var(--brand-2);
  cursor: pointer;
}
.iconbtn .ic { width: 19px; height: 19px; }
.iconbtn[hidden] { display: none; }

/* 14 — forms */
input[type="text"], input[type="password"], input[type="number"], input[type="date"], select {
  min-height: var(--tap);
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  font-size: 1rem;
  max-width: 100%;
}
input.tiny { min-height: 32px; width: 4.5em; padding: 4px; }
input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--brand-2); }
form.stack { display: flex; flex-direction: column; gap: 10px; }
form.stack label { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); color: var(--dim); }
form.row, div.row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: var(--sp-2) 0; }
/* Pending (unsaved) edits in a combined-save form: amber, like everything admin. */
form[data-dirty] input.dirty, form[data-dirty] select.dirty {
  border-color: var(--warn);
  background: var(--warn-soft);
}
form[data-dirty] input[type="checkbox"].dirty {
  outline: 2px solid var(--warn);
  outline-offset: 1px;
  border-radius: 3px;
}
/* Save bar of a combined-save form: static row without JS, floating above
   the tab bar (only while edits are pending) with it. */
.savebar {
  display: flex;
  gap: var(--sp-2);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  margin-top: var(--sp-3);
  padding: 10px 12px;
  border: 1px solid var(--warn);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--warn) 13%, var(--surface));
}
.savebar[hidden] { display: none; }
.savebar.floating {
  position: sticky;
  bottom: calc(var(--tabbar-h) + var(--safe-b) + var(--sp-2));
  z-index: 2;
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.18);
}
.savebar-count { color: var(--warn); font-weight: 600; font-size: var(--fs-sm); }
.savebar-actions { display: flex; gap: var(--sp-2); }
.courtlabel { min-width: 62px; font-weight: 600; }
.checkline { display: flex; align-items: center; gap: var(--sp-2); }
.checkline input[type="checkbox"] { width: 22px; }
label.inline { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }

/* 16 — poll checklist */
.polllist { list-style: none; margin: 10px 0; padding: 0; }
.polllist li { border-bottom: 1px solid var(--line); }
.polllist li:last-child { border-bottom: 0; }
.polllist li.locked { opacity: 0.6; }
.polllist label { display: flex; align-items: center; gap: var(--sp-3); min-height: 52px; padding: 6px 2px; flex-wrap: wrap; }
.polllist input[type="checkbox"] { accent-color: var(--bad); }
.polllist input:checked ~ .date { color: var(--bad); text-decoration: line-through; }

/* 17 — date lists */
.datelist { list-style: none; margin: var(--sp-2) 0 var(--sp-3); padding: 0; }
.datelist li { border-bottom: 1px solid var(--line); }
.datelist li:last-child { border-bottom: 0; }
.datelist a {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  min-height: 50px;
  align-items: center;
  color: var(--text);
  text-decoration: none;
  padding: 4px 2px;
  flex-wrap: wrap;
}
.datelist.compact a { min-height: 38px; font-size: 0.92rem; }

/* 18 — tables */
.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: var(--sp-2) -4px; padding: 0 4px; }
table { border-collapse: collapse; font-size: 0.92rem; }
.stats th, .stats td, .admintable th, .admintable td { padding: 7px 8px; border-bottom: 1px solid var(--line); text-align: left; }
.stats thead th, .admintable thead th { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .05em; color: var(--dim); }
.stats .num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
.num.pos { color: var(--ok); }
.num.neg { color: var(--bad); }

/* 19 — season grid (dense matrix; cells tinted like chips) */
.grid { min-width: 100%; }
.grid th, .grid td { border: 1px solid var(--line); padding: 4px; text-align: center; }
.grid .datecol {
  position: sticky;
  left: 0;
  background: var(--surface);
  text-align: left;
  white-space: nowrap;
  min-width: 72px;
  z-index: 2;
}
.grid .datecol a { color: var(--text); font-weight: 600; text-decoration: none; }
/* Court tags stack under the date: the column is sticky, so its width is what
   a phone loses from the player columns — one compact tag per line, not a
   date-plus-tags one-liner. */
.grid .datecol .datetags { display: flex; flex-wrap: wrap; gap: 2px; white-space: normal; max-width: 108px; }
.grid .datecol .tag { font-size: 0.66rem; padding: 0 5px; white-space: nowrap; }
.grid thead th { background: var(--surface); position: sticky; top: 0; z-index: 1; }
.grid thead th.datecol { z-index: 3; }
.grid .playercol span {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  max-height: 110px;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 600;
  font-size: 0.78rem;
  color: var(--dim);
}
.grid .fillcol { font-size: 0.78rem; white-space: nowrap; color: var(--dim); }
.grid .fillcol.under { color: var(--warn); font-weight: 700; }
.grid .fillcol.over { color: var(--bad); font-weight: 700; }
.grid td.cell { min-width: 32px; height: 36px; font-weight: 700; }
.grid tr.cancelled td { opacity: 0.45; }
td.cell.st-in { color: var(--ok); background: var(--ok-soft); }
td.cell.st-sit_out { color: var(--dim); background: var(--surface-2); }
td.cell.st-unavailable { color: var(--bad); background: var(--bad-soft); }
td.cell.st-cancelled { color: var(--warn); background: var(--warn-soft); }
td.cell.st-none { color: var(--dim); }
td.cell.locked { box-shadow: inset 0 0 0 2px currentColor; }
td.cell[hx-post] { cursor: pointer; }
.legend { font-size: 0.82rem; color: var(--dim); }
.legend .locked-demo { box-shadow: inset 0 0 0 2px var(--dim); border-radius: 4px; padding: 0 4px; }
.notedot { cursor: help; }

/* 20 — courts */
.courts { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.court {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-2) 10px;
  min-width: 100px;
  flex: 1 1 140px;
}
.court.mode-empty, .court.mode-subbooked, .court.mode-offered { opacity: 0.65; }
/* An offered court is ours to lose: dashed, so it reads as "on the market". */
.court.mode-offered { border-style: dashed; }
/* An incomplete doubles/singles: amber, so the gap gets seen — and filled. */
.court.short { border-color: var(--warn); background: var(--warn-soft); }
.courtrow.short .cbadge { background: var(--warn-soft); color: var(--warn); }
.courthead { font-weight: 600; }
.courtnames { margin-top: 4px; }
.cellcourt { font-size: 0.62em; vertical-align: super; opacity: 0.75; margin-left: 1px; }
.cbadge {
  width: 26px;
  height: 26px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--dim);
  font-size: 13px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* 21 — segmented control (half filter etc.) */
.seg, .filters {
  display: inline-flex;
  background: var(--surface-2);
  border-radius: 10px;
  padding: 3px;
  gap: 2px;
}
.seg span, .seg a, .filters a {
  text-align: center;
  padding: 7px 12px;
  border-radius: var(--r-sm);
  font-size: 13px;
  font-weight: 600;
  color: var(--dim);
  text-decoration: none;
  white-space: nowrap;
}
.seg .on, .seg .active, .filters .active { background: var(--surface); color: var(--text); box-shadow: var(--shadow-seg); }

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

/* 23 — desktop */
@media (min-width: 760px) {
  .tabbar { display: none; }
  .savebar.floating { bottom: var(--sp-3); } /* no tab bar to clear */
  .footer { padding-bottom: var(--sp-4); }
  .appheader {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: 10px var(--sp-5);
    gap: var(--sp-5);
  }
  .appnav { display: flex; align-items: center; gap: 2px; flex: 1; }
  .appnav a, .appnav .navoff {
    padding: 8px 14px;
    border-radius: var(--r-full);
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--dim);
    text-decoration: none;
    position: relative;
  }
  .appnav a.active { background: var(--surface-2); color: var(--text); }
  .appnav .navoff { opacity: .45; }
  .appnav .navdot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: var(--r-full);
    background: var(--dot);
    margin-left: 5px;
    vertical-align: 2px;
  }
  main { padding-top: var(--sp-5); }
  h1, .page-title { font-size: 1.9rem; }
}
@media (min-width: 1000px) {
  body[data-page="season"] main, body[data-page="admin"] main { max-width: 1080px; }
}

/* 24 — page components (Phase 2) */
.pagehead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin: var(--sp-2) 0 var(--sp-1);
}
.pagehead h1 { margin: 0; }
.titlerow { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.titlerow h1 { margin: 0; }
.pillrow { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin: 10px 0 2px; }
.backlink {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin: 2px 0 4px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--brand-2);
  text-decoration: none;
}
.cardtitle { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-2); font-size: var(--fs-md); }
.cardtitle .ic { color: var(--ok); }
.cardtitle.warntitle .ic { color: var(--warn); }

/* login hero */
.herologo { border-radius: var(--r-full); object-fit: cover; margin: var(--sp-2) auto 2px; display: block; }
.pininput { text-align: center; font-size: 1.25rem; letter-spacing: 0.12em; }
.alert {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  background: var(--bad-soft);
  color: var(--bad);
  border-radius: var(--r-md);
  padding: 10px 12px;
  font-weight: 600;
  font-size: var(--fs-sm);
  text-align: left;
}

/* grouped list rows (name picker, link lists) */
.rowlist { display: flex; flex-direction: column; margin: var(--sp-2) calc(-1 * var(--sp-4)) calc(-1 * var(--sp-2)); }
.rowhead { padding: var(--sp-3) var(--sp-4) var(--sp-1); }
.listrow {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 56px;
  padding: 6px var(--sp-4);
  border: 0;
  border-top: 1px solid var(--line);
  background: none;
  font: inherit;
  color: var(--text);
  text-align: left;
  width: 100%;
  cursor: pointer;
}
.listrow .ic-chevron-right { color: var(--dim); }
.rowmain { flex: 1; font-weight: 600; min-width: 0; }
.rowlink { color: var(--brand-2); }
.avatar {
  width: 34px;
  height: 34px;
  border-radius: var(--r-full);
  background: var(--act-soft);
  color: var(--brand-2);
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.datelist .ic-chevron-right { color: var(--dim); }
.checkline .rowmain { font-weight: 400; }

/* switch (styled checkbox) */
input[type="checkbox"].switch {
  appearance: none;
  -webkit-appearance: none;
  width: 50px;
  height: 30px;
  border-radius: var(--r-full);
  background: var(--line);
  position: relative;
  cursor: pointer;
  transition: background .15s ease;
  flex: none;
}
input[type="checkbox"].switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: var(--r-full);
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  transition: left .15s ease;
}
input[type="checkbox"].switch:checked { background: var(--ok); }
input[type="checkbox"].switch:checked::after { left: 23px; }

/* lineup partial */
.lineuphead { margin: 14px 0 4px; }
.courtrows { display: flex; flex-direction: column; border-top: 1px solid var(--line); margin-top: 6px; }
.courtrow {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 52px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
}
.courtrow:last-child { border-bottom: 0; }
.courtrowbody { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.courtrowlabel {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--dim);
}
.courthead { display: flex; align-items: center; gap: var(--sp-2); }
.open .ic { color: var(--warn); }

/* season legend swatches + admin hint */
.legend { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: var(--sp-3) 2px; }
.cellswatch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  font-weight: 700;
  font-size: 12px;
}
.cellswatch.st-in { background: var(--ok-soft); }
.cellswatch.st-sit_out { background: var(--surface-2); }
.cellswatch.st-unavailable { background: var(--bad-soft); }
.cellswatch.st-cancelled { background: var(--warn-soft); }
.cellswatch.locked { box-shadow: inset 0 0 0 2px currentColor; }
.notedot .ic { color: var(--dim); width: 1em; height: 1em; }
details.adminhint { font-size: var(--fs-sm); color: var(--dim); margin: var(--sp-2) 2px var(--sp-4); }
details.adminhint summary { cursor: pointer; font-weight: 600; }

/* copy feedback */
.iconbtn.copied { background: var(--ok-soft); color: var(--ok); }
/* share feedback: the picture is being fetched */
.iconbtn.busy { color: var(--dim); cursor: progress; animation: iconpulse 1s ease-in-out infinite; }
@keyframes iconpulse { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .iconbtn.busy { animation: none; opacity: .6; } }

/* 25 — data pages (Phase 3) */
.pagesub { margin: 4px 2px 10px; font-size: var(--fs-sm); }
.headtools { display: flex; align-items: center; gap: var(--sp-2); }
.kvlist { list-style: none; margin: 6px 0 0; padding: 0; }
.kvlist li {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 5px 0;
  border-top: 1px solid var(--line);
}
.kvlist li:first-child { border-top: 0; }
.klabel { flex: 1; min-width: 0; }
.kbody { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kname { font-weight: 600; }
.ksub { font-size: var(--fs-xs); color: var(--dim); }
.kval { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.kval.pos { color: var(--ok); }
.kval.neg { color: var(--bad); }
.stats tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
.stats thead th { position: sticky; top: 0; background: var(--surface); }
.shieldhero { display: block; margin: var(--sp-2) auto 0; color: var(--warn); }
.shieldhero .ic { width: 44px; height: 44px; fill: var(--warn-soft); }

/* 26 — interaction layer (Phase 4) */
@view-transition { navigation: auto; }
#toast-region {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--tabbar-h) + var(--safe-b) + var(--sp-3));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  z-index: 90;
  pointer-events: none;
}
.toast {
  background: var(--brand);
  color: #fff;
  border-radius: var(--r-full);
  padding: 10px 18px;
  font-size: var(--fs-sm);
  font-weight: 600;
  box-shadow: var(--shadow-1);
  max-width: min(92vw, 480px);
  transition: opacity .3s ease, transform .3s ease;
}
.toast.gone { opacity: 0; transform: translateY(6px); }
dialog#confirm {
  border: 0;
  border-radius: var(--r-lg);
  padding: var(--sp-5) var(--sp-4) var(--sp-4);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-1);
  width: min(92vw, 400px);
}
dialog#confirm::backdrop { background: rgba(10, 20, 12, .45); }
#confirm-text { margin: 0 0 var(--sp-4); }
.dlgactions { display: flex; gap: var(--sp-2); justify-content: flex-end; }
@media (max-width: 759px) {
  dialog#confirm { margin: auto auto calc(var(--sp-3) + var(--safe-b)); width: calc(100vw - 24px); }
  .dlgactions .btn { flex: 1; }
}
.btn.htmx-request, form.htmx-request .btn { opacity: .6; pointer-events: none; }
@media (min-width: 760px) {
  #toast-region { bottom: var(--sp-5); }
}
@media (prefers-reduced-motion: reduce) {
  .toast, input[type="checkbox"].switch, input[type="checkbox"].switch::after { transition: none; }
}

/* 27 — pool grid („Pool & Gäste" on the Saisonplan; second table, collapsed) */
details.poolcard > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  min-height: var(--tap);
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-md);
}
details.poolcard > summary::-webkit-details-marker { display: none; }
details.poolcard > summary::before {
  content: "";
  width: 8px;
  height: 8px;
  flex: none;
  border-right: 2px solid var(--dim);
  border-bottom: 2px solid var(--dim);
  transform: rotate(-45deg);
  transition: transform .15s ease;
}
details.poolcard[open] > summary::before { transform: rotate(45deg); }
.poolsummary { font-weight: 700; }
.grid .guestcol { font-size: 0.78rem; white-space: nowrap; color: var(--dim); }
.grid tfoot td {
  border-top: 2px solid var(--line);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--dim);
}
.grid td.cell a { display: block; color: inherit; text-decoration: none; }
@media (prefers-reduced-motion: reduce) {
  details.poolcard > summary::before { transition: none; }
}

/* 28 — Vermietung (admin) */
.rentlist { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.rentlist > li {
  border-top: 1px solid var(--line);
  padding-top: var(--sp-2);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}
.rentlist > li:first-child { border-top: 0; padding-top: 0; }
.rentmain { flex: 1 1 100%; display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); }
.rentactions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.checkinline { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 0.9rem; }
.checkinline input[type="checkbox"] { width: 18px; }
