/* Dark is the app's only theme now (not a toggle - see README/commit notes
   if that changes). Token roles, since a straight "invert the old light
   values" mapping doesn't hold up once the background is dark:
     --bg          page background - near-black, not pure black.
     --card        an elevated surface distinct from --bg (cards, inputs,
                   match cards) - visibly lighter than the page, not a
                   different-hued panel.
     --border      subtle but visible against both --bg and --card.
     --text        primary reading text - near-white, not pure white
                   (softer on a dark background, easier on the eyes).
     --muted       secondary text/labels - still legible on dark, dimmer
                   than --text.
     --accent      the green: TEXT-safe on dark surfaces (buttons, active
                   tab text, winner highlight, "final" pill text) - bright
                   enough to read as text on --bg/--card, not just as a
                   button fill.
     --accent-dark a deeper green used only where it sits on ITS OWN
                   background (the topbar, and the darkened hover state of
                   an --accent button) - never used as text-on-dark, which
                   is what --accent is for. This split is the one real
                   structural change from the light theme: light mode used
                   --accent-dark for both roles interchangeably because
                   "darker green" reads fine as text on a light page; on a
                   dark page a dark green is nearly invisible as text, so
                   every former text-role use of --accent-dark below now
                   reads --accent instead.
     --bad/--warn  red/amber, brightened for dark-background contrast - the
                   old values (#a13a2f/#a67c1f) were tuned for text on
                   white and read as muddy, low-contrast smears on a dark
                   page.
   `--court-a`/`--court-b` (unused - confirmed nothing in this file or the
   templates referenced them) are removed rather than repurposed; the
   surfaces that would have wanted a third tone (inputs, match cards) reuse
   --card, which is simpler and keeps the surface count small. */
:root {
  --bg: #15171b;
  --card: #1e2126;
  --border: #34383f;
  --text: #e8eaed;
  --muted: #9aa0a8;
  --accent: #4cb578;
  --accent-dark: #2f7a4c;
  --bad: #e07267;
  --warn: #dba64a;
  /* Tells the browser to render ITS OWN chrome - scrollbars, and native
     form-control defaults (the date-picker/number-spinner glyphs, select
     dropdown backgrounds) that aren't styleable via these tokens - in dark
     mode, so they don't stay light-mode-gray/white against a dark page. */
  color-scheme: dark;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.4;
}

/* The topbar is the one place a literal white/near-white is kept rather than
   tokenized: it sits on its own solid --accent-dark fill (not the page
   background), so "white text on a colored bar" is a legitimate fixed pair
   independent of the page theme, the same as white text on any button. */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1.25rem;
  background: var(--accent-dark);
  color: #fff;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.topbar .brand {
  font-weight: 700;
  font-size: 1.1rem;
  color: #fff;
  text-decoration: none;
}

.topbar nav a {
  color: #e7efe9;
  text-decoration: none;
  margin-left: 1rem;
  font-size: 0.95rem;
}

.topbar nav a:hover { text-decoration: underline; }

main {
  max-width: 960px;
  margin: 1.5rem auto;
  padding: 0 1rem 3rem;
}

.flashes { max-width: 960px; margin: 1rem auto 0; padding: 0 1rem; }

.flash {
  padding: 0.6rem 0.9rem;
  border-radius: 6px;
  margin-bottom: 0.5rem;
  font-size: 0.95rem;
}
/* Each flash is a dark tint of its color (not a light pastel - those read
   as bright, glary rectangles on a dark page) with the bright token color
   as text, and a mid-tone border a step between the two so the box still
   reads as outlined rather than just a color field. */
.flash-ok { background: #16301f; color: var(--accent); border: 1px solid #2f6b45; }
.flash-error { background: #3a1f1c; color: var(--bad); border: 1px solid #7a3830; }
.flash-warn { background: #3a2c12; color: var(--warn); border: 1px solid #7a5b24; }

h1 { font-size: 1.5rem; margin: 0 0 0.75rem; }
h2 { font-size: 1.15rem; margin: 1.75rem 0 0.5rem; }
h3 { font-size: 1rem; margin: 1rem 0 0.4rem; color: var(--muted); }

.tabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 1.25rem;
}
.tabs .tab {
  display: inline-block;
  padding: 0.5rem 0.9rem;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 600;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tabs .tab:hover { color: var(--text); }
.tabs .tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
}

label { display: block; font-size: 0.85rem; color: var(--muted); margin: 0.6rem 0 0.2rem; }

input[type=text], input[type=date], input[type=number], textarea, select {
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  font-size: 0.95rem;
  font-family: inherit;
  background: var(--card);
  color: var(--text);
}

textarea { resize: vertical; }

.help { font-size: 0.8rem; color: var(--muted); margin-top: 0.15rem; }

button, .btn {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 5px;
  font-size: 0.95rem;
  cursor: pointer;
  text-decoration: none;
  margin-top: 0.75rem;
}
button:hover, .btn:hover { background: var(--accent-dark); }
/* A mid-gray distinct from both --card (the surfaces buttons sit on) and
   --muted (which is now a light gray used for TEXT on dark surfaces - reusing
   it as a button fill would put near-white text on a near-white button). */
button.secondary, .btn.secondary { background: #4b4f57; }
button.danger, .btn.danger { background: var(--bad); }
button.danger:hover, .btn.danger:hover { background: #b3564c; }
button.small { padding: 0.3rem 0.6rem; font-size: 0.85rem; margin-top: 0; }

/* Two-step Remove control on the Players tab: the confirm step sits inline
   in the row rather than in a blocking confirm() dialog.
   [hidden] must win over the display rules below - an element with the
   hidden attribute only defaults to display:none, so any explicit display
   (inline-flex here) would silently override it and leave every row's
   confirm step visible at once. */
[hidden] { display: none !important; }
.row-actions { white-space: nowrap; }
.row-actions .confirm-step { display: inline-flex; align-items: center; gap: 0.4rem; }
.row-actions .confirm-step .help { margin: 0; }
#player-status { margin-bottom: 1rem; }

table { width: 100%; border-collapse: collapse; margin: 0.5rem 0 1rem; }
th, td { text-align: left; padding: 0.4rem 0.5rem; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
th { color: var(--muted); font-weight: 600; }
tr.rank-1 td:first-child { font-weight: 700; }

.pill {
  display: inline-block;
  padding: 0.1rem 0.55rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}
/* Each status keeps its own hue (gray/amber/green/gray/blue-gray, same as
   before) as a dark tint with a bright, distinctly-colored text - not a
   uniform "all pills look the same dark gray" flip, which is what would
   happen if only the shared .pill rule were touched. pending and bye stay
   the same hue family (neutral gray) but bye is dimmer, exactly as before -
   the pair most likely to be confused for each other if that distinction
   were lost. */
.pill-pending { background: #2b2e33; color: #9aa0a8; }
.pill-active, .pill-in_progress { background: #3a2c12; color: #e3ae4c; }
.pill-final, .pill-complete { background: #16301f; color: var(--accent); }
.pill-bye { background: #2b2e33; color: #686d74; }
.pill-placeholder { background: #212a38; color: #7c9cc4; }

.round-block { margin-bottom: 1.25rem; }
.round-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.4rem; }

/* Slightly wider minimum than the old 220px: the two sides now sit on one
   line (see .matchup), which needs a bit more room before names start
   wrapping. */
.match-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 0.6rem; }

.match-card {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.45rem 0.7rem;
  background: var(--card);
}
.match-card .court { font-size: 0.75rem; color: var(--muted); margin-bottom: 0.15rem; }

/* Both sides on one line rather than stacked, so a round of 4+ courts fits
   on screen without scrolling - the point is vertical density when you're
   glancing at the board between games. Each half wraps its own names
   internally instead of overflowing: min-width:0 is what lets a flex item
   shrink below its content width, which it will not do by default. */
.match-card .matchup { display: flex; align-items: baseline; gap: 0.5rem; }
.match-card .team {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  justify-content: space-between;
  gap: 0.4rem;
  overflow-wrap: anywhere;
}
.match-card .team.winner { font-weight: 700; color: var(--accent); }
/* The score sits at the outer edge of its own half, so the digits line up
   card to card rather than drifting with the name length. white-space:nowrap
   overrides the .team rule's overflow-wrap:anywhere for just this span - that
   rule is meant for long names, but with no override it also let a squeezed
   score break BETWEEN its own digits ("11" as "1" over "1") whenever a long
   name on the same row wrapped and left it little width. flex-shrink:0 keeps
   it at its natural width instead of being squeezed that narrow in the
   first place. */
.match-card .team span:last-child {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex-shrink: 0;
}
.match-card .vs { flex: 0 0 auto; font-size: 0.7rem; color: var(--muted); }

/* A not-yet-resolved ladder slot ("Court 3 winner (2)"). Deliberately set
   smaller and muted: it is meaningfully longer than a name, and it is not a
   person yet, so it should read as scaffolding rather than compete with the
   real names above and below it. It still wraps inside its own half of the
   .matchup (overflow-wrap on .team), so the two sides stay side by side at
   phone widths - no stacked fallback is reintroduced. */
.match-card .team .slot {
  font-size: 0.8em;
  color: var(--muted);
  font-style: italic;
  line-height: 1.25;
}

/* Deliberately NO stacked fallback at narrow widths. A phone is exactly
   where vertical space is scarcest and where the side-by-side layout is
   worth the most, so reverting to stacked there defeats the whole point.
   Long pairings wrap inside their own half instead (min-width:0 above),
   which measures clean with no horizontal overflow down to ~180px. */

/* Player dropdowns for a match that hasn't started (score entry). Each side
   stacks its seats; the selects shrink with their half of the card. An
   empty spot is outlined so it can't be missed before the match starts. */
.match-card .team.seats { flex-direction: column; justify-content: flex-start; gap: 0.25rem; }
.seat-form { margin: 0; }
.seat-select { width: 100%; min-width: 0; padding: 0.25rem 0.3rem; font-size: 0.85rem; }
.seat-select.open { border: 1px dashed var(--accent); color: var(--muted); }
.upcoming { margin: 1rem 0; }
.upcoming summary { cursor: pointer; font-weight: 600; }
.upcoming h3 { font-size: 0.95rem; margin: 0.8rem 0 0.4rem; }

.score-form { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.4rem; }
.score-form input[type=number] { width: 4.5rem; }

.checklist { display: flex; flex-wrap: wrap; gap: 0.4rem 1.2rem; }
.checklist label { display: flex; align-items: center; gap: 0.35rem; font-size: 0.9rem; color: var(--text); margin: 0; }

.summary-line { color: var(--muted); font-size: 0.9rem; margin-bottom: 0.5rem; }

.signed-in-as {
  color: #cfe9db;
  font-size: 0.85rem;
  margin-left: 1rem;
  opacity: 0.85;
}

/* Podium popup (Part D) - a real overlay, not window.alert(). Sits above
   everything, dims the page behind it, and is centered at every width
   (including phone - courtside is exactly where this needs to work). */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  z-index: 1000;
}
.modal-overlay .modal {
  max-width: 420px;
  width: 100%;
  text-align: center;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}
.podium-list {
  list-style: none;
  padding: 0;
  margin: 0.75rem 0 1rem;
  text-align: left;
}
.podium-list li {
  padding: 0.45rem 0.2rem;
  border-bottom: 1px solid var(--border);
  font-size: 1.05rem;
}
.podium-list li:last-child { border-bottom: none; }
