/* style.css — ackackCup design tokens and layout.
   One place to restyle the whole app: change the custom properties below.
   Dark by default, readable from across a room, works down to phone width. */

:root {
  --bg: #0f1117;
  --bg-2: #161a24;
  --bg-3: #1e2432;
  --border: #2a3142;
  --text: #e6e9f0;
  --muted: #8b93a7;
  --accent: #7c5cff;
  --accent-soft: #efeaff;
  --green: #3ddc84;
  --amber: #ffb454;
  --red: #ff5c5c;
  --gold: #ffd166;
  --silver: #c0c7d6;
  --bronze: #cd7f32;
  --radius: 12px;
  --shadow: 0 6px 24px rgba(0, 0, 0, 0.28);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a { color: var(--accent); }
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.9em;
       background: var(--bg-3); border-radius: 4px; padding: 1px 5px; }

/* ------------------------------------------------------------------ top bar */
.topbar {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: 12px; padding: 14px 22px; background: var(--bg-2);
  border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 10;
}
.brand { display: flex; align-items: center; gap: 12px; }
/* The Relic Arena wordmark (assets/, mounted at /assets): 178×124, so size it by height. */
.brand .logo { height: 40px; width: auto; display: block; }
.brand h1 { font-size: 19px; letter-spacing: 0.3px; }
.brand .subtitle { color: var(--muted); font-size: 13px; }

.status-cluster { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.badge {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text);
  border-radius: 999px; padding: 4px 12px; font-size: 12.5px; letter-spacing: 0.2px;
}
.conn { display: inline-flex; align-items: center; gap: 7px; color: var(--muted); font-size: 12.5px; }
.conn .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); }
.conn[data-state="live"] .dot { background: var(--green); box-shadow: 0 0 8px var(--green); }
.conn[data-state="offline"] .dot { background: var(--red); }

/* --------------------------------------------------------------------- main */
main { flex: 1; width: 100%; max-width: 1080px; margin: 0 auto; padding: 22px; }
/* the admin editor is dense: give it more room (the viewer stays narrow) */
body.admin main { max-width: 1440px; }

.card {
  background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px 20px; margin-bottom: 18px; box-shadow: var(--shadow);
}
.card h2 { font-size: 15px; color: var(--accent); margin-bottom: 10px; letter-spacing: 0.2px; }

.notice { background: var(--bg-2); border: 1px solid var(--border); border-left: 3px solid var(--accent);
          border-radius: var(--radius); padding: 18px 20px; margin-bottom: 18px; }
.notice h2 { font-size: 16px; margin-bottom: 6px; }
.notice p { color: var(--muted); font-size: 14px; }
.notice .links { margin-top: 10px; font-size: 13.5px; }

/* ------------------------------------------------------------------- tables */
table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
thead th {
  text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.7px;
  color: var(--muted); border-bottom: 1px solid var(--border); padding: 8px 10px;
}
tbody td { padding: 10px; border-bottom: 1px solid var(--border); font-size: 14.5px; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--bg-3); }
.num { text-align: right; }
/* a numeric column hugs its content: the flexible column takes the slack, so the value
   sits under its own header instead of drifting under the next one */
thead th.num { text-align: right; }
th.num, td.num { width: 1%; white-space: nowrap; }
tbody tr.empty td { color: var(--muted); font-style: italic; text-align: center; padding: 26px; }
.rank-1 td:first-child { color: var(--gold); font-weight: 700; }
.rank-2 td:first-child { color: var(--silver); font-weight: 700; }
.rank-3 td:first-child { color: var(--bronze); font-weight: 700; }

/* ------------------------------------------------------------ key/value list */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 6px 18px; font-size: 14px; }
.kv dt { color: var(--muted); }
.kv dd { font-variant-numeric: tabular-nums; }
.ok { color: var(--green); }
.warn { color: var(--amber); }
.bad { color: var(--red); }

/* ------------------------------------------------------------------ admin */
.tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.tab { background: transparent; border: 1px solid var(--border); color: var(--muted);
       border-radius: 8px; padding: 8px 14px; font-size: 13.5px; cursor: pointer; }
.tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.tab[disabled] { opacity: 0.45; cursor: not-allowed; }
ul.roadmap { list-style: none; font-size: 14px; }
ul.roadmap li { padding: 7px 0; border-bottom: 1px solid var(--border); }
ul.roadmap li:last-child { border-bottom: 0; }
ul.roadmap .tag { font-size: 11.5px; border-radius: 6px; padding: 2px 7px; margin-right: 8px; }
.tag.done { background: rgba(61, 220, 132, 0.15); color: var(--green); }
.tag.next { background: rgba(124, 92, 255, 0.18); color: var(--accent); }
.tag.later { background: var(--bg-3); color: var(--muted); }

/* ------------------------------------------------------- admin editor (M1) */
.tab-body { display: block; }
.notify {
  border-radius: var(--radius); padding: 10px 14px; margin-bottom: 14px; font-size: 14px;
  border: 1px solid var(--border); background: var(--bg-2);
}
.notify.ok { border-color: var(--green); color: var(--green); background: rgba(61, 220, 132, 0.12); }
.notify.error { border-color: var(--red); color: var(--red); background: rgba(255, 92, 92, 0.12); }
.notify[hidden] { display: none; }

.card h3 {
  font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.7px;
  margin: 16px 0 8px;
}
.hint { color: var(--muted); font-size: 13px; margin-bottom: 10px; }

.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 10px 16px; margin-bottom: 10px; }
.grid .wide { grid-column: 1 / -1; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; margin-bottom: 10px; }
/* a textarea in a `.row` takes the whole line: it is never as narrow as an input */
.row .wide { flex: 1 1 100%; }
.row .wide textarea { width: 100%; }
label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }

input, select, textarea {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 7px 9px; font-size: 13.5px; font-family: inherit; min-width: 90px;
}
input[type="checkbox"] { min-width: auto; width: 16px; height: 16px; }
textarea { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

button {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 8px 12px; font-size: 13px; font-family: inherit; cursor: pointer;
}
button:hover:not([disabled]) { border-color: var(--accent); }
button[disabled] { opacity: 0.4; cursor: not-allowed; }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
button.danger { color: var(--red); }
button.primary.danger { background: var(--red); border-color: var(--red); color: #fff; }

.actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 10px; }

/* Tables must never push past their card: the wrapper scrolls, the cells shrink. */
.table-wrap { overflow-x: auto; max-width: 100%; }
.admin-table { margin-top: 12px; width: 100%; }
.admin-table th, .admin-table td { padding: 8px 7px; }
.admin-table input, .admin-table select { min-width: 0; width: 100%; }
.admin-table input.name { min-width: 110px; max-width: 190px; }
.admin-table input.title { min-width: 130px; }
.admin-table input.description { min-width: 200px; }
.admin-table input.points { min-width: 64px; }
.admin-table input.stats_url, .admin-table input.discord,
.admin-table input.in_game_id { min-width: 96px; }
.admin-table input.stats_url { min-width: 170px; }   /* a pasted address, not a file name */
.admin-table select.kind, .admin-table select.input { min-width: 96px; }
.admin-table select.round_id { min-width: 140px; }
.admin-table td.check { width: 56px; text-align: center; }
.admin-table td.tight { width: 1%; white-space: nowrap; }
.admin-table .seat-cell { text-align: center; }
.admin-table .seat {
  display: inline-block; min-width: 24px; padding: 1px 6px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--border); color: var(--muted);
  font-size: 12.5px; font-variant-numeric: tabular-nums;
}
.admin-table .row-actions { display: flex; gap: 4px; }
.admin-table .row-actions button { padding: 6px 9px; }
.admin-table .options { display: grid; gap: 4px; grid-template-columns: max-content max-content; }
.admin-table .options label { flex-direction: row; align-items: center; gap: 5px; font-size: 11.5px; }
.admin-table .options select, .admin-table .options input { width: 86px; }
.nowrap { white-space: nowrap; }

/* Counters ("9/16"), callouts, and the "a change was saved" feedback. */
.count {
  font-size: 12.5px; font-variant-numeric: tabular-nums; border-radius: 999px; padding: 2px 10px;
  margin-left: 8px; background: var(--bg-3); border: 1px solid var(--border); color: var(--muted);
}
.count.ok { color: var(--green); border-color: rgba(61, 220, 132, 0.5); }
.count.off { color: var(--amber); border-color: rgba(255, 180, 84, 0.5); }
.callout {
  border: 1px solid rgba(255, 180, 84, 0.55); border-left-width: 3px; border-radius: 10px;
  background: rgba(255, 180, 84, 0.08); padding: 10px 12px; margin: 10px 0; font-size: 13.5px;
}
.callout .actions { margin-top: 8px; }
.callout.bad { border-color: rgba(255, 92, 92, 0.55); background: rgba(255, 92, 92, 0.08); }
.callout.warn { border-color: rgba(255, 180, 84, 0.55); background: rgba(255, 180, 84, 0.08); }

/* the cut preview: one list per group, the line between "through" and "out" (§5.9) */
.cut-groups { display: flex; flex-wrap: wrap; gap: 14px; margin: 10px 0; }
.cut-group { flex: 1 1 240px; min-width: 220px; }
.cut-group h3 { margin: 0 0 6px; font-size: 13px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em; }
ol.cut-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
ol.cut-list li { display: grid; grid-template-columns: 22px 1fr auto auto; gap: 8px;
  align-items: center; padding: 3px 8px; border-radius: 8px; font-size: 13.5px;
  border: 1px solid transparent; }
ol.cut-list li.through { background: rgba(61, 220, 132, 0.08);
  border-color: rgba(61, 220, 132, 0.28); }
ol.cut-list li.out { background: var(--bg-2); color: var(--muted); }
ol.cut-list li .rank { color: var(--muted); font-variant-numeric: tabular-nums; }
ol.cut-list li .pts { font-variant-numeric: tabular-nums; color: var(--accent-soft); }
.tag.none { background: var(--bg-3); color: var(--muted); }

/* the cup shape: one column per stage, one box per group, arrows between them (§5.10) */
.bracket { display: flex; flex-wrap: wrap; gap: 14px; align-items: stretch; margin: 10px 0; }
.stage-column { flex: 1 1 260px; min-width: 240px; border: 1px solid var(--border);
  border-radius: 12px; background: var(--bg-2); padding: 10px 12px; position: relative; }
.stage-column.playing, .stage-column.active { border-color: rgba(124, 92, 255, 0.5); }
.stage-column.done { opacity: 0.85; }
.stage-head { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-bottom: 8px; }
.stage-column + .stage-column::before { content: '→'; position: absolute; left: -12px; top: 50%;
  color: var(--muted); transform: translateY(-50%); }
.group-box { border: 1px dashed var(--border); border-radius: 10px; padding: 6px 8px;
  margin-bottom: 8px; background: var(--bg-1); }
.group-box.open { border-style: solid; border-color: rgba(61, 220, 132, 0.35); }
.group-box.waiting { opacity: 0.75; }
.group-head { display: flex; align-items: center; justify-content: space-between; gap: 6px;
  font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em;
  margin-bottom: 4px; }
ol.group-players { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: 1fr 1fr; gap: 0 8px; font-size: 13px; }
ol.group-players li.gone { color: var(--muted); text-decoration: line-through; }
.cut-line { margin-top: 6px; border-top: 1px dashed rgba(255, 180, 84, 0.6); padding-top: 4px;
  font-size: 11.5px; color: var(--amber); text-align: center; }

/* moving players between the groups of a stage that has not started yet (§5.10) */
.group-box.movable { border-color: rgba(124, 92, 255, 0.45); }
ol.group-players li { display: flex; align-items: center; gap: 4px; min-width: 0; }
ol.group-players li .who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
ol.group-players li[draggable="true"] { cursor: grab; }
ol.group-players li.dragging { opacity: 0.45; }
/* the tags inside a shape box — *out* (§5.9) and *in for X* (§5.11). The base `.tag` look is the
   viewer's, so the admin gets the same pill here rather than bare text */
.group-box .tag { display: inline-block; padding: 0 6px; border-radius: 999px; font-size: 11px;
                  background: var(--bg-2); border: 1px solid var(--border); color: var(--muted);
                  white-space: nowrap; }
.group-box .tag.out { color: var(--red); border-color: rgba(255, 92, 92, 0.45); }
ol.group-players li .row-swap { padding: 0 5px; font-size: 11px; line-height: 1.6;
  border-radius: 6px; color: var(--muted); }
ol.group-players li .row-swap:hover { color: var(--accent); }
.group-box.drop-target { border-color: var(--accent); border-style: solid;
  background: rgba(124, 92, 255, 0.1); }
li.swap-pick-row { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px; padding: 4px 0; }
li.swap-pick-row select { max-width: 160px; }
li.swap-pick-row button { padding: 3px 9px; font-size: 12px; }
.swap-hint { color: var(--accent); }

/* the viewer's group tables: one ranking per group, with the cut line drawn in (§5.10) */
.group-standings { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 14px; margin: 10px 0 4px; }
.group-panel h3 { margin: 0 0 6px; font-size: 15px; display: flex; align-items: center;
  justify-content: space-between; gap: 8px; }
.group-panel h3 .hint { font-size: 12px; font-weight: 400; }
/* the standings are the group tables and nothing else (§9.2.2): when there is nothing to rank
   yet, one dashed box says why instead of an empty ranking */
.group-panel.group-notice { display: flex; align-items: center; justify-content: center;
  min-height: 104px; border: 1px dashed var(--border); border-radius: 10px; }
.group-panel.group-notice p { margin: 0; }
table.standings tr.cut-line td { border-top: 1px dashed rgba(255, 180, 84, 0.6);
  color: var(--amber); font-size: 11.5px; text-align: center; padding: 2px 0 6px; }
button[data-state="busy"] { opacity: 0.6; cursor: progress; }
button[data-state="done"] { border-color: var(--green); color: var(--green); }

@keyframes flash-row { from { background: rgba(61, 220, 132, 0.24); } to { background: transparent; } }
@keyframes flash-card { 0% { box-shadow: 0 0 0 3px var(--green); } 100% { box-shadow: var(--shadow); } }
tr.flash { animation: flash-row 1.6s ease-out; }
details.table-card.flash { animation: flash-row 1.6s ease-out; }
.card.flash { animation: flash-card 1.6s ease-out; }

/* Confirmations always visible, wherever the admin has scrolled to. */
.toast {
  position: fixed; right: 18px; bottom: 18px; z-index: 50; max-width: min(420px, 90vw);
  display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--bg-3); box-shadow: var(--shadow); font-size: 14px;
}
.toast[hidden] { display: none; }
.toast.ok { border-color: var(--green); background: #14251c; color: var(--green); }
.toast.error { border-color: var(--red); background: #2a1618; color: #ffd9d9; }
.toast .toast-close {
  background: transparent; border: 0; color: inherit; padding: 0 2px; font-size: 15px;
  line-height: 1; cursor: pointer;
}

.points-grid { display: flex; gap: 8px; flex-wrap: wrap; }
.points-grid .pt { align-items: center; }
.points-grid .pt span { font-size: 11.5px; }
.points-grid .pt input { width: 68px; text-align: center; }

ol.chain { list-style: none; display: flex; flex-direction: column; gap: 6px; }
ol.chain li {
  display: flex; align-items: center; gap: 8px; background: var(--bg-3);
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; font-size: 13.5px;
}
ol.chain li > span:first-child { flex: 1; }
ol.chain button { padding: 3px 9px; }

ul.roster { list-style: none; display: grid; gap: 6px;
            grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
ul.roster li {
  display: flex; align-items: center; gap: 8px; background: var(--bg-3);
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px; font-size: 14px;
}
ul.roster .seat { color: var(--muted); font-variant-numeric: tabular-nums; min-width: 18px; }
ul.roster .who { flex: 1; }
ul.roster button { padding: 2px 8px; }
ul.roster li.empty { grid-column: 1 / -1; color: var(--muted); font-style: italic; }
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chips button { border-radius: 999px; }

details.table-card {
  border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin-top: 10px;
  background: var(--bg-3);
}
details.table-card summary { cursor: pointer; display: flex; gap: 10px; align-items: baseline; }

/* the manual half of the seating card: dealing a single round by hand (§5.10 keeps it out of
   the way — the Cup shape card deals whole stages) */
details.seating-advanced { border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px;
  margin: 8px 0; background: var(--bg-2); }
details.seating-advanced > summary { cursor: pointer; color: var(--muted); font-size: 13px; }
details.seating-advanced[open] > summary { color: var(--text); margin-bottom: 4px; }
.seats { display: grid; gap: 8px; margin: 10px 0;
         grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); }
.seat-pick { flex-direction: row; align-items: center; gap: 6px; }
.seat-pick select { min-width: 80px; width: 100%; }

/* ------------------------------------------------- score entry (M2, §9.1) */
.side-by-side { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; align-items: start; }
@media (max-width: 900px) { .side-by-side { grid-template-columns: 1fr; } }

.chips button.chip {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  border-radius: 10px; padding: 6px 12px; line-height: 1.15;
}
.chips button.chip em { font-style: normal; font-size: 11.5px; color: var(--muted); }
.chips button.chip.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.chips button.chip.done { border-color: rgba(61, 220, 132, 0.45); }
.chips button.chip.off { opacity: 0.55; }

table.score-table { width: 100%; }
table.score-table th:nth-child(1), table.score-table td:nth-child(1) { width: 74px; }
table.score-table th:nth-child(2), table.score-table td:nth-child(2) { width: 230px; }
table.score-table td { padding: 7px 8px; }
.score-row input.place {
  width: 58px; text-align: center; font-size: 16px; padding: 5px 4px;
  background: var(--bg-3); border: 1px solid var(--border); border-radius: 8px;
}
.score-row input.place:focus { outline: none; border-color: var(--accent); }
.score-row button.name {
  background: none; border: none; padding: 0; font-size: 15px; color: var(--fg);
  text-align: left; cursor: pointer; border-bottom: 1px dashed var(--border);
}
.score-row button.name:hover { color: var(--accent); border-bottom-color: var(--accent); }
.score-row td.tasks { vertical-align: middle; }
/* the global `label` rule stacks its children — a task label is one line, checkbox first */
.score-row td.tasks .task {
  display: inline-flex; flex-direction: row; align-items: center; gap: 5px;
  font-size: 13.5px; color: var(--text); white-space: nowrap; margin: 2px 14px 2px 0;
}
.score-row td.tasks .task em { font-style: normal; color: var(--muted); font-size: 12px; }
.score-row td.tasks .task input.qty { width: 46px; padding: 2px 4px; }
.score-row td.tasks .tag { display: inline-flex; align-items: center; gap: 4px;
                           margin: 2px 8px 2px 0; }
.score-row td .hint { margin-left: 6px; }
.hint.ok { color: var(--green); }
.hint.bad { color: var(--red); }

details.ad-hoc { margin-top: 10px; }
details.ad-hoc summary { cursor: pointer; color: var(--muted); font-size: 13px; }

ul.awards { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 6px; }
ul.awards li { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
               padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px;
               background: var(--bg-3); font-size: 13.5px; }
ul.awards button.remove-award { padding: 0 6px; }

table.admin-table.compact td, table.admin-table.compact th { padding: 5px 8px; font-size: 13.5px; }
table.admin-table tr.manual td { background: rgba(124, 92, 255, 0.10); }
/* the row whose points and tables the panel below is showing */
table.admin-table tr.selected td { background: rgba(124, 92, 255, 0.07); }
table.admin-table tr.selected td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* checkboxes in a grid (the §5.8 rules) sit next to their label, not under it */
.grid label.check { flex-direction: row; align-items: center; gap: 6px; font-size: 12.5px; }


/* --------------------------------------------------- viewer & overlay (§9.2, M3) */
body.viewer main { max-width: 1200px; }
.badge.live { display: inline-flex; align-items: center; gap: 6px; color: var(--green);
              border-color: rgba(61, 220, 132, 0.5); }
.badge.live .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green);
                   animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* the standings: the ranks are the point, so points are the biggest number in the row */
table.standings td.points { font-weight: 700; font-size: 16px; }
table.standings.compact th, table.standings.compact td { padding: 6px 8px; font-size: 13.5px; }
table.standings tr.clickable { cursor: pointer; }
table.standings tr.unranked { opacity: 0.6; }
table.standings tr.total td { font-weight: 700; border-top: 1px solid var(--border); }

/* a tag explains a row: manual rank call, tie, award, table status */
body.viewer .tag, body.overlay .tag {
  display: inline-flex; align-items: center; gap: 4px; border-radius: 999px;
  padding: 1px 8px; font-size: 11.5px; background: var(--bg-2);
  border: 1px solid var(--border); color: var(--muted); white-space: nowrap;
}
body.viewer .tag.manual { color: var(--accent); border-color: rgba(124, 92, 255, 0.55); }
body.viewer .tag.tied { color: var(--amber); border-color: rgba(255, 180, 84, 0.5); }
/* eliminated (§5.9): the row stays readable but the tag is unmistakable */
body.viewer .tag.out { color: var(--red); border-color: rgba(255, 92, 92, 0.45); }
/* a stand-in (§5.11) and a reserve (§5.12): the place is somebody else's, its points are the place's */
.tag.stand-in { color: var(--amber); border-color: rgba(255, 180, 84, 0.5); }
.admin-table .tag.stand-in { display: inline-block; margin-left: 6px; font-size: 11.5px; }
.tag.reserve { color: var(--accent-soft); border-color: rgba(124, 92, 255, 0.5); }
.admin-table .tag.reserve { display: inline-block; margin-left: 6px; font-size: 11.5px; }
/* "unable to participate" (§5.12): the player cannot play the next stage, so the place moves on */
.tag.afk { color: var(--red); border-color: rgba(255, 92, 92, 0.45); }
.admin-table .tag.afk { display: inline-block; margin-left: 6px; font-size: 11.5px; }

/* the picker for a place that has to change hands (§5.12): the store's own list, with its reasons */
.substitute-picker { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
                     grid-column: 1 / -1; }
.substitute-picker select { max-width: 340px; }
.substitute-picker .why { flex-basis: 100%; margin: 0; font-size: 11.5px; }
body.viewer table.standings tr.out { opacity: 0.55; }
body.viewer .tag.finished, body.overlay .tag.finished { color: var(--green);
  border-color: rgba(61, 220, 132, 0.45); }
body.viewer .tag.in_progress { color: var(--amber); border-color: rgba(255, 180, 84, 0.5); }
body.viewer .tag.void { color: var(--red); border-color: rgba(255, 92, 92, 0.45); }
.tag.award { color: var(--accent-soft); border-color: rgba(124, 92, 255, 0.5); }
.tag.award em { font-style: normal; color: var(--accent); }

.chips button.chip.live { border-color: rgba(255, 180, 84, 0.5); }

/* the stand-ins note at the foot of a round card (§5.11): who is playing whose seat */
.stand-ins { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.stand-ins h3 { display: flex; align-items: center; gap: 8px; font-size: 12.5px;
                text-transform: uppercase; letter-spacing: 0.6px; color: var(--muted);
                margin: 0 0 6px; }
.stand-ins ul { list-style: none; display: grid; gap: 4px; }
.stand-ins li { font-size: 13.5px; }
.stand-ins strong { color: var(--text); }

/* one card per table, seats in placement order */
.round-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
               gap: 12px; margin: 12px 0 4px; }
.table-card { background: var(--bg-3); border: 1px solid var(--border); border-radius: 10px;
              padding: 12px 14px; }
.table-card h3 { display: flex; align-items: center; justify-content: space-between; gap: 8px;
                 font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.6px;
                 color: var(--muted); margin: 0 0 8px; }
ol.seats { list-style: none; display: grid; grid-template-columns: 1fr; gap: 3px; }
ol.seats li { display: grid; grid-template-columns: 24px 1fr auto; align-items: baseline;
              gap: 8px; padding: 3px 0; border-bottom: 1px solid rgba(42, 49, 66, 0.5); }
ol.seats li:last-child { border-bottom: 0; }
ol.seats li.empty { grid-template-columns: 1fr; color: var(--muted); font-style: italic; }
ol.seats .place { text-align: center; font-variant-numeric: tabular-nums; color: var(--muted); }
ol.seats li.place-1 .place, ol.seats li.place-1 .name { color: var(--gold); font-weight: 700; }
ol.seats li.place-2 .place, ol.seats li.place-2 .name { color: var(--silver); font-weight: 600; }
ol.seats li.place-3 .place, ol.seats li.place-3 .name { color: var(--bronze); font-weight: 600; }
ol.seats .pts { font-variant-numeric: tabular-nums; font-weight: 600; }
ol.seats .badges { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: 5px; }

/* the bonus catalog and the breakdown's award list share this list look */
ul.tasks { list-style: none; display: grid; gap: 6px; }
ul.tasks li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
              border: 1px solid var(--border); background: var(--bg-3); border-radius: 8px;
              padding: 7px 10px; font-size: 13.5px; }
ul.tasks li.empty { border: 0; background: none; color: var(--muted); font-style: italic; }
ul.tasks .what { color: var(--muted); }
ul.tasks .when { margin-left: auto; color: var(--muted); font-size: 12px; }

details.service { margin: 4px 0 18px; }
details.service summary { cursor: pointer; color: var(--muted); font-size: 13px; }
details.service .kv { margin-top: 10px; }

/* ----------------------------------------------------------------- footer */
.footer {
  display: flex; justify-content: space-between; gap: 12px; padding: 14px 22px;
  border-top: 1px solid var(--border); color: var(--muted); font-size: 12.5px;
}

/* --------------------------------------------------- overlay (stream / TV) */
body.overlay { background: transparent; }
body.overlay .topbar { background: rgba(22, 26, 36, 0.82); }
body.overlay .brand .logo { height: 34px; }        /* the panel is small: keep the header short */
body.overlay main { max-width: 620px; }
body.overlay .card { background: rgba(22, 26, 36, 0.82); }
body.overlay .footer { display: none; }
body.overlay .standings td, body.overlay .standings th { padding: 9px 11px; font-size: 16px; }
body.overlay .standings td.points { font-size: 18px; }
body.overlay .card h2 { font-size: 13px; }
body.overlay .count { font-size: 11.5px; }
/* the rules panel drops the standings table for a text block on the same card */
body.overlay .rules-text { font-size: 17px; line-height: 1.55; }

/* ------------------------------------------------------- a player's stats page (007) */
/* The player's NAME is the link (no address is ever printed on the page — the standings are read
   from the far side of the room). So the link has to look like the name it replaces and only admit
   it can be clicked on hover: inherit the colour, including a gold/silver/bronze finish, and keep
   one quiet dotted line under it. The standings rows, the round's seat lists and the breakdown
   heading all use this one class (static/ui.js `playerNameHTML`). */
.player-link {
  color: inherit; text-decoration: none;
  border-bottom: 1px dotted rgba(255, 255, 255, 0.3);
}
.player-link:hover, .player-link:focus-visible {
  color: var(--accent); border-bottom-color: var(--accent);
}

/* ------------------------------------------------------- the game stats link (006) */
/* The audience's way out to the full RelicStats page of the game it just watched. Rendered only
   when the admin pasted one (app.js), so there is never a dead link on the viewer. */
.stats-link {
  color: var(--accent); font-weight: 600; text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
}
.stats-link:hover { border-bottom-color: var(--accent); }
.table-card p.hint a.stats-link { font-size: 13px; }

/* ------------------------------------------------------- the rules (004) */
/* The button that opens them, on the viewer and on the overlay. */
.rules-button {
  background: var(--bg-3); border: 1px solid var(--border); color: var(--text);
  border-radius: 999px; padding: 6px 14px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.rules-button:hover { border-color: var(--accent); color: var(--accent); }

/* Plain text, exactly as typed: the admin's line breaks are the formatting. */
.rules-text {
  white-space: pre-wrap;          /* keep the line breaks… */
  overflow-wrap: break-word;      /* …but never let a long line push the page wide */
  line-height: 1.65; font-size: 15px; color: var(--text); margin: 0;
}
dialog.rules {
  background: var(--bg-2); border: 1px solid var(--border);
  color: var(--text); border-radius: 14px; padding: 0;
  width: min(680px, calc(100vw - 32px)); max-height: min(80vh, 780px);
}
dialog.rules::backdrop { background: rgba(8, 10, 16, 0.62); }
dialog.rules .rules-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 14px 18px 10px; border-bottom: 1px solid var(--border);
}
dialog.rules h2 { margin: 0; font-size: 15px; text-transform: uppercase; letter-spacing: 0.7px; }
dialog.rules .rules-body { padding: 14px 18px; overflow: auto; max-height: 62vh; }
dialog.rules .rules-foot {
  display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 10px;
  padding: 10px 18px 14px; border-top: 1px solid var(--border);
}
dialog.rules .rules-foot .hint { margin: 0 auto 0 0; }
/* on a phone the overlay address is noise: the Close button is what matters */
@media (max-width: 560px) {
  dialog.rules .rules-foot .hint { display: none; }
  dialog.rules .rules-foot { justify-content: flex-end; }
}
/* the overlay's copy needs no dialog chrome: the panel *is* the card */
body.overlay #rules-panel .rules-text { margin-top: 6px; }

/* ------------------------------------------------------------ the admin login (§8.2) */
/* One narrow card and nothing else: this page is either skipped entirely (no password) or seen once
   per evening, so it stays out of the way — but it is also the only thing between a stranger and the
   score entry, so the button is the primary one and the field is big enough to type on a phone. */
body.login main { max-width: 460px; margin-top: 5vh; }
body.login .login-card h2 { font-size: 16px; }
body.login .login-card .hint { margin-bottom: 14px; }
body.login label { font-size: 13px; }
body.login input[type="password"] { width: 100%; padding: 11px 12px; font-size: 16px; }
body.login .login-actions { align-items: center; gap: 12px; margin: 14px 0 0; }
body.login .login-actions button { padding: 10px 20px; font-size: 14px; }
body.login #login-next { margin: 0 0 0 auto; text-align: right; }
body.login #login-error { margin: 14px 0 0; }
body.login .login-foot { margin: 0; }
body.login .notice { text-align: left; }
body.login .notice .links { line-height: 2; }

@media (max-width: 620px) {
  main { padding: 14px; }
  .topbar { padding: 12px 14px; }
  thead th, tbody td { padding: 8px 6px; }
}
