:root {
  --bg: #f2f4ef;
  --surface: #ffffff;
  --surface-2: #eaeee4;
  --text: #1b2420;
  --text-2: #57645c;
  --accent: #2e6f52;
  --accent-dark: #234f3c;
  --accent-soft: #e2ede6;
  --accent-2: #c08a2e;
  --border: #dce1d7;
  --good: #2e6f52;
  --bad: #b04a3f;
  /* Match-mode pitch tint, set on <body> by setMatchBackground() in app.js
     from the active team's colors — these fallbacks only apply if a match
     screen is somehow shown before that runs. */
  --team-primary: #1b4d33;
  --team-secondary: #ffffff;
}

* { box-sizing: border-box; }

/* Belt-and-braces against any element (a too-wide table, an unwrapped
   flex row, ...) forcing the whole page wider than the viewport on a
   phone — see the @media block at the end of this file for the real
   phone-layout fixes. This alone stops such a thing from ever showing up
   as the *page* scrolling sideways or the colored topbar looking like it
   stops short of the screen edge; the specific culprits still get their
   own fix below rather than relying on this alone. */
html { width: 100%; }
body {
  margin: 0;
  width: 100%;
  overflow-x: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: "Source Sans 3", ui-sans-serif, system-ui, -apple-system, sans-serif;
}

/* ---- Accessibility: dyslexia-friendly reading mode ---------------------
   Toggled from Settings (see the Accessibility section in screenSettings,
   and DYSLEXIA_STORAGE_KEY in app.js) and remembered per-browser via
   localStorage — applied as a class on <html> the moment app.js loads
   (before the first render), so there's no flash of the normal styling on
   every page load once it's turned on.

   This isn't the OpenDyslexic font specifically — this build has no
   outbound network access to fetch a custom webfont from, so instead it
   switches to font/spacing choices recommended by dyslexia style guides
   regardless of which typeface is used: an irregular, easily-distinguished
   letterform font that ships on both Windows and Mac (so no download is
   needed at all), generous letter/word spacing, and taller line height.
   Swap in an @font-face for a real OpenDyslexic file here later if one
   gets added under wwwroot/fonts/. */
html.dyslexia-font body,
html.dyslexia-font input,
html.dyslexia-font button,
html.dyslexia-font select,
html.dyslexia-font textarea {
  font-family: 'Comic Sans MS', 'Comic Sans', Verdana, Tahoma, sans-serif;
  letter-spacing: 0.02em;
  word-spacing: 0.14em;
  line-height: 1.7;
}
html.dyslexia-font .question-text,
html.dyslexia-font p,
html.dyslexia-font li {
  line-height: 1.7;
}

/* ---- Match mode: sport-photo pitch backgrounds --------------------------
   Real photos from wwwroot/backgrounds/ (GAAPitch.png / RugbyPitch.png /
   AFLPitch.png) — see the pitch-gaa/pitch-rugby/pitch-afl rules further
   down. setMatchBackground() in app.js toggles `match-bg` plus exactly one
   of those three classes on <body> (from the active sport's `pitch_shape`),
   and sets --team-primary / --team-secondary from the active team's jersey
   colors (currently unused by the photo backgrounds themselves, kept for
   any UI that still reads them). */
body.match-bg {
  min-height: 100vh;
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-color: #2f7d4a;
}
body.match-bg .app {
  background: rgba(255, 255, 255, 0.94);
  border-radius: 16px;
  margin-top: 20px;
  margin-bottom: 20px;
  box-shadow: 0 10px 35px rgba(0, 0, 0, 0.35);
  position: relative;
  z-index: 1;
}
/* The footer sits outside .app's translucent panel, directly on the pitch
   background during a match — lighten it so it stays legible there. */
body.match-bg .site-footer { color: rgba(255, 255, 255, 0.85); }

/* Sport-specific match backgrounds — real photos from wwwroot/backgrounds/
   (GAAPitch.png / RugbyPitch.png / AFLPitch.png), one per sport.pitch_shape,
   set via the pitch-gaa/pitch-rugby/pitch-afl class from setMatchBackground()
   in app.js. This replaces an earlier pure-CSS-gradient pitch drawing (goal
   posts, hoarding, mown-grass stripes built out of stacked linear-gradients)
   — reverted back to actual background images per feedback that the drawn
   version didn't read as clearly as a real pitch photo. The dark vignette
   is kept as the top layer purely for legibility: the translucent .app
   panel and the footer text both sit on top of this image and need
   consistent contrast regardless of how bright any given photo is. */
body.pitch-gaa {
  background-image:
    linear-gradient(rgba(8, 14, 10, 0.25), rgba(8, 14, 10, 0.55)),
    url('backgrounds/GAAPitch.png');
  background-position: center, center;
  background-size: 100% 100%, cover;
  background-repeat: no-repeat, no-repeat;
}
body.pitch-rugby {
  background-image:
    linear-gradient(rgba(8, 14, 10, 0.25), rgba(8, 14, 10, 0.55)),
    url('backgrounds/RugbyPitch.png');
  background-position: center, center;
  background-size: 100% 100%, cover;
  background-repeat: no-repeat, no-repeat;
}
body.pitch-afl {
  background-image:
    linear-gradient(rgba(8, 14, 10, 0.25), rgba(8, 14, 10, 0.55)),
    url('backgrounds/AFLPitch.png');
  background-position: center, center;
  background-size: 100% 100%, cover;
  background-repeat: no-repeat, no-repeat;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* flex-wrap + row-gap, not overflow: on a narrow screen the nav simply
     drops to a second row (still full-width, still colored) instead of
     forcing the whole page wider than the viewport — see .topnav below,
     which is the piece that actually has enough buttons to overflow. */
  flex-wrap: wrap;
  row-gap: 10px;
  padding: 16px 24px;
  background: var(--accent);
  color: #fff;
}

.topbar-left { display: flex; align-items: center; gap: 14px; min-width: 0; }

.brand {
  font-family: Georgia, serif;
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.01em;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: #fff;
}
.brand span { color: #ffe9b0; }

/* Playing-as chip: your team flag + nickname, next to the brand. Purely an
   identity display now — it used to be the only (hidden-tooltip) way into
   Settings, which nobody could actually discover; #topbar-settings-btn in
   the nav is the one explicit way in now (see index.html). */
.topbar-profile {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 20px;
  padding: 4px 12px 4px 4px;
}

.topbar-flag {
  width: 38px;
  height: 26px;
  border-radius: 4px;
  border: 2px solid rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.15);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.topbar-flag img { width: 100%; height: 100%; object-fit: cover; }

/* The little sport emoji (🍀/🏈/🏉) shown between the team flag and the
   nickname, so "what sport is this player currently in" is visible at a
   glance without opening Settings — see updateTopbarProfile() in app.js. */
.topbar-sport-icon {
  font-size: 15px;
  line-height: 1;
  flex: 0 0 auto;
}

.topbar-nickname {
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
}

/* flex-wrap here (rather than on .topbar's account letting nav text wrap
   mid-button) is what actually stops the seven nav buttons + gear icon
   forcing horizontal overflow on a phone: they drop onto however many
   rows they need, each button keeping its label on one line
   (white-space: nowrap below), instead of either overflowing the screen
   or wrapping awkwardly inside a single button. */
.topnav { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; row-gap: 8px; }

.link-btn {
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.35);
  color: #fff;
  padding: 8px 14px;
  white-space: nowrap;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
}
.link-btn:hover { background: rgba(255,255,255,0.25); }
.nav-icon { margin-right: 6px; }

/* The gear icon that opens Settings — deliberately its own, always-visible
   button rather than an overloaded click target on the team flag, so
   "where do I change my age group / team / PIN" has one obvious answer. */
.icon-btn {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  cursor: pointer;
  font-size: 17px;
  line-height: 1;
  margin-left: 4px;
}
.icon-btn:hover { background: rgba(255, 255, 255, 0.3); }

.site-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  row-gap: 4px;
  gap: 8px;
  padding: 18px 20px 24px;
  color: var(--text-2);
  font-size: 13px;
}
.site-footer img { border-radius: 50%; }
.footer-sep { opacity: 0.6; }
.footer-link {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.footer-link:hover { color: var(--accent); }

.splash-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 60px 0;
  animation: splash-fade-in 0.35s ease-out;
}
.splash-logo { border-radius: 50%; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); }
.splash-brand {
  font-family: Georgia, serif;
  font-weight: 700;
  font-size: 32px;
  letter-spacing: -0.01em;
  color: var(--text);
}
.splash-brand span { color: var(--accent-2); }
@keyframes splash-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.about-page { text-align: center; max-width: 480px; margin: 0 auto; }
.about-logo { border-radius: 50%; margin-bottom: 16px; }
.about-page .sub { text-align: left; }

/* Privacy Policy — a proper reading column (narrower than the .app's full
   760px so paragraph lines don't get too long to read comfortably),
   left-aligned, with its own heading rhythm and list spacing since this
   is the one screen in the app that's mostly prose. */
.policy-page { max-width: 640px; }
.policy-page h2 { font-size: 16px; margin: 26px 0 8px; }
.policy-page p { margin: 0 0 14px; line-height: 1.55; }
.policy-page ul { margin: 0 0 16px; padding-left: 22px; line-height: 1.5; }
.policy-page li { margin-bottom: 8px; }
.policy-disclaimer {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
  font-size: 13px;
  color: var(--text-2);
  margin-bottom: 14px;
}

.app {
  max-width: 760px;
  margin: 0 auto;
  padding: 28px 20px 60px;
}

h1 { font-size: 24px; margin: 0 0 6px; }
h2 { font-size: 19px; margin: 0 0 12px; }
p.sub { color: var(--text-2); margin: 0 0 24px; }

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}
/* The browser's own default "hidden means display:none" rule lives in its
   built-in stylesheet, which always loses to any author rule of equal or
   higher specificity — so plain .team-grid { display: grid } above was
   silently winning over the `hidden` attribute on every collapsed
   province group, leaving every group visibly expanded from the start
   and making the expand/collapse click look like it did nothing (the JS
   was toggling `hidden` correctly the whole time — nothing was ever
   actually hiding). This rule outranks the base one (two selectors
   instead of one) so `hidden` actually takes effect again. */
.team-grid[hidden] { display: none; }

.team-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  text-align: left;
  cursor: pointer;
  font-size: 14px;
  color: var(--text);
}
.team-card:hover { border-color: var(--accent); background: var(--accent-soft); }
.team-card.selected { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }

.team-flag {
  display: block;
  width: 32px;
  height: 22px;
  object-fit: cover;
  border-radius: 3px;
  border: 1px solid var(--border);
  margin-bottom: 8px;
}

.section-label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-2);
  margin: 28px 0 10px;
}

/* ---- Sport picker chips (sign-up + Settings) ---------------------------
   sportChipsHtml() in app.js renders one .chip.sport-chip per sport
   (🍀 GAA / 🏈 AFL / 🏉 Rugby). Reuses the plain .chip look almost as-is —
   just a touch larger since each chip carries an emoji + full sport name
   rather than a short age-band label. */
.sport-chip { font-size: 15px; padding: 9px 16px; }

/* ---- Collapsible province/team-group picker ---------------------------
   Every team picker (Settings, sign-up, Solo Quiz, Match mode, Championship)
   groups counties by GAA province plus a "World Board" group for the
   diaspora teams (see teamGroupsHtml/attachTeamGroupToggles in app.js).
   Each group starts collapsed — just the province name and a count — and
   expands into its .team-grid on tap, so picking a team is "open a
   province, tap a county" instead of scrolling past everything at once. */
.team-groups { margin-top: 4px; }
.team-group + .team-group { margin-top: 4px; }

.team-group-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 12px 2px;
  margin: 0;
  cursor: pointer;
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  text-align: left;
  font-family: inherit;
}
.team-group-toggle:hover { color: var(--accent); }

.team-group-chevron {
  display: inline-block;
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--text-2);
  transition: transform 0.15s ease;
}
.team-group-toggle[aria-expanded="true"] .team-group-chevron { transform: rotate(90deg); }

.team-group-count {
  margin-left: auto;
  font-size: 12px;
  font-weight: 400;
  color: var(--text-2);
  background: var(--surface-2);
  border-radius: 10px;
  padding: 2px 9px;
}

.team-grid-collapsible { margin: 12px 0 6px; }

.signin-tabs { display: flex; gap: 8px; margin-bottom: 8px; }

.text-input {
  display: block;
  width: 100%;
  max-width: 280px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  font-size: 15px;
  margin-bottom: 6px;
  font-family: inherit;
}

.field-hint {
  font-size: 12px;
  color: var(--text-2);
  margin: 0 0 8px;
  max-width: 320px;
}

/* Settings autosave status line (see screenSettings/saveSettings in
   app.js) — sits where the old "Save settings" button's error box used
   to be, reused for "Saving…" / "All changes saved" / an error, for
   whichever field (sport, age group, team, parent email) just changed.
   Reserves its line height even when empty so nothing above/below it
   jumps around as the message appears and clears. */
.settings-status {
  min-height: 20px;
  font-size: 13px;
  font-weight: 600;
  margin: -6px 0 18px;
}
.settings-status-saving { color: var(--text-2); font-weight: 400; }
.settings-status-saved { color: var(--good); }
.settings-status-error { color: var(--bad); }

.category-row, .age-row, .age-band-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}

.chip {
  border: 1px solid var(--border);
  background: var(--surface);
  padding: 8px 14px;
  border-radius: 20px;
  cursor: pointer;
  font-size: 14px;
}
.chip.selected { background: var(--accent); color: #fff; border-color: var(--accent); }

p.sub.small { font-size: 13px; margin: 0 0 16px; }

/* Accessibility toggle row on the Settings screen (dyslexia-friendly font,
   see html.dyslexia-font above and setDyslexiaFont() in app.js) — a
   standard checkbox under the hood (keyboard/screen-reader friendly)
   styled as an on/off pill switch. */
.settings-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
}
.settings-toggle-label { font-size: 14px; color: var(--text); }
.settings-toggle-hint { font-size: 12px; color: var(--text-2); margin-top: 2px; }
.toggle-switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 26px;
  flex: 0 0 auto;
}
.toggle-switch input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}
.toggle-switch-track {
  position: absolute;
  inset: 0;
  background: var(--border);
  border-radius: 999px;
  transition: background 0.15s ease;
}
.toggle-switch-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 0.15s ease;
}
.toggle-switch input:checked ~ .toggle-switch-track { background: var(--accent); }
.toggle-switch input:checked ~ .toggle-switch-thumb { transform: translateX(18px); }
.toggle-switch input:focus-visible ~ .toggle-switch-track { box-shadow: 0 0 0 2px var(--accent-soft), 0 0 0 4px var(--accent); }

/* County/team leaderboard period toggle (This month / All-time) — reuses
   the same .chip look as the age-band buttons, just in its own row above
   the table. The "show full table" link below the table reuses
   .footer-link's plain-underline treatment rather than a new button style. */
.leaderboard-toggle-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.county-expand-btn { display: block; margin: 8px 0 22px; font-size: 13px; }

.primary-btn {
  background: var(--accent);
  color: #fff;
  border: none;
  padding: 12px 22px;
  border-radius: 10px;
  font-size: 15px;
  cursor: pointer;
  margin-top: 20px;
}
.primary-btn:hover { background: var(--accent-dark); }
.primary-btn:disabled { background: var(--border); color: var(--text-2); cursor: not-allowed; }

.progress {
  font-family: ui-monospace, monospace;
  font-size: 13px;
  color: var(--text-2);
  margin-bottom: 14px;
}

.question-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px;
}

.question-text { font-size: 19px; margin: 0 0 18px; line-height: 1.4; }

.option {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 13px 16px;
  margin-bottom: 9px;
  font-size: 15px;
  cursor: pointer;
}
.option:hover { border-color: var(--accent); }
.option-ball { flex: 0 0 auto; }
.option-text { flex: 1; }
.option.correct { background: var(--accent-soft); border-color: var(--good); }
.option.correct .option-text { color: var(--accent-dark); font-weight: 600; }
.option.incorrect { background: #f6e7e4; border-color: var(--bad); }
.option.incorrect .option-text { color: var(--bad); font-weight: 600; }
.option:disabled { cursor: default; pointer-events: none; }

.result-hero {
  text-align: center;
  padding: 30px 0;
}
.result-score {
  font-size: 48px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.result-sub { color: var(--text-2); margin-top: 6px; }

/* Same fix as .match-log-wrap below: a 5-6 column table doesn't shrink
   below its content's natural width, so on a narrow phone it can force
   the whole page wider than the screen instead of just scrolling itself.
   Wrapping each leaderboard table lets it — and only it — scroll
   sideways while everything else on the page stays put. */
.leaderboard-wrap { overflow-x: auto; margin-top: 6px; }

table.leaderboard {
  width: 100%;
  border-collapse: collapse;
  margin-top: 10px;
}
table.leaderboard th, table.leaderboard td {
  text-align: left;
  padding: 10px 8px;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}
table.leaderboard th { color: var(--text-2); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; }
table.leaderboard td.score { font-variant-numeric: tabular-nums; font-weight: 600; }

.error-box {
  background: #f6e7e4;
  border: 1px solid var(--bad);
  color: var(--bad);
  padding: 12px 16px;
  border-radius: 8px;
  margin-bottom: 16px;
}

.success-box {
  background: var(--accent-soft);
  border: 1px solid var(--good);
  color: var(--accent-dark);
  padding: 12px 16px;
  border-radius: 8px;
  margin-bottom: 16px;
}

.muted-btn {
  background: none;
  border: 1px solid var(--border);
  padding: 10px 18px;
  border-radius: 10px;
  cursor: pointer;
  margin-top: 12px;
  margin-right: 8px;
}

/* ---- Head-to-head match mode ------------------------------------------- */

.match-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 18px;
}
.match-side { flex: 1; text-align: center; }
.match-flag {
  display: block;
  width: 40px;
  height: 28px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid var(--border);
  margin: 0 auto 6px;
}
.match-team-name { font-size: 13px; font-weight: 600; }
.match-score { font-size: 28px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.match-breakdown { font-size: 11px; color: var(--text-2); margin-top: 2px; }
.match-vs { font-size: 12px; color: var(--text-2); text-transform: uppercase; letter-spacing: 0.06em; padding: 0 8px; }

/* Match-round countdown, drawn as a stopwatch face rather than plain text —
   a dial with a crown, tick marks and a depleting ring around the digits,
   built as inline SVG (see renderMatchRound/runMatchTimer in app.js) so it
   needs no image assets and scales crisply at any size. The ring's
   stroke-dashoffset is driven from JS each second (0 = full ring showing,
   100 = fully depleted); pathLength="100" on the <circle> lets JS work in
   plain 0-100 percentages instead of computing circle circumference. */
.stopwatch {
  position: relative;
  width: 108px;
  height: 108px;
  margin: 4px auto 16px;
}
.stopwatch-face { display: block; width: 100%; height: 100%; }
.stopwatch-crown { fill: var(--text-2); }
.stopwatch-track { fill: var(--surface); stroke: var(--border); stroke-width: 4; }
.stopwatch-tick { stroke: var(--border); stroke-width: 2; }
.stopwatch-progress {
  fill: none;
  stroke: var(--accent);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(-90deg);
  transition: stroke-dashoffset 1s linear, stroke 0.2s ease;
}
.stopwatch-digits {
  position: absolute;
  top: 54%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: ui-monospace, monospace;
  font-size: 26px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.match-timer-urgent .stopwatch-progress { stroke: var(--bad); }
.match-timer-urgent .stopwatch-digits {
  color: var(--bad);
  animation: stopwatch-pulse 1s ease-in-out infinite;
}
@keyframes stopwatch-pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.1); }
}

.match-result-banner {
  margin-top: 14px;
  padding: 12px 16px;
  border-radius: 10px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  font-size: 14px;
  text-align: center;
}

.match-log-wrap { overflow-x: auto; margin-top: 6px; }
table.match-log {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
table.match-log th, table.match-log td {
  text-align: left;
  padding: 8px 6px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.match-log th { color: var(--text-2); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
table.match-log td.log-score { color: var(--good); }
table.match-log td.log-concede { color: var(--bad); }
table.match-log td.log-denied { color: var(--text-2); }
table.match-log td.score-cell { font-variant-numeric: tabular-nums; }

/* ---- Championship tier picker ------------------------------------------ */

.tier-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.tier-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  text-align: left;
  cursor: pointer;
}
.tier-card:hover { border-color: var(--accent); background: var(--accent-soft); }
.tier-card.locked {
  cursor: not-allowed;
  opacity: 0.6;
  background: var(--surface-2);
}
.tier-card.locked:hover { border-color: var(--border); background: var(--surface-2); }
.tier-card-name { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.tier-card-blurb { font-size: 13px; color: var(--text-2); }

/* ---- Badges of honour --------------------------------------------------- */

.badge-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.badge-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 12px;
  text-align: center;
  opacity: 0.55;
}
.badge-card.earned {
  background: var(--surface);
  border-color: var(--accent-2);
  opacity: 1;
  box-shadow: 0 2px 10px rgba(192, 138, 46, 0.15);
}
.badge-icon { font-size: 32px; margin-bottom: 8px; }
.badge-name { font-size: 14px; font-weight: 700; margin-bottom: 4px; }
.badge-desc { font-size: 12px; color: var(--text-2); }

/* ---- Home dashboard ------------------------------------------------------ */

.home-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 24px;
}
.home-hero-flag {
  width: 60px;
  height: 40px;
  border-radius: 6px;
  overflow: hidden;
  border: 2px solid var(--border);
  flex: 0 0 auto;
  background: var(--surface-2);
}
.home-hero-flag img { width: 100%; height: 100%; object-fit: cover; }
.home-hero-text h1 { margin-bottom: 2px; }
.home-hero-text .sub { margin: 0; }

.game-tile-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 14px;
  margin-bottom: 28px;
}
.game-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px 16px;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.game-tile:hover { border-color: var(--accent); background: var(--accent-soft); }
.game-tile-icon { font-size: 30px; }
.game-tile-title { font-size: 16px; font-weight: 700; color: var(--text); }
.game-tile-sub { font-size: 12px; color: var(--text-2); }

/* A "trophy cabinet" look for earned badges on the home dashboard — a
   wood-toned shelf rather than the plain grid the full Badges screen uses,
   since this is meant to read as a display case, not a checklist. */
.trophy-cabinet {
  background: linear-gradient(180deg, #caa06a 0%, #a97c46 100%);
  border-radius: 14px;
  padding: 18px;
  margin-bottom: 20px;
}
.trophy-cabinet-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}
.trophy-cabinet-header h2 { color: #fff; margin: 0; }
.trophy-cabinet-header .link-inline {
  color: #fff8ea;
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  white-space: nowrap;
}
.trophy-shelf {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 10px;
  background: rgba(0, 0, 0, 0.14);
  border-radius: 10px;
  padding: 14px 10px;
}
.trophy-item { text-align: center; color: #fff; }
.trophy-icon {
  font-size: 30px;
  display: block;
  margin-bottom: 4px;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35));
}
.trophy-name { font-size: 11px; font-weight: 600; line-height: 1.25; }
.trophy-cabinet-empty { color: #fff2da; font-size: 13px; text-align: center; padding: 10px 4px; }

/* ============================================================================
   Phone layout (roughly anything narrower than a small tablet in portrait).
   Nothing above this point changes on desktop/tablet — everything here is
   an override for a screen where the default paddings, font sizes and
   grid minimums (all sized for a ~760px desktop reading column) end up
   too big for a 360-430px phone screen: buttons and text crowd the edges,
   grids can't fit more than one very wide card per row, and inputs that
   cap out at 280px look oddly narrow instead of filling the space they
   actually have. Combined with the topbar/topnav flex-wrap fix and the
   .leaderboard-wrap/.team-groups-collapsible changes above (which apply
   at every width, not just here), this is what "phone-friendly" means for
   this app: everything reflows to fit instead of overflowing or leaving
   dead space.
   ============================================================================ */
@media (max-width: 640px) {
  .topbar { padding: 12px 14px; }
  .topbar-left { gap: 10px; }
  .brand { font-size: 19px; }
  .topbar-profile { padding: 3px 10px 3px 3px; }
  .topbar-flag { width: 32px; height: 22px; }
  .topbar-nickname { font-size: 13px; }
  .topnav { width: 100%; justify-content: flex-start; gap: 6px; }
  .link-btn { padding: 7px 11px; font-size: 13px; }
  .icon-btn { width: 32px; height: 32px; font-size: 15px; }

  .app { padding: 18px 14px 44px; }
  h1 { font-size: 20px; }
  h2 { font-size: 17px; }
  p.sub { margin-bottom: 18px; }

  /* Grids sized for a 760px desktop column force at most one column at
     phone widths (minmax(140-200px, 1fr) vs. a ~330px available width) —
     dropping the minimum lets 2 (sometimes 3) columns fit instead of one
     oversized card per row. */
  .team-grid,
  .badge-grid,
  .trophy-shelf { grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); gap: 8px; }
  .game-tile-row { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; }
  .tier-row { grid-template-columns: 1fr; gap: 10px; }

  .team-group-toggle { font-size: 14px; padding: 11px 2px; }

  /* 280px made sense as a cap on a wide desktop column; on a phone it's
     just unused space either side of the field. */
  .text-input { max-width: 100%; }

  .question-card { padding: 16px; }
  .question-text { font-size: 17px; }
  .option { padding: 12px 14px; font-size: 14px; }

  .match-header { padding: 12px; gap: 8px; }
  .match-flag { width: 32px; height: 22px; }
  .match-team-name { font-size: 12px; }
  .match-score { font-size: 22px; }
  .stopwatch { width: 88px; height: 88px; margin: 4px auto 12px; }
  .stopwatch-digits { font-size: 22px; }

  .result-score { font-size: 36px; }

  table.leaderboard th, table.leaderboard td { padding: 8px 6px; font-size: 13px; }
}
