/* ============================================================
   Spreads: the rules that belong to this one site.

   The bar, the theme switch, the type, the palette, the buttons and the
   footer come from sitekit (assets/sitekit/, built from packages/sitekit
   with the saarthm skin and the primitives, skin, base, shell and buttons
   layers) and are never restated here. Loaded after sitekit.css, so a rule
   here wins any tie. Everything is written in the kit's roles (--bg, --ink,
   --head, --card, --card-edge, --trim, --tag, --rule, --shadow, the button
   pairs), so a future skin recolours the whole app.

   What this file owns: the week page (the game rows with their two sides
   and the best-bet star), the standings and leaderboard tables, forms,
   flashes, and the admin grids.
   ============================================================ */

/* The hidden attribute wins over any display rule below (the save button,
   the best-bet slot and the save bar are hidden and shown by script). */
[hidden] { display: none !important; }

/* ---------- page frame ---------- */
.page { max-width: 1060px; padding-top: 28px; padding-bottom: 20px; }
.narrow { max-width: 560px; margin: 0 auto; }
.page-head { margin-bottom: 22px; }
.page-head h1 { font-size: var(--fs-h1); letter-spacing: -.015em; line-height: 1.15; margin: 0 0 8px; color: var(--head); display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.lede { margin: 0; font-size: 15.5px; color: var(--tag); max-width: 64ch; }
.lede b { color: var(--ink); font-weight: 600; }
.lede .note { display: block; margin-top: 8px; padding: 8px 12px; border-left: 3px solid var(--trim); background: var(--card); color: var(--ink); font-size: 14px; border-radius: 0 8px 8px 0; }
.crumbs { margin: 0 0 6px; font-size: 13px; }
.crumbs a { color: var(--tag); text-decoration: none; display: inline-flex; align-items: center; gap: 4px; }
.muted { color: var(--tag); }
.small { font-size: 12.5px; }
.ico { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.ico.flip { transform: scaleX(-1); }
.ico.ok { color: var(--head); }
.ico.gold { color: var(--trim); }

/* The football in the bar rides at the kit's mark size, in the trim colour
   like every mark, so this bar is exactly as tall as the bar on the hub one
   click away. It used to be 40px and one pixel taller for it. */

/* the topbar's account chip, the nav's active link */
.who { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; color: var(--ink); font-size: 13px; font-weight: 600; }
.who .avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--btn1-bg); color: var(--btn1-fg); display: inline-grid; place-items: center; font-size: 12px; font-weight: 700; }
.who-in { color: var(--head); font-family: var(--font-mono); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }
/* The nav's size, its active colour and its underline all come from the
   kit's shell now; this file used to restate the first two. */

/* the "a newer version is out" note, above the bar, only when version.json says so */
.update-note { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 8px 16px; font-size: 13.5px; background: var(--btn1-bg); color: var(--btn1-fg); }
.update-note b { font-family: var(--font-mono); font-weight: 700; }

/* ---------- pills, flashes, status ---------- */
.pill { display: inline-flex; align-items: center; gap: 6px; border-radius: var(--radius-pill); padding: 6px 12px; font-size: 12px; font-weight: 600; font-family: var(--font); border: 1px solid var(--pill-b); background: var(--pill-bg); color: var(--pill-fg); text-decoration: none; cursor: pointer; line-height: 1.3; white-space: nowrap; transition: background-color var(--transition), color var(--transition), border-color var(--transition); }
.pill-sm { padding: 3px 9px; font-size: 11px; }
.flash { margin: 0 0 18px; padding: 12px 16px; border-radius: 12px; font-size: 14px; background: var(--pill-bg); border: 1px solid var(--pill-b); color: var(--ink); display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.flash-error { border-color: var(--trim); background: var(--card); }
.flash-buyin { border-color: var(--trim); border-style: dashed; background: var(--card); font-weight: 600; }
/* The money-with-wings badge in front of the name of somebody who has not paid
   the buy-in; its title is the nudge. */
.buyin { cursor: help; font-size: .95em; line-height: 1; }
/* inline-flex and nowrap: a plain inline span with padding that wrapped
   drew its two halves over the badge beside it. */
.status { display: inline-flex; align-items: center; white-space: nowrap; line-height: 1.3; font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; padding: 4px 10px; border-radius: var(--radius-pill); border: 1px solid var(--pill-b); background: var(--pill-bg); color: var(--pill-fg); font-weight: 700; vertical-align: middle; }
.status-open { border-color: var(--trim); color: var(--head); }
.status-final { background: var(--btn1-bg); color: var(--btn1-fg); border-color: var(--btn1-bg); }
.status-practice { border-style: dashed; border-color: var(--trim); color: var(--tag); background: transparent; }
label.check { flex-direction: row; align-items: center; gap: 8px; text-transform: none; letter-spacing: 0; font-family: var(--font); font-size: 13px; font-weight: 500; color: var(--ink); cursor: pointer; }
label.check input { width: auto; }

/* ---------- cards and notices ---------- */
.card { background: var(--card); border: 1px solid var(--card-edge); border-top: 3px solid var(--card-top); border-radius: var(--radius); padding: 18px 20px; transition: background-color var(--transition), border-color var(--transition); }
.card .sec-label { margin-bottom: 14px; }
.notice { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 18px; font-size: 14.5px; border-top-width: 1px; }
.notice .ico { width: 20px; height: 20px; margin-top: 2px; color: var(--head); }
.notice a { color: var(--head); }
.notice-warn { border-color: var(--trim); }

/* ---------- the week page ---------- */
.my-picks { margin-bottom: 18px; padding: 14px 18px 12px; }
.my-picks-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.my-picks .sec-label { margin: 0; }
.my-picks .sec-label::after { display: none; }
/* The rail: one round logo per saved pick with the line beneath and the
   opponent under that. A ring says its state (copper for the best bet,
   slate once it covered), a corner badge repeats it, a faded strikethrough
   is a loss, a dashed plus is a pick still to make. Items are fixed width
   and the row wraps centred, so a phone shows three then two and nothing
   ever scrolls sideways. */
.rail { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 8px; }
.rail-item { width: 92px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px; }
.rail-logo { position: relative; width: 56px; height: 56px; border-radius: 50%; background: var(--bg); border: 2px solid var(--card-edge); display: grid; place-items: center; transition: border-color var(--transition), background-color var(--transition); }
.rail-logo img { width: 42px; height: 42px; object-fit: contain; display: block; }
.rail-abbr-only { font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--tag); }
.rail-plus { font-size: 22px; line-height: 1; color: var(--tag); }
.rail-line { font-family: var(--font-mono); font-size: 13px; color: var(--ink); white-space: nowrap; }
.rail-line b { color: var(--head); font-weight: 700; }
.rail-vs { font-family: var(--font-mono); font-size: 11px; color: var(--tag); white-space: nowrap; letter-spacing: .02em; }
.rail-pts { font-family: var(--font-mono); font-size: 12px; font-weight: 700; color: var(--tag); padding: 1px 8px; border-radius: var(--radius-pill); border: 1px solid var(--rule); margin-top: 2px; transition: box-shadow var(--transition), background-color var(--transition), border-color var(--transition); }
.rail-pts.tbd { letter-spacing: .08em; font-weight: 600; }

/* Once a pick settles, the whole item lights up: a green glow for a win,
   gold for a best bet that came in, red for a miss. The three colours are
   the pick's own meaning and stay fixed across themes; the glow is a soft
   spread around the logo ring and the points pill. */
.rail-item.res-win { --glow: #2f9e6d; }
.rail-item.res-win.is-best { --glow: #d9a441; }
.rail-item.res-loss { --glow: #d9534f; }
.rail-item.res-win .rail-logo, .rail-item.res-loss .rail-logo { border-color: var(--glow); box-shadow: 0 0 0 4px color-mix(in srgb, var(--glow) 22%, transparent), 0 0 18px color-mix(in srgb, var(--glow) 45%, transparent); }
.rail-item.res-win .rail-pts, .rail-item.res-loss .rail-pts { color: #fff; background: var(--glow); border-color: var(--glow); box-shadow: 0 0 12px color-mix(in srgb, var(--glow) 55%, transparent); }
.rail-item.res-win.is-best .rail-pts { color: #3a2a05; }
.rail-item.res-loss { opacity: 1; }
.rail-item.res-loss .rail-line { text-decoration: none; color: var(--tag); }
.rail-item.res-win .badge-win, .rail-item.res-loss .badge-loss { background: var(--glow); }
.rail-item.res-win.is-best .badge-best { background: var(--glow); color: #3a2a05; }
.badge { position: absolute; right: -4px; top: -4px; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font-size: 12px; line-height: 1; border: 2px solid var(--card); }
.badge .ico { width: 11px; height: 11px; stroke-width: 3; }
.badge-best { background: var(--trim); color: var(--bg); left: -4px; right: auto; }
.badge-win { background: var(--head); color: var(--bg); }
.badge-loss { background: var(--ink); color: var(--bg); }
.badge-lock { background: var(--tag); color: var(--bg); }
.badge-live { background: var(--head); width: 12px; height: 12px; right: 0; top: 0; animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.rail-item.is-best .rail-logo { border-color: var(--trim); }
.rail-item.is-locked .rail-line { color: var(--tag); }
.rail-empty .rail-logo { border-style: dashed; background: transparent; }
.rail-empty .rail-line { color: var(--tag); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }

/* A pick in a game that is on flashes its ring every two seconds: green while
   it is covering at the latest score, red while it is not. The same green and
   red as a settled pick, so a live win looks like the win it is heading for.
   The live dot takes the colour too. With reduced motion the ring holds the
   colour and does not flash. */
.rail-item.live-up { --live: #2f9e6d; }
.rail-item.live-down { --live: #d9534f; }
.rail-item.live-up .rail-logo, .rail-item.live-down .rail-logo { animation: live-ring 2s ease-in-out infinite; }
.rail-item.live-up .badge-live, .rail-item.live-down .badge-live { background: var(--live); }
@keyframes live-ring {
  0%, 100% { border-color: var(--live); box-shadow: 0 0 0 4px color-mix(in srgb, var(--live) 22%, transparent), 0 0 16px color-mix(in srgb, var(--live) 45%, transparent); }
  50% { border-color: var(--card-edge); box-shadow: 0 0 0 0 transparent, 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .badge-live { animation: none; }
  .rail-item.live-up .rail-logo, .rail-item.live-down .rail-logo { animation: none; border-color: var(--live); }
}
.week-head .week-nav { display: flex; gap: 8px; margin-bottom: 10px; }
.count-badge { margin-left: auto; font-size: 11px; letter-spacing: .08em; color: var(--tag); }
.is-full .count-badge { color: var(--head); }
.week-grid { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 28px; align-items: start; }
.side-col { position: sticky; top: calc(var(--nav-h) + 16px); }

.game { border: 1px solid var(--card-edge); background: var(--card); border-radius: 14px; padding: 8px 10px; margin-bottom: 8px; transition: border-color .15s ease, background-color var(--transition); }
.game.has-pick { border-color: var(--trim); }
.game.is-live { border-color: var(--head); }
.game-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; color: var(--tag); margin-bottom: 6px; }
.game-meta .kick { font-family: var(--font-mono); letter-spacing: .04em; }
.game-meta .score { color: var(--ink); font-weight: 600; }
.game-meta .score.live { color: var(--head); }
.game-meta [class^="tag-"] { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; }
.game-meta .tag-live { color: var(--head); }
.game-meta .tag-final { color: var(--tag); }
.game-meta .ico { width: 13px; height: 13px; }

.sides { display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px; align-items: stretch; }
.sides .at { align-self: center; font-family: var(--font-mono); font-size: 12px; color: var(--tag); grid-column: 2; grid-row: 1; }
.side-away { grid-column: 1; grid-row: 1; }
.side-home { grid-column: 3; grid-row: 1; }
.side {
  position: relative; display: flex; align-items: center; justify-content: center; gap: 10px;
  border: 1.5px solid var(--card-edge); border-radius: 10px; padding: 8px 10px; cursor: pointer; user-select: none;
  background: transparent; color: var(--ink);
  transition: border-color .12s ease, background-color .12s ease, color .12s ease, opacity .12s ease;
}
.side input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
/* ESPN's team logo, from its CDN; a blank square keeps the row aligned when a game has none. */
.side .logo { width: 34px; height: 34px; object-fit: contain; display: block; flex: none; }
.side .logo-blank { border-radius: 8px; background: var(--rule); }
.side.on .logo { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .25)); }
.side .abbr { font-family: var(--font-mono); font-weight: 700; font-size: 15px; letter-spacing: .02em; }
.side .team { font-size: 12.5px; color: var(--tag); line-height: 1.2; }
.side .line { font-weight: 700; font-size: 14px; color: var(--head); }
.side:hover:not(.static):not(.held) { border-color: var(--ghost-b); }
.side.on { background: var(--btn1-bg); color: var(--btn1-fg); border-color: var(--btn1-bg); }
.side.on .team, .side.on .line { color: inherit; opacity: .85; }
.side.static { cursor: default; }
.side.held { opacity: .45; cursor: not-allowed; }
.is-locked .side:not(.on) { opacity: .6; }
.side.covered:not(.on) { border-style: dashed; border-color: var(--head); }
.side .result { position: absolute; right: 8px; bottom: 3px; font-family: var(--font-mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: .1em; }
.side .result .ico { width: 14px; height: 14px; stroke-width: 3; }
/* A settled pick wears its result on its edge: green for a win, red with a
   red strike for a loss, both a touch heavier than a plain side. The extra
   width is a one-pixel ring outside the border, so the tile does not grow
   and the row does not shift when a game goes final. */
.res-win .side.on { background: var(--head); color: var(--bg); border-color: #2f9e6d; box-shadow: 0 0 0 1px #2f9e6d; }
.res-loss .side.on { background: transparent; color: var(--ink); border-color: #d9534f; box-shadow: 0 0 0 1px #d9534f; text-decoration: line-through; text-decoration-color: #d9534f; text-decoration-thickness: 2px; }
.res-push .side.on { background: var(--pill-bg); color: var(--pill-fg); border-color: var(--pill-b); }

.game-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
/* the best-bet star: beside the kickoff once the game is picked; bold with a thick copper border when chosen */
.best-slot { display: inline-flex; }
.best { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 500; color: var(--tag); cursor: pointer; user-select: none; border-radius: var(--radius-pill); padding: 2px 10px 2px 7px; border: 2px solid var(--card-edge); background: transparent; line-height: 1.4; transition: color .12s ease, border-color .12s ease, background-color .12s ease; }
.best:hover { border-color: var(--ghost-b); color: var(--ink); }
.best input { position: absolute; opacity: 0; width: 0; height: 0; }
.best .star { font-size: 15px; line-height: 1; color: var(--card-edge); transition: color .12s ease; }
.best.on { color: var(--head); font-weight: 700; border-color: var(--trim); background: var(--pill-bg); }
.best.on .star { color: var(--trim); }
/* Where the game is played and the weather there, under the two sides.
   Copper when the conditions could move a line (rain, snow, wind, the ends
   of the thermometer); a dome and a fair day stay grey. */
.where { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; font-size: 12px; color: var(--tag); }
.where .ico { width: 13px; height: 13px; }
.where .dot { color: var(--rule); }
.where.rough { color: var(--pill-fg); }
.others { margin-left: auto; display: flex; gap: 12px; flex-wrap: wrap; font-size: 12px; color: var(--tag); }
.others b { color: var(--ink); font-family: var(--font-mono); font-weight: 700; }

.save-bar { position: sticky; bottom: 12px; display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; margin-top: 14px; padding: 12px 14px; background: var(--card); border: 1px solid var(--card-edge); border-radius: 14px; box-shadow: 0 10px 30px var(--shadow); z-index: 2; }
/* The bar floats only while there is something to save. With the picks saved
   it holds just "Reset picks", and a floating reset button did nothing but sit
   over the games in mid-screen, above the phone browser's own bottom bar. It
   now rests at the foot of the slate until a pick changes. The bottom offset
   also clears the phone's home indicator. */
.pick-form:not([data-dirty]) .save-bar { position: static; box-shadow: none; }
.save-bar { bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
.save-bar .save-hint { width: 100%; text-align: center; }
/* the reset button: a firm dark border, so it reads as a button and not a hint */
.save-bar .btn-ghost { border: 2px solid var(--ink); color: var(--ink); }
.pick-form { padding-bottom: 8px; }
.standings th, .standings td { white-space: nowrap; }
.signin-nudge { margin: 0; line-height: 1.6; }
.signin-nudge a { color: var(--head); }
.standings .name { white-space: nowrap; }
.btn-sm { padding: 9px 16px; font-size: 13px; }

/* ---------- tables ---------- */
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th, .table td { text-align: left; padding: 8px 8px; border-bottom: 1px solid var(--rule); vertical-align: middle; }
.table th { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--tag); font-weight: 700; white-space: nowrap; vertical-align: bottom; line-height: 1.35; }
/* number columns centred under their headings, on the leaderboard and the stats table alike */
.table .num, .table th.num { text-align: center; }
.table .rank { width: 3.2em; color: var(--tag); white-space: nowrap; }
/* gold, silver and bronze trophies beside the top three ranks; ties share both the rank and the metal */
.table .rank .medal { width: 15px; height: 15px; vertical-align: -3px; margin-right: 4px; stroke-width: 2.2; }
.medal-1 { color: #d9a441; }
.medal-2 { color: #9aa3ad; }
.medal-3 { color: #b87333; }
.table .pts { color: var(--head); font-weight: 700; }
.table tr.me td { background: var(--pill-bg); }
.table tr.top td.name { font-weight: 600; }
.table tr.gone td { opacity: .6; }
.table.compact { font-size: 13px; }
.table.compact th, .table.compact td { padding: 6px 6px; }
.table.log tr.bad td { color: var(--ink); }
.table.log tr.bad td:last-child { color: var(--trim); }
/* The admin page's weeks: a block per week, the number, its badges and
   manage on the first line, then one line per fact, badges included. */
.week-list { display: flex; flex-direction: column; margin-bottom: 10px; }
.week-row { display: flex; flex-direction: column; gap: 4px; padding: 12px 0; border-bottom: 1px solid var(--rule); }
.wr-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 2px; }
.wr-num { font-weight: 600; white-space: nowrap; }
.wr-tags { display: flex; gap: 6px; }
.wr-line { display: flex; align-items: center; gap: 12px; min-height: 24px; font-size: 13px; white-space: nowrap; }
.wr-k { flex: 0 0 72px; font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--tag); line-height: 20px; }
.week-add summary { justify-content: flex-start; }
.week-add .inline-form { margin-top: 4px; }

/* The messages page's "not sent yet" list: a block per missed post, name
   over week and due time, the Send button kept to the right and whole. */
.pending-list { display: flex; flex-direction: column; }
.pending-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--rule); }
.pending-row:last-child { border-bottom: none; }
.pr-what { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pr-what a { color: var(--head); }
.pr-send { display: flex; align-items: center; gap: 10px; flex: none; margin: 0; }
.pr-send .btn { white-space: nowrap; }
.pr-skip { margin: 0; flex: none; }
.pr-x { display: inline-grid; place-items: center; width: 44px; height: 44px; margin-right: -10px; border: none; background: none; border-radius: 50%; color: var(--tag); cursor: pointer; }
.pr-x:hover, .pr-x:focus-visible { color: var(--ink); background: var(--bg); }
.pr-x .ico { width: 16px; height: 16px; }

/* The older log lines, behind a toggle under the newest three. The summary
   is the table's full-width tap target and flips its own wording. */
.log-more summary { list-style: none; display: flex; align-items: center; justify-content: center; gap: 6px; min-height: 44px; font-size: 13px; font-weight: 600; color: var(--tag); cursor: pointer; }
.log-more summary::-webkit-details-marker { display: none; }
.log-more .lm-hide, .log-more[open] .lm-show { display: none; }
.log-more[open] .lm-hide { display: inline; }
.log-more[open] .pc-chev { transform: rotate(90deg); }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -22px; padding: 0 22px; }
.leaderboard th.wk a { color: inherit; text-decoration: none; }
.leaderboard th.wk.open a { color: var(--head); }
.standings .name { max-width: 0; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.edit-as { margin-left: 6px; font-size: 11px; color: var(--head); text-decoration: none; font-family: var(--font-mono); letter-spacing: .06em; }
.people { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
.people li.done { color: var(--ink); }
.people li.part, .people li.none { color: var(--tag); }
.people li .mono { font-size: 12px; margin-left: 6px; }

/* ---------- stats (on the leaderboard page) ---------- */
.stats-section { margin-top: 40px; scroll-margin-top: calc(var(--nav-h) + 16px); }
.stats-section > .sec-label { margin-bottom: 18px; }
.stat-title { font-size: 17px; font-weight: 700; color: var(--head); margin: 26px 0 4px; }
.stat-note { margin: 0 0 12px; }
.breakdown th.wk a { color: inherit; text-decoration: none; white-space: nowrap; }
.breakdown th.wk a:hover { color: var(--head); }
.table .teams { white-space: nowrap; font-size: 12.5px; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-bottom: 20px; }
.stat dl { display: grid; grid-template-columns: 1fr auto; gap: 8px 16px; margin: 0; font-size: 14px; }
.stat dt { color: var(--tag); }
.stat dd { margin: 0; text-align: right; color: var(--ink); }

/* ---------- forms ---------- */
.form-card { display: flex; flex-direction: column; gap: 16px; margin-bottom: 18px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label, .form-grid label { font-size: 12px; font-family: var(--font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--tag); font-weight: 700; }
input[type=text], input[type=password], input[type=number], input[type=datetime-local] {
  font: inherit; font-size: 15px; color: var(--ink); background: var(--bg); border: 1.5px solid var(--card-edge); border-radius: 10px; padding: 10px 12px; width: 100%;
  transition: border-color .12s ease, background-color var(--transition), color var(--transition);
}
input:focus { outline: none; border-color: var(--head); }
/* Keyboard focus keeps a ring: the border change alone is too faint a signal. */
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 2px solid var(--head); outline-offset: 2px; }
input.short { width: 7.5em; }

/* The message body. Monospaced because it is written with {placeholders} and
   fenced blocks, and what lines up here lines up in Discord. */
textarea {
  font: inherit; font-size: 15px; color: var(--ink); background: var(--bg); border: 1.5px solid var(--card-edge); border-radius: 10px; padding: 10px 12px; width: 100%;
  resize: vertical; line-height: 1.5;
  transition: border-color .12s ease, background-color var(--transition), color var(--transition);
}
textarea:focus { outline: none; border-color: var(--head); }
textarea.mono-input { font-family: var(--font-mono); font-size: 13.5px; }

/* A rendered message, as close to how Discord will show it as a page can
   get: its own ground, its own wrapping, nothing reflowed. */
.preview {
  margin: 12px 0 0; padding: 14px 16px; border-radius: 10px;
  background: var(--card); border: 1px solid var(--card-edge);
  font-family: var(--font-mono); font-size: 13px; line-height: 1.55; color: var(--ink);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.hint { font-size: 12.5px; color: var(--tag); }
.field-error { font-size: 13px; color: var(--ink); border-left: 3px solid var(--trim); padding-left: 10px; }
/* the admin page's "the cron has stopped" line, clear of the status line under it */
.clock-warn { margin: 0 0 12px; }
.clock-warn p { margin: 0 0 6px; }
.clock-warn p:last-child { margin-bottom: 0; }
.clock-warn code { overflow-wrap: anywhere; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px 14px; align-items: end; }
.form-grid label { display: flex; flex-direction: column; gap: 6px; }
/* A checkbox and its sentence sit on one line. label.check says so already,
   but it is declared earlier in this file at the same specificity, so the
   column rule above was winning and the box was landing over the words, in
   mono capitals. The week page's warm-up toggle had it too. */
.form-grid label.check {
  flex-direction: row; align-items: center; gap: 8px;
  font-family: var(--font); font-size: 13px; font-weight: 500;
  letter-spacing: 0; text-transform: none; color: var(--ink);
}
.form-grid label.check input { width: auto; flex: none; }
.form-grid label.wide, .form-grid .form-actions { grid-column: 1 / -1; }
.form-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.inline-form { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.inline-form.tight { margin: 0; gap: 6px; }
.inline-form label { font-size: 13px; color: var(--tag); }
.inline-form input[type=text] { flex: 1; min-width: 160px; }
.linklike { background: none; border: none; padding: 0; font: inherit; font-size: 12.5px; color: var(--head); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--trim); }
.linklike.danger { color: var(--ink); text-decoration-color: var(--trim); }
.signout { margin-top: 6px; }

/* ---------- admin ---------- */
.admin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 18px; }
/* A grid item's min-width is auto, so the widest thing inside a card set the
   column's width: the games table pushed the single phone column to 478px and
   took the whole admin page sideways with it. Zero lets the column be the
   screen and the scrollers inside do the scrolling. */
.admin-grid > * { min-width: 0; }
.admin-grid .card.wide { grid-column: 1 / -1; }
.btns-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
.btns-row form { margin: 0; }
.btn[disabled] { opacity: .4; cursor: not-allowed; }
.actions { display: flex; gap: 12px; flex-wrap: wrap; }
.actions form { margin: 0; }
/* The Discord ID box in the people table: narrow and monospaced, so a full
   18-digit ID fits and the table still fits a phone. */
.discord-form { flex-wrap: nowrap; }
.discord-form input[type=text] { flex: none; min-width: 0; width: calc(19ch + 22px); padding: 5px 8px; font-family: var(--font-mono); font-size: 12px; border-radius: 8px; }
.email-form { flex-wrap: nowrap; }
.email-form input[type=email] { flex: none; min-width: 0; width: calc(22ch + 22px); padding: 5px 8px; font-size: 12px; border-radius: 8px; }
.google-linked { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }

/* The People list, at every width since 0.10.2: one collapsed line per
   person, the details underneath when opened. Nothing scrolls sideways and
   the actions never wrap down a column. */
.person-card { border-bottom: 1px solid var(--rule); }
.person-card:last-of-type { border-bottom: none; }
.person-card.gone { opacity: .6; }
.person-card summary { list-style: none; display: grid; grid-template-columns: 1fr auto; grid-template-areas: "who chev" "meta chev"; align-items: center; column-gap: 10px; row-gap: 3px; padding: 10px 0; cursor: pointer; }
.person-card summary::-webkit-details-marker { display: none; }
.pc-who { grid-area: who; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pc-name { font-weight: 600; }
.pc-meta { grid-area: meta; display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pc-chev { grid-area: chev; color: var(--tag); transform: rotate(-90deg); transition: transform .15s ease; }
.person-card[open] .pc-chev { transform: rotate(90deg); }
.pc-body { display: flex; flex-direction: column; gap: 10px; padding: 2px 0 14px; }
.pc-row { display: flex; flex-direction: column; gap: 5px; }
.pc-label { font-size: 10.5px; font-family: var(--font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--tag); font-weight: 700; }
.pc-value { font-size: 13px; }
.pc-value .discord-form input[type=text], .pc-value .email-form input[type=email] { flex: 1; width: auto; max-width: 340px; }
.pc-value.actions { gap: 14px; }

/* Sign in with Google. Google's own button colours (white in the light
   theme, near-black in the dark) so it reads as the button people know;
   the shape and type are the kit's .btn. */
.btn-google { background: #fff; color: #1f1f1f; border: 1px solid #747775; gap: 10px; }
.btn-google:hover { background: #f3f3f3; }
[data-theme="dark"] .btn-google { background: #131314; color: #e3e3e3; border-color: #8e918f; }
[data-theme="dark"] .btn-google:hover { background: #1f1f20; }
.gsi-logo { flex: none; width: 18px; height: 18px; }
.gsi-logo-sm { width: 14px; height: 14px; }
.or-rule { display: flex; align-items: center; gap: 12px; color: var(--tag); font-size: 12px; font-family: var(--font-mono); letter-spacing: .08em; text-transform: uppercase; }
.or-rule::before, .or-rule::after { content: ""; flex: 1; border-top: 1px solid var(--card-edge); }
.form-inner { margin-bottom: 0; }
/* The team emoji codes: long, so they wrap rather than widen the table. */
.emoji-codes .team { white-space: nowrap; }
.emoji-codes code { overflow-wrap: anywhere; }
.invites { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.invites li { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; }
.invites code { font-size: 12px; background: var(--bg); padding: 4px 8px; border-radius: 6px; border: 1px solid var(--rule); word-break: break-all; }
.invites form { margin: 0; }

/* ---------- prose ---------- */
.prose { max-width: 66ch; font-size: 15.5px; }
.prose h2 { font-size: 15px; font-family: var(--font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--head); margin: 28px 0 10px; }
.prose ul { padding-left: 20px; }
.prose li { margin-bottom: 8px; }
.prose a { color: var(--head); }

/* ---------- phones ---------- */
@media (max-width: 860px) {
  .week-grid { grid-template-columns: 1fr; }
  .side-col { position: static; }
}
@media (max-width: 560px) {
  .page { padding-top: 18px; }
  .who-name { display: none; }
  /* Phones keep the two sides side by side and drop the team names: the
     logo, the abbreviation and the line are the whole story. The @ stays
     between them, on a narrower gap, so the row still reads as a matchup. */
  .sides { grid-template-columns: 1fr auto 1fr; gap: 6px; }
  .sides .at { font-size: 11px; }
  .side { padding: 8px 8px; gap: 8px; }
  .side .team { display: none; }
  .side .logo { width: 30px; height: 30px; }
  .side .result { font-size: 0; right: 6px; bottom: 2px; }
  .side .result .ico { width: 13px; height: 13px; }
  .others { margin-left: 0; }
  .save-bar { bottom: calc(8px + env(safe-area-inset-bottom, 0px)); padding: 10px 12px; }
  .save-hint { display: none; }
  .admin-grid { grid-template-columns: 1fr; }
  .table-scroll { margin: 0 -22px; padding: 0 22px; }
  /* tighter cells on a phone so the leaderboard's week columns get room */
  .leaderboard th, .leaderboard td { padding: 9px 7px; font-size: 13px; }
  .leaderboard th { vertical-align: bottom; line-height: 1.35; }
  .leaderboard .rank { width: 2.8em; }
  .leaderboard th.wk, .leaderboard td.wk { padding-left: 4px; padding-right: 4px; }
}

/* The admin's buy-in switch inside each person's card: a small track
   and knob, copper once paid, with the state spelled out beside it. */
.buyin-toggle { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 2px; background: none; border: none; font: inherit; font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--tag); cursor: pointer; }
.bt-track { position: relative; width: 34px; height: 20px; border-radius: var(--radius-pill); background: var(--rule); border: 1px solid var(--card-edge); transition: background-color var(--transition), border-color var(--transition); }
.bt-knob { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--card); box-shadow: 0 1px 2px rgba(0, 0, 0, .25); transition: transform var(--transition); }
.buyin-toggle.is-paid { color: var(--head); }
.buyin-toggle.is-paid .bt-track { background: var(--trim); border-color: var(--trim); }
.buyin-toggle.is-paid .bt-knob { transform: translateX(14px); }
.bt-label { min-width: 4.6em; text-align: left; }
