:root {
  --bg: #070b14;
  --bg-elevated: #0c1220;
  --card: #111a2c;
  --card-hover: #142235;
  --border: #223049;
  --border-soft: #1a2438;
  --text: #eef2fb;
  --muted: #8b9ab3;
  --accent: #16d97e;
  --accent-dim: #0f8f56;
  --accent2: #ff4d6a;
  --gold: #f0b429;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px -8px rgba(0,0,0,.55);
}
/* Light mode: toggled by JS setting data-theme="light" on <html>, persisted in
   localStorage (theme-toggle.js). Same variable names, different values, so every
   existing rule that already reads var(--bg)/var(--text)/etc. repaints correctly
   with zero other changes anywhere in the app. */
html[data-theme="light"] {
  --bg: #eef1f7;
  --bg-elevated: #ffffff;
  --card: #ffffff;
  --card-hover: #f7f9fd;
  --border: #dde3ee;
  --border-soft: #e6eaf2;
  --text: #121a29;
  --muted: #5c6b82;
  --accent: #12885a;
  --accent-dim: #0e6d47;
  --accent2: #c0392b;
  --gold: #b5790f;
  --shadow: 0 1px 2px rgba(20,30,50,.06), 0 8px 20px -10px rgba(20,30,50,.15);
}
/* A handful of rules below use a hardcoded dark hex instead of var(--card)/var(--bg) (they
   predate the variable set, or were deliberately a shade off the card background) — those
   don't repaint on their own when the theme flips, so light mode overrides them explicitly. */
html[data-theme="light"] input, html[data-theme="light"] select,
html[data-theme="light"] .result, html[data-theme="light"] .milestone-tile, html[data-theme="light"] .over-cell {
  background: #f4f6fb !important;
}
html[data-theme="light"] #clockStrip { background: #ffffff !important; box-shadow: 0 1px 0 var(--border), 0 2px 10px -6px rgba(20,30,50,.15) !important; }
html[data-theme="light"] #liveLinks a { background: #f4f6fb !important; }
html[data-theme="light"] .brand-mark { color: var(--accent-dim) !important; }
#themeToggleBtn {
  background: none; border: 1px solid var(--border); color: var(--muted); border-radius: 20px;
  padding: 3px 11px; font-size: 11px; cursor: pointer; flex: none; margin-left: 8px;
  transition: border-color .15s, color .15s;
}
#themeToggleBtn:hover { border-color: var(--accent); color: var(--text); }
* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  padding: 16px 14px 24px;   /* 40px of bottom padding was just empty scroll */
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  /* #clockStrip's fixed-width items (date/time text, theme toggle, login button)
     don't shrink — on a narrow phone their combined width used to exceed the
     viewport with nothing to absorb the overflow, clipping the login button off
     the right edge entirely instead of just squeezing the (still-scrollable)
     live-match ticker in the middle. This is the safety net; the real fix is
     giving #clockText somewhere to go on mobile, below. */
  overflow-x: hidden;
}
/* Cards used to stack in a single narrow column (max-width: 900px) regardless of
   screen size, leaving most of a wide desktop empty. .wrap is now a responsive grid
   — as many columns as fit at a minimum comfortable card width, so a wide screen
   fills with cards side by side instead of one long empty-margined column, and a
   narrow one still collapses to a single column on its own via auto-fill. Elements
   that aren't a .card (the page title, back link, match header) span every column
   so they still read as a full-width header, not a grid cell. */
.wrap {
  /* 1920, not 1480. A card's result tiles sit side by side only when the card itself
     is wide enough for three of them (3 x 260px min-width + two 10px gaps = 800px of
     card), and at three cards per row that needs about 1750px of .wrap. The old 1480
     cap made that unreachable on ANY monitor -- a 2560px screen got the same 1480px
     column as a 1500px one, so the tiles stacked no matter how much room there was.
     Measured on match.html (India v West Indies, all cards run), .wrap width vs grid
     height, 3 cards per row:
        1480  2,353px   tiles stacked (441px wide, one per line)
        1700  2,311px   tiles stacked
        1750  2,102px   tiles go side by side  <- threshold
        1850  2,060px   side by side
        2200  1,997px   side by side
     So crossing 1750 makes the page SHORTER and the card contents horizontal at the
     same time -- the one change here that doesn't trade one against the other.
     Nothing below 1480 changes. */
  max-width: 1920px;
  margin: 0 auto;
  display: grid;
  /* 420px, not 300px. At 300 the columns came out ~320-340px wide, and a card's
     three result tiles need 410px of container to sit on one line (3 x 130px min-width
     + two 10px gaps) -- so the third always wrapped and every card ran down the page as
     a tall strip (the fall-of-wicket card measured 1717px in a 334px column).
     420 is the smallest value that keeps all three tiles on one line at 1024, 1280,
     1440 AND 1680; 380 fails at 1280 and 1680, where auto-fill squeezes in one column
     too many. */
  grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
  /* Without "dense", a 2-column hero card that can't fit next to whatever's
     already in the row (e.g. another hero card right after it in DOM order) leaves
     that slot permanently empty — the grid only ever moves forward, it doesn't look
     back to backfill a gap with a later, smaller card. "dense" is exactly the fix:
     it lets a later 1-column card fill an earlier empty cell instead of leaving
     visible dead space, which is what "space khali na rahe" (no empty space) means
     in a multi-span grid like this one. */
  grid-auto-flow: dense;
  gap: 14px;
  align-items: start;
}
.wrap > h1, .wrap > .sub, .wrap > .back-link, .wrap > .match-header, .wrap > datalist {
  grid-column: 1 / -1;
}
/* No bottom margin on h1/.sub: inside .wrap (a grid with gap:14px) an item's margin
   ADDS to the gap rather than collapsing into it, so these were paying for the space
   twice. Safe on all four pages -- each has its h1 and .sub as direct children of
   .wrap. match.html's own h1 sits inside .match-header, whose more specific
   ".match-header h1" rule keeps its margin regardless of this one. */
h1 {
  font-size: 22px; margin: 0; font-weight: 800; letter-spacing: -.01em;
  background: linear-gradient(135deg, var(--text), var(--muted));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.sub { color: var(--muted); font-size: 12.5px; margin: 0; }
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  min-width: 0; /* let grid shrink a card below its content's natural width instead of overflowing the column */
  box-shadow: var(--shadow);
  transition: border-color .15s, transform .15s;
}
.card h2 {
  font-size: 12px; margin: 0 0 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em;
  font-weight: 700; padding-left: 10px; border-left: 3px solid var(--accent); line-height: 1.3;
}
.row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
input, select {
  flex: 1;
  min-width: 120px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 9px 11px;
  border-radius: 8px;
  font-size: 13px;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(22,217,126,.15);
}
button {
  background: linear-gradient(135deg, var(--accent), var(--accent-dim));
  color: #04170c;
  border: none;
  font-weight: 700;
  padding: 9px 16px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 13px;
  letter-spacing: .01em;
  transition: transform .12s, box-shadow .12s, filter .12s;
  box-shadow: 0 2px 8px -2px rgba(22,217,126,.4);
}
button:hover { transform: translateY(-1px); filter: brightness(1.06); }
button:active { transform: translateY(0); }
button.secondary { background: transparent; border: 1px solid var(--border); color: var(--text); box-shadow: none; }
button.secondary:hover { border-color: var(--accent); background: var(--card-hover); }
button:disabled { opacity: .5; cursor: default; transform: none; }
.result { margin-top: 10px; padding: 11px 13px; border-radius: 9px; background: var(--bg-elevated); border: 1px solid var(--border-soft); display: none; font-size: 13px; }
.bar {
  height: 11px; border-radius: 6px; background: var(--border); overflow: hidden; display: flex; margin: 8px 0;
  box-shadow: inset 0 1px 2px rgba(0,0,0,.25);
}
.bar div { height: 100%; transition: width .4s ease; }
.fixture {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;
  padding: 10px 4px; border-bottom: 1px solid var(--border-soft); gap: 8px 10px;
  border-radius: 8px;
}
.fixture:last-child { border-bottom: none; }
.fixture .teams { font-weight: 700; font-size: 13px; }
.fixture .meta { color: var(--muted); font-size: 11px; }
.pill { padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 800; white-space: nowrap; letter-spacing: .01em; }
/* A live match's status pill carries free-text commentary ("Day 1: 3rd Session -
   Warwickshire trail by 39 runs") that can run much longer than a normal pill's
   fixed label — nowrap forced it past the card's edge on a narrow screen instead of
   wrapping, one of the concrete mobile overflow bugs found in a UX pass. Only this
   pill gets to wrap; every other (short, fixed-label) pill keeps the nowrap pill look. */
.fixture > .pill { white-space: normal; text-align: right; max-width: 100%; }
.pill.ok { background: rgba(22,217,126,.15); color: var(--accent); }
.loading, .empty { color: var(--muted); font-size: 13px; padding: 6px 0; }
.over-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  gap: 6px;
  margin-top: 10px;
}
.over-cell {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 3px;
  text-align: center;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}
.over-cell .over-num { color: var(--muted); font-size: 9px; }
.over-cell .over-runs { font-weight: 800; font-size: 13px; margin: 1px 0; }
.over-cell .over-wkt { font-size: 9px; }
.over-cell .over-wkt.high { color: var(--accent2); font-weight: 700; }
.milestones { display: flex; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.milestone-tile { flex: 1; min-width: 150px; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 10px; padding: 12px; }
.milestone-tile .label { color: var(--muted); font-size: 11px; margin-bottom: 5px; }
/* A persistent label above an input — placeholder text alone disappears the moment
   someone types, which makes a form of several similar-looking fields (team, venue,
   over number, target score...) hard to re-read at a glance once filled in. */
.field-label { color: var(--muted); font-size: 11px; margin-bottom: 4px; }
.milestone-tile .value { font-size: 20px; font-weight: 800; font-variant-numeric: tabular-nums; }
.confidence-tag { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 800; margin-left: 6px; }
.confidence-tag.high { background: rgba(22,217,126,.15); color: var(--accent); }
.confidence-tag.low { background: rgba(255,77,106,.15); color: var(--accent2); }
/* Per-card collapse (frontend/card-collapse.js). Was in match.html's own <style>;
   moved here when index.html started using the same control. The toggle button's
   own look is set inline where it is built, next to the reorder arrows it matches. */
.card.collapsed > .card-collapsible { display: none; }
.card:not(.collapsed) .card-summary-line { display: none; }
.card-summary-line { font-size: 11.5px; color: var(--muted); margin: 2px 0 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
/* A card that nominates its own folded content (.card-summary-source) lays out real
   blocks -- a probability bar, a wrapped warning -- not one line of text, so the
   nowrap/ellipsis above would clip it. card-collapse.js adds .is-rich when it uses a
   nominated summary. */
.card-summary-line.is-rich { white-space: normal; overflow: visible; text-overflow: clip; }

.fixture.clickable { cursor: pointer; }
/* Row state tints. A glance at the Today's Matches card should separate a match that is
   being played right now from one that hasn't started and one that is already over,
   without having to read the section heading or the status pill. The three sections were
   already rendered separately (see renderLiveMatchesCard) -- only the colour was missing.
   Tints stay deliberately faint: the row's own content (team names, score, the LIVE
   badge, the probability pill) has to stay the thing the eye lands on. */
:root {
  --fx-live-bg:   rgba(255, 77, 106, .10);   /* --accent2, same hue as the LIVE badge */
  --fx-live-hover:rgba(255, 77, 106, .17);
  --fx-up-bg:     rgba(240, 180, 41, .07);   /* --gold, "not yet" */
  --fx-up-hover:  rgba(240, 180, 41, .14);
  --fx-fin-bg:    rgba(139, 154, 179, .07);  /* --muted, done and de-emphasised */
  --fx-fin-hover: rgba(139, 154, 179, .13);
}
/* Light mode needs its own alphas: the dark-mode values are mixed against a near-black
   card and wash out to almost nothing on white. */
html[data-theme="light"] {
  --fx-live-bg:   rgba(192, 57, 43, .07);
  --fx-live-hover:rgba(192, 57, 43, .13);
  --fx-up-bg:     rgba(181, 121, 15, .08);
  --fx-up-hover:  rgba(181, 121, 15, .15);
  --fx-fin-bg:    rgba(92, 107, 130, .07);
  --fx-fin-hover: rgba(92, 107, 130, .13);
}
.fixture--live     { --fx-bg: var(--fx-live-bg); --fx-hover: var(--fx-live-hover); --fx-edge: var(--accent2); }
.fixture--upcoming { --fx-bg: var(--fx-up-bg);   --fx-hover: var(--fx-up-hover);   --fx-edge: var(--gold); }
.fixture--finished { --fx-bg: var(--fx-fin-bg);  --fx-hover: var(--fx-fin-hover);  --fx-edge: var(--muted); }
.fixture--live, .fixture--upcoming, .fixture--finished {
  background: var(--fx-bg);
  border-left: 3px solid var(--fx-edge);
  padding-left: 9px;          /* 4px base + 3px border + 2px, so text doesn't touch it */
  margin-bottom: 4px;
  /* The 1px divider existed to separate otherwise identical rows; the tint and the gap
     do that job now, and keeping both reads as clutter. */
  border-bottom-color: transparent;
}
/* A finished match is still clickable and still shows its score, but it is the least
   actionable of the three -- so it also sits back a little. */
.fixture--finished { opacity: .8; }
.fixture--finished:hover { opacity: 1; }
/* Each state carries its own hover shade, so hovering a tinted row no longer flips it to
   the neutral --card-hover and momentarily loses the state colour. Untinted rows
   elsewhere in the app fall back to the original value. */
.fixture.clickable:hover { background: var(--fx-hover, var(--card-hover)); }
.back-link { color: var(--muted); font-size: 12px; text-decoration: none; display: inline-block; margin-bottom: 4px; }
.back-link:hover { color: var(--accent); }
.match-header { margin-bottom: 10px; }
.match-header h1 { font-size: 21px; margin: 0 0 3px; }

/* The two most information-dense, "at a glance" cards (Live Score, Match Overview —
   the win-probability bar, live-adjusted over-by-over grid, etc.) are the actual
   hero of the page — worth the FULL row's width, not just a fixed 2-column span.
   "span 2" only looked full at exactly 2 columns; on a wide screen with 3+ columns
   it left the hero sharing its row with an unrelated card instead of standing on
   its own, and left a real card at half its available room. "1 / -1" spans every
   column that exists at the current width, whatever that number is. */
.card[data-card-key="liveScore"],
.card[data-card-key="overview"],
.card[data-card-key="liveNow"] {
  grid-column: 1 / -1;
}
@media (max-width: 680px) {
  .wrap { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  /* The full date/time text is redundant on a phone (the device already shows a
     clock) and was the single biggest fixed-width item forcing #clockStrip to
     overflow — dropping it is what actually gives the login button room to stay
     on-screen, rather than just letting it silently scroll off. */
  #clockText { display: none; }
}
.card.dragging { opacity: .4; }
.card-drag-handle:active { cursor: grabbing; }

/* Live cards rewrite their whole result block every ~2s poll tick — this softens
   a genuine value change into a visible highlight instead of a silent/jarring swap,
   and (paired with the MutationObserver in match.html only flashing on real text
   changes) stays quiet on ticks where nothing actually moved. */
@keyframes valueFlash {
  0% { background-color: rgba(22, 217, 126, .22); }
  100% { background-color: transparent; }
}
.value-flash { animation: valueFlash 1.1s ease-out; border-radius: 8px; }

/* Sticky top bar: brand mark (left), scrolling live-match ticker (middle), clock +
   theme toggle (right) — a proper app header instead of a bare info strip. */
#clockStrip {
  position: sticky; top: 0; z-index: 1000;
  margin: -16px -14px 16px;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 2px 12px -6px rgba(0,0,0,.5);
  color: var(--muted); font-size: 11px; letter-spacing: .3px;
  font-variant-numeric: tabular-nums;
  display: flex; align-items: center; height: 40px;
}
#clockStrip::before {
  flex: none; padding: 0 4px 0 14px; font-size: 15px;
}
#clockStrip b { color: var(--text); font-weight: 700; }
#liveLinks { flex: 1 1 auto; min-width: 0; height: 100%; padding: 0 12px; display: flex; gap: 6px; align-items: center; overflow-x: auto; white-space: nowrap; scrollbar-width: none; }
/* NOT display:none when empty — #liveLinks is the flex-grow spacer that pushes the
   clock/theme/account cluster to the right edge; hiding it when there are no live matches
   collapses that spacer too, which is exactly what left the login button stranded in the
   middle of the bar instead of pinned to the corner. Empty and invisible (no background/
   border of its own) is enough — it doesn't need to disappear from the layout. */
#liveLinks::-webkit-scrollbar { display: none; }
#liveLinks a {
  flex: none; color: var(--text); text-decoration: none; padding: 4px 10px; line-height: 16px;
  border: 1px solid var(--border); border-radius: 20px; background: var(--card);
  font-weight: 600; transition: border-color .15s, color .15s;
}
#liveLinks a:hover { border-color: var(--accent); color: var(--accent); }
#liveLinks a.current { border-color: var(--accent2); color: var(--accent2); }
#clockText { flex: none; padding: 0 8px; text-align: right; white-space: nowrap; font-weight: 600; }

/* Compact login widget in the top bar (account-widget.js) — a button that opens a
   dropdown panel below it, instead of a full-width card taking up grid space. */
#accountWidget { position: relative; flex: none; margin-left: 10px; padding-right: 0; margin-right: 0; }
#accountBtn {
  background: linear-gradient(135deg, var(--accent), var(--accent-dim)); color: #04170c; border: none;
  font-weight: 800; padding: 6px 16px; border-radius: 20px; cursor: pointer; font-size: 11.5px;
  box-shadow: 0 2px 10px -2px rgba(22,217,126,.5); transition: transform .12s, filter .12s;
}
#accountBtn:hover { transform: translateY(-1px); filter: brightness(1.08); }
#accountPanel {
  display: none; position: absolute; right: 0; top: calc(100% + 8px); z-index: 1001;
  width: 280px; background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 14px; box-shadow: var(--shadow); text-align: left;
}
#accountPanel.open { display: block; }
#accountPanel .row { margin-bottom: 8px; }
#accountPanel input { font-size: 12.5px; padding: 7px 9px; }
#accountPanel button { font-size: 12px; padding: 7px 12px; }

/* Shown on a match page when the match has already finished. */
.finished-badge { display: inline-block; padding: 3px 10px; border-radius: 999px; background: rgba(139,154,179,.18); color: var(--text); font-size: 11px; font-weight: 800; letter-spacing: .06em; margin-right: 8px; text-transform: uppercase; }
/* Shown on a match page while the match is in progress. */
.running-badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; background: rgba(255,77,106,.15); color: var(--accent2); font-size: 11px; font-weight: 800; letter-spacing: .06em; margin-right: 8px; text-transform: uppercase; }
.running-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent2); animation: runBlink 1s linear infinite; }
@keyframes runBlink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: .1; } }
@media (prefers-reduced-motion: reduce) { .running-badge .dot { animation: none; } }
