/* Six links and a name on a phone: the row has to be allowed to break. */
.online-nav { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-left:8px; }
.online-nav .online-user { font-size:.9rem; color:var(--ink-soft); }
.online-status { margin:10px 0; padding:9px 11px; border-radius:7px; color:var(--ink); background:var(--info-wash); }
.online-status.error { background:var(--bad-wash); color:var(--bad-ink); }
.online-status.good { background:var(--good-wash); color:var(--good-ink); }
.online-status:empty { display:none; }
/* Every run counts: a replay says so, quietly, and the clock waits dimmed
   for the first mark. */
.online-status.replay, .online-replay, .mark-replay { color:var(--ink-soft); }
#timer.is-idle { opacity:.45; }
.online-rank { margin:6px 0 0; font-size:.85rem; font-variant-numeric:tabular-nums; }
.online-actions { display:flex; flex-wrap:wrap; gap:8px; margin:10px 0; }
/* The other ways this case may be played, under its title. */
.online-modes { display:flex; flex-wrap:wrap; gap:8px; margin:8px 0 0; }
.online-content { max-width:920px; margin:30px auto; padding:0 16px; }
.online-content table { width:100%; border-collapse:collapse; background:var(--card); }
.online-content th,.online-content td { padding:9px; border-bottom:1px solid var(--rule); text-align:left; }
.online-content th { font-size:.85rem; color:var(--ink-soft); }
.online-content h2 { margin:22px 0 8px; font:700 15px/1.3 var(--sans); }
#online-history h2,#lb-panel h2:first-child { margin-top:16px; }
/* A button that hides itself: .act declares a display, so [hidden] needs help. */
.online-content .act[hidden] { display:none; }
.online-content td .online-actions { margin:0; gap:6px; }
.online-content td .act { padding:5px 7px; font-size:10px; box-shadow:2px 2px 0 var(--shadow); }
.online-content #online-more { margin:10px 0 0; }

/* The player's own record: three numbers, then the detail. */
.online-tiles { display:grid; gap:10px; margin:14px 0 4px; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); }
.tile { padding:12px 14px; background:var(--card); border:2px solid var(--outline); border-radius:10px; box-shadow:3px 3px 0 var(--shadow); }
.tile b { display:block; font:800 24px/1.1 var(--sans); font-variant-numeric:tabular-nums; }
.tile span { display:block; margin-top:4px; color:var(--ink-soft); font:700 10.5px/1.3 var(--sans); text-transform:uppercase; letter-spacing:.06em; }
#online-settings { margin:22px 0 0; padding-top:14px; border-top:1px solid var(--rule); }
#online-settings[hidden] { display:none; }
.toggle { display:inline-flex; align-items:center; gap:7px; cursor:pointer; font:500 13px/1.3 var(--sans); color:var(--ink); }
.toggle input { margin:0; }

/* The boards: one tab per case on a wide screen, a select on a narrow one. */
.online-tabs { display:flex; flex-wrap:wrap; gap:6px; margin:14px 0 4px; }
.online-tabs .act[aria-selected="true"] { color:var(--ground); background:var(--ink); border-color:var(--ink); }
.online-select { display:none; width:100%; margin:14px 0 4px; }
/* The way of playing, under the case it is played on. Smaller than the case
   tabs, because it is a choice within one board rather than between boards --
   and it stays visible on a narrow screen, where there is no select for it. */
.lb-modes { display:flex; flex-wrap:wrap; gap:6px; margin:2px 0 8px; }
.lb-modes .act { font-size:11.5px; padding:4px 9px; }
.lb-modes .act[aria-selected="true"] { color:var(--ground); background:var(--ink); border-color:var(--ink); }
#lb-panel .toggle { margin:10px 0 0; }
/* A case played two ways has two boards; one way is no choice at all. */
.lb-mode { display:inline-flex; align-items:center; gap:7px; margin:10px 0 0; font:700 10.5px/1.3 var(--sans); text-transform:uppercase; letter-spacing:.06em; color:var(--ink-soft); }
.lb-mode select { font:500 12.5px/1 var(--sans); text-transform:none; letter-spacing:0; color:var(--ink); background:var(--card); border:2px solid var(--outline); border-radius:7px; padding:5px 7px; }

/* What a scored mode's run was worth, beside the clock it also took. */
.score-label { font-weight:700; white-space:nowrap; }
.online-content tr.is-me { background:var(--gold-wash); }
.online-content tr.is-me td { font-weight:700; }
.mark-assisted { color:var(--gold-text); }
.online-content td, .online-content th { font-variant-numeric:tabular-nums; }

@media (max-width:620px) {
  .online-nav { gap:4px; }
  .online-user { display:none; }
  /* Too narrow for a date as well as a time: the time is what matters. */
  .online-content .col-when { display:none; }
  .online-tabs { display:none; }
  .online-select { display:block; }
}

/* The activity page: seven small numbers, then six plain tables -- one of
   them, the website's own accounts, carrying five small numbers of its own. */
.online-content[data-page="activity"] { max-width:1180px; }
#activity-notice[hidden] { display:none; }
.online-content[data-page="activity"] .online-tiles { grid-template-columns:repeat(auto-fit,minmax(118px,1fr)); }
.online-content[data-page="activity"] .tile b { font-size:20px; }
.activity-panel { margin:22px 0 0; }
.activity-panel h2 { margin:0 0 6px; }
.activity-panel .online-tiles { margin:0 0 10px; }
.activity-controls { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 8px; }
.activity-controls:empty { display:none; }
.activity-controls .hint { margin:0; }
.activity-choice,.activity-search { font:500 12.5px/1 var(--sans); color:var(--ink); background:var(--card); border:2px solid var(--outline); border-radius:7px; padding:6px 8px; }
.activity-search { flex:1 1 180px; max-width:280px; }
.online-content table.activity-table { margin:0; font:400 12.5px/1.35 var(--sans); background:var(--card); }
.online-content table.activity-table th,.online-content table.activity-table td { padding:6px 8px; border-bottom:1px solid var(--rule); text-align:left; vertical-align:top; white-space:nowrap; }
.online-content table.activity-table th { font:700 10px/1.4 var(--sans); text-transform:uppercase; letter-spacing:.06em; color:var(--ink-soft); }
.online-content table.activity-table tr:last-child td { border-bottom:0; }
.activity-panel .act { margin:8px 0 0; }
.activity-panel .act[hidden] { display:none; }

/* The release board: one card per case, a schedule dialog above it. */
.online-content[data-page="releases"] { max-width:1180px; }
#release-status[hidden] { display:none; }
#upcoming { margin:18px 0 6px; }
#upcoming[hidden] { display:none; }
#upcoming h2,.release-case h2 { margin:0; font:700 15px/1.3 var(--sans); }
#upcoming ul { list-style:none; margin:8px 0 0; padding:0; display:grid; gap:8px; }
#upcoming li { display:flex; flex-wrap:wrap; align-items:center; gap:6px; padding:8px 11px; background:var(--card); border:2px solid var(--rule); border-radius:9px; }
#upcoming li .release-actions { margin:0 0 0 auto; }
.release-case { margin:14px 0; padding:12px 14px; background:var(--card); border:2px solid var(--outline); border-radius:10px; box-shadow:3px 3px 0 var(--shadow); }
.release-case header { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.release-case header small { flex:1 1 100%; color:var(--ink-soft); font:400 11.5px/1.4 var(--sans); }
.badge { padding:3px 8px; border:1px solid var(--rule); border-radius:999px; background:var(--card-sunk); color:var(--ink-soft); font:700 10px/1.5 var(--sans); text-transform:uppercase; letter-spacing:.07em; white-space:nowrap; }
.badge.live { color:var(--good); border-color:var(--good); }
.badge.scheduled { color:var(--gold-text); border-color:var(--gold); background:var(--gold-wash); }
.badge.superseded { color:var(--ink-soft); border-color:var(--ink-soft); }
.badge.retired,.badge.cancelled { color:var(--bad); border-color:var(--bad); }
.badge.draft { color:var(--ink-faint); }
.release-actions { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:10px 0 0; }
.release-when { font-variant-numeric:tabular-nums; white-space:nowrap; }
.release-when small { display:block; color:var(--ink-faint); font-size:10px; }
.release-changes { font-size:11.5px; color:var(--ink-soft); }
.release-case details.versions { margin:12px 0; padding-top:8px; border-top:1px solid var(--rule); }
.release-case details.versions[open] { padding-bottom:6px; border-bottom:1px solid var(--rule); }
.release-case details.versions summary { cursor:pointer; font:700 11px/1 var(--sans); text-transform:uppercase; letter-spacing:.07em; color:var(--ink-soft); }
.release-scroll { overflow-x:auto; }
.versions-slot { margin-top:8px; }
.versions-slot .hint,.release-case > .hint { margin:8px 0 0; }
.online-content table.publications,.online-content table.versions-table { margin:0; font:400 12.5px/1.35 var(--sans); background:var(--card); }
.online-content table.publications th,.online-content table.publications td,
.online-content table.versions-table th,.online-content table.versions-table td { padding:6px 8px; border-bottom:1px solid var(--rule); text-align:left; vertical-align:top; }
.online-content table.publications th,.online-content table.versions-table th { font:700 10px/1.4 var(--sans); text-transform:uppercase; letter-spacing:.06em; color:var(--ink-soft); }
table.publications .release-actions,table.versions-table .release-actions { margin:0; gap:6px; }
table.publications .act,table.versions-table .act { padding:5px 7px; font-size:10px; box-shadow:2px 2px 0 var(--shadow); }
dialog#schedule { width:min(420px,calc(100vw - 32px)); padding:16px 18px; color:var(--ink); background:var(--card); border:2px solid var(--outline); border-radius:12px; box-shadow:4px 4px 0 var(--shadow); }
dialog#schedule::backdrop { background:rgba(18,18,24,.45); }
dialog#schedule h2 { margin:0 0 4px; font:700 15px/1.25 var(--sans); }
dialog#schedule .hint { margin:0 0 10px; }
dialog#schedule label { display:flex; flex-direction:column; gap:4px; margin:10px 0; font:700 11px/1 var(--sans); text-transform:uppercase; letter-spacing:.07em; color:var(--ink-soft); }
dialog#schedule label[hidden] { display:none; }
dialog#schedule label.inline { flex-direction:row; align-items:center; text-transform:none; letter-spacing:0; color:var(--ink); font-weight:500; }
dialog#schedule input[type="datetime-local"],dialog#schedule input[type="text"] { font:500 13px/1 var(--sans); color:var(--ink); background:var(--card); border:2px solid var(--outline); border-radius:7px; padding:6px 8px; }
dialog#schedule input:disabled { color:var(--ink-faint); border-color:var(--rule); }
dialog#schedule .schedule-error { margin:6px 0 0; color:var(--bad); font:500 12px/1.35 var(--sans); }
dialog#schedule .schedule-error[hidden] { display:none; }
@media (max-width:620px) {
  /* Too narrow for eight columns: the least important ones go. */
  .online-content .col-thin { display:none; }
  .activity-search { max-width:none; }
  .release-case { padding:10px 11px; }
  #upcoming li .release-actions { margin:4px 0 0; }
  /* Too narrow for eight columns: every row becomes a labelled block. */
  .online-content table.publications,.online-content table.versions-table,
  .online-content table.publications tbody,.online-content table.versions-table tbody { display:block; }
  .online-content table.publications thead,.online-content table.versions-table thead { display:none; }
  .online-content table.publications tr,.online-content table.versions-table tr { display:block; padding:8px 0; border-bottom:1px solid var(--rule); }
  .online-content table.publications tr:last-child,.online-content table.versions-table tr:last-child { border-bottom:0; }
  .online-content table.publications td,.online-content table.versions-table td { display:block; padding:2px 0; border:0; }
  table.publications td[data-label]::before,table.versions-table td[data-label]::before {
    content:attr(data-label) " ";
    color:var(--ink-soft);
    font:700 9.5px/1.6 var(--sans);
    text-transform:uppercase;
    letter-spacing:.06em;
  }
  table.publications td .release-actions,table.versions-table td .release-actions { margin:4px 0 0; }
  .release-when,.release-when small { display:inline; }
  .release-when small { margin-left:5px; }
}

/* -- the way in to a table: the buttons and a code to type ---------------- */
.table-start { margin:14px 0 0; }
#table-start-status[hidden] { display:none; }
.table-join { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:16px 0 0; padding-top:14px; border-top:1px solid var(--rule); }
.table-join label { font:700 11px/1 var(--sans); text-transform:uppercase; letter-spacing:.07em; color:var(--ink-soft); }
.table-join input { width:9em; font:700 15px/1 var(--sans); letter-spacing:.12em; text-transform:uppercase; color:var(--ink); background:var(--card); border:2px solid var(--outline); border-radius:7px; padding:7px 9px; }
#table-open[hidden] { display:none; }
.table-open-row { display:flex; flex-wrap:wrap; align-items:center; gap:9px; padding:9px 11px; margin:8px 0 0; background:var(--card); border:2px solid var(--rule); border-radius:9px; }
.table-open-row b { flex:1 1 120px; }
.table-open-code { font-variant-numeric:tabular-nums; letter-spacing:.08em; color:var(--ink-soft); font-size:12px; }
.table-open-role,.table-open-state { color:var(--ink-soft); font-size:12px; }
.table-open-head { margin:12px 0 0; font:700 10.5px/1.3 var(--sans); text-transform:uppercase; letter-spacing:.07em; color:var(--ink-soft); }
.table-open-row.is-your-turn { border-color:var(--gold); }
.table-open-row .table-close { margin-left:auto; }
.table-pace { display:flex; flex-wrap:wrap; gap:6px; margin:0 0 6px; }
.table-pace .act.is-on { color:var(--ground); background:var(--ink); border-color:var(--ink); }
.table-pace-note { margin:0 0 10px; }

/* -- shared by every table: the invite link, the dot, the toasts --------- */
.table-share { display:inline-flex; flex-wrap:wrap; gap:6px; }
.table-share[hidden],.witness-share[hidden],.inv-share[hidden] { display:none; }
.turn-dot { display:inline-flex; align-items:center; gap:5px; font:700 11px/1.3 var(--sans); color:var(--ink); text-decoration:none; }
.turn-dot::before { content:""; width:9px; height:9px; border-radius:50%; background:var(--gold); box-shadow:0 0 0 2px var(--gold-wash); }
.case .turn-dot { margin:6px 10px 8px; }
.table-toasts { position:fixed; left:50%; bottom:14px; z-index:60; display:grid; gap:6px; width:min(92vw, 420px); transform:translateX(-50%); pointer-events:none; }
.table-toast { margin:0; padding:9px 12px; background:var(--ink); color:var(--ground); border-radius:9px; box-shadow:3px 3px 0 var(--shadow); font:600 13px/1.35 var(--sans); transition:opacity .5s ease; }
.table-toast.is-leaving { opacity:0; }

/* A table opened for two, while the second seat is empty: the code and the
   link at the top of the rail (of the sheet, on a phone). The mode panel's
   own "a partner joins with the code" line would say it twice meanwhile. */
.table-waiting { display:flex; flex-wrap:wrap; align-items:center; gap:8px 12px; margin:0; padding:12px 14px; background:var(--card); border:2px solid var(--outline); border-radius:12px; box-shadow:3px 3px 0 var(--act); }
.table-waiting-line { flex:1 1 100%; margin:0; font:700 14px/1.35 var(--sans); color:var(--ink); }
.table-waiting-code { display:inline-flex; align-items:baseline; gap:8px; margin:0; font:600 13px/1 var(--sans); color:var(--ink-soft); }
.table-waiting-code b { font:800 22px/1 var(--sans); letter-spacing:.12em; font-variant-numeric:tabular-nums; color:var(--ink); }
.table-waiting .act { min-height:34px; padding:6px 12px; border-radius:10px; font:700 13.5px/1.2 var(--sans); text-transform:none; letter-spacing:0; box-shadow:2px 2px 0 var(--shadow); }
.table-waiting .table-notify-box { flex:1 1 100%; }
.table-inviting .inv-code, .table-inviting .inv-share { display:none; }

/* The notification switch: a bell and two words, pressed while it is on;
   or one muted line when the browser has blocked them. */
.table-notify-box { margin:0; }
.table-notify { display:inline-flex; align-items:center; gap:6px; margin:0; padding:3px 2px; background:none; border:0; border-radius:6px; color:var(--ink-faint); font:700 13px/1.2 var(--sans); cursor:pointer; }
.table-notify .icon { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.table-notify:hover, .table-notify[aria-pressed="true"] { color:var(--ink); }
.table-notify[aria-pressed="true"] .icon { fill:var(--act); }
.table-notify:focus-visible { outline:2px solid var(--focus); outline-offset:2px; }
.table-notify-note { margin:0; font:500 12.5px/1.4 var(--sans); color:var(--ink-faint); }
.table-notify[hidden], .table-notify-note[hidden] { display:none; }

/* -- The Investigation: the panel the mode mounts in #mode-panel ----------
   On a wide screen the panel is the rail: it comes first, above the cast
   (the cards' words arrive in the panel's own evidence list, not on cards).
   On a phone it is the first tab of the clue sheet, under the plan. */
.inv-status { margin:0; padding:8px 11px; border-radius:9px; background:var(--card); border:1.5px solid var(--rule); font:600 13px/1.4 var(--sans); }
.inv-status.error { background:var(--bad-wash); color:var(--bad-ink); border-color:var(--bad-ink); }
.inv-status[hidden] { display:none; }
.investigation-table #timer-box,
.investigation-table #timer,
.investigation-table .rail .focus,
.investigation-table .rail .general { display:none; }
.investigation-table [data-photo-next] { display:none; }
/* Four tabs that always fit: they share the row, and wrap onto a second
   one before a label is ever cut off (330 px rail, French, a phone). */
.inv-tabs { display:flex; flex-wrap:wrap; gap:5px; margin:0 0 7px; }
.mode-panel .inv-tabs .act { flex:1 1 auto; min-width:0; justify-self:stretch; padding:7px 6px; display:inline-flex; align-items:center; justify-content:center; gap:5px; }
.inv-tabs .act.is-on { color:var(--ground); background:var(--ink); border-color:var(--ink); }
.inv-tab-name { white-space:nowrap; }
.inv-badge { display:inline-grid; place-items:center; min-width:18px; height:18px; padding:0 5px; border-radius:999px; background:var(--crime); color:var(--card); font:800 11px/1 var(--sans); font-variant-numeric:tabular-nums; }
.inv-badge[hidden] { display:none; }
.inv-work > [hidden] { display:none; }
.inv-help .inv-hint { margin:0; }
.inv-box { margin:0; padding:10px 12px; background:var(--card); border:2px solid var(--outline); border-radius:12px; }
.inv-box button.act[disabled] { opacity:.55; }
.inv-head { margin:0 0 7px; font:800 13px/1.3 var(--sans); color:var(--ink-soft); }
.inv-hint { margin:7px 0 0; color:var(--ink-soft); font:500 12.5px/1.45 var(--sans); }

/* The clock: one number the size of the decision it drives. */
.inv-readout { display:flex; align-items:baseline; gap:6px; margin:0; }
.inv-left { font:700 34px/1 var(--font-title); font-variant-numeric:tabular-nums; color:var(--ink); }
.inv-budget { font:600 12.5px/1.3 var(--sans); color:var(--ink-soft); }
.inv-bar { height:9px; margin:8px 0 6px; overflow:hidden; background:var(--card-sunk); border:1.5px solid var(--outline); border-radius:999px; }
.inv-bar-fill { display:block; height:100%; width:100%; background:var(--good); transition:width .3s ease; }
.inv-spent { margin:0; color:var(--ink-soft); font:600 12px/1.3 var(--sans); font-variant-numeric:tabular-nums; }
.inv-clock.is-warn .inv-bar-fill { background:var(--gold); }
.inv-clock.is-warn .inv-left { color:var(--gold-text); }
.inv-clock.is-danger .inv-bar-fill,.inv-clock.is-lost .inv-bar-fill { background:var(--bad); }
.inv-clock.is-danger .inv-left,.inv-clock.is-lost .inv-left { color:var(--bad); }
.inv-clock.is-lost,.inv-clock.is-out { border-color:var(--bad); }
.inv-clock.is-out .inv-spent { color:var(--bad-ink); font-weight:700; }

/* Both investigators: in the panel as a list, on the plan as a token. */
.inv-players { list-style:none; margin:0; padding:0; display:grid; gap:6px; }
.inv-player { display:flex; flex-wrap:wrap; align-items:center; gap:6px; font:500 13px/1.3 var(--sans); }
.inv-player b { font-weight:700; }
.inv-where { color:var(--ink-soft); font-size:12px; font-variant-numeric:tabular-nums; }
.inv-presence { padding:1px 8px; border:1.5px solid var(--rule); border-radius:999px; color:var(--ink-faint); font:700 11px/1.5 var(--sans); }
.inv-presence.is-here { color:var(--good); border-color:var(--good); }
.inv-code { margin:7px 0 0; font:600 12px/1.4 var(--sans); color:var(--ink-soft); }
.inv-code[hidden] { display:none; }
/* What a tap on the plan does: one segmented control, one segment chosen. */
.inv-modes { display:flex; margin:9px 0 0; border:2px solid var(--outline); border-radius:10px; overflow:hidden; box-shadow:2px 2px 0 var(--shadow); }
.mode-panel .inv-modes .act { flex:1 1 0; min-width:0; justify-self:stretch; margin:0; border:0; border-radius:0; box-shadow:none; padding:7px 6px; }
.mode-panel .inv-modes .act + .act { border-left:2px solid var(--outline); }
.mode-panel .inv-modes .act:hover { transform:none; }
.inv-modes .act.is-on { color:var(--on-act); background:var(--act); }
.inv-modes .act.is-on:hover { cursor:default; }
.inv-token {
  position:absolute; z-index:6; top:2px; left:2px;
  display:flex; align-items:center; justify-content:center;
  width:42%; height:42%; min-width:13px; min-height:13px;
  border-radius:50%; pointer-events:none;
  color:var(--ground); background:var(--ink); border:1.5px solid var(--card);
  font:800 clamp(8px, calc(var(--cell, 40px) * 0.18), 12px)/1 var(--sans);
  box-shadow:1.5px 1.5px 0 var(--shadow);
}
.inv-token.is-you { color:var(--on-act); background:var(--act); border-color:var(--outline); }
.inv-token.is-inline { position:static; width:18px; height:18px; min-width:18px; min-height:18px; font-size:9.5px; }
/* The plan as the investigators know it: the crime scene washed red, the
   body on its square, and every room somebody has searched hatched. */
.inv-mark { position:absolute; inset:0; z-index:1; pointer-events:none; }
.inv-mark.is-scene,.inv-swatch.is-scene { background-color:color-mix(in srgb, var(--crime) 16%, transparent); }
.inv-mark.is-searched,.inv-swatch.is-searched { background-image:repeating-linear-gradient(45deg, color-mix(in srgb, var(--ink) 26%, transparent) 0 1.5px, transparent 1.5px 7px); }
.inv-body {
  position:absolute; inset:10%; z-index:4; pointer-events:none; border-radius:50%;
  background:var(--surface-2); border:2px solid var(--crime); box-shadow:0 0 0 1.5px var(--outline);
}
.inv-body .face { display:block; width:100%; height:100%; border-radius:50%; filter:grayscale(1); opacity:.75; }
.inv-body-tag {
  position:absolute; right:-6%; bottom:-6%; display:grid; place-items:center;
  width:42%; height:42%; border-radius:50%; background:var(--crime); color:var(--card);
  border:1.5px solid var(--outline); font:800 clamp(7px, calc(var(--cell, 40px) * 0.16), 12px)/1 var(--sans);
}
.inv-legend { display:flex; flex-wrap:wrap; justify-content:center; gap:6px 16px; margin:8px 0 0; font:600 12px/1.3 var(--sans); color:var(--ink-soft); }
.inv-legend[hidden] { display:none; }
.inv-key { display:inline-flex; align-items:center; gap:6px; }
.inv-swatch { display:inline-block; width:16px; height:16px; border:1.5px solid var(--outline); border-radius:4px; background-color:var(--surface); }
body.inv-picking #board .cell { cursor:crosshair; }
.cell.inv-pinged { animation:inv-ping 1.4s ease-out 1; }
@keyframes inv-ping {
  0%,100% { box-shadow:inset 0 0 0 0 var(--act); }
  20%,60% { box-shadow:inset 0 0 0 4px var(--act); }
}

/* Interviewing and searching: a cost on every button, and a mark on what
   has been asked or turned over once already. */
.inv-label { display:flex; flex-direction:column; gap:4px; font:700 12.5px/1.2 var(--sans); color:var(--ink-soft); }
.inv-select { font:500 14px/1.2 var(--sans); color:var(--ink); background:var(--card); border:2px solid var(--outline); border-radius:9px; padding:7px 9px; }
.inv-questions { display:grid; gap:6px; margin:9px 0 0; }
.mode-panel .inv-questions .act { justify-self:stretch; text-align:left; }
.inv-question.is-asked { color:var(--ink-soft); border-style:dashed; }
/* The answers of the person picked, right under the questions asked. */
.inv-answers { list-style:none; margin:9px 0 0; padding:0; display:grid; gap:6px; }
.inv-answers[hidden] { display:none; }
.inv-answer { display:grid; gap:2px; padding:7px 9px; background:var(--card-sunk); border:1.5px solid var(--rule); border-radius:9px; }
.inv-answer.is-new { border-color:var(--outline); box-shadow:2px 2px 0 var(--shadow); }
.inv-answer.is-false { border-color:var(--bad); background:var(--bad-wash); }
.inv-answer-q { font:700 11.5px/1.3 var(--sans); color:var(--ink-soft); }
.inv-answer-text { font:500 13.5px/1.4 var(--sans); color:var(--ink); }
.inv-answer-note { font:600 12px/1.35 var(--sans); color:var(--ink-soft); }
/* A quiet nudge: two claims to one room, and the question that settles it. */
.inv-nudge { display:block; margin:5px 0 0; padding:2px 0 2px 8px; border-left:3px solid var(--gold); font:italic 500 12px/1.4 var(--sans); color:var(--ink-soft); }
.inv-found { list-style:none; margin:8px 0 0; padding:0; display:grid; gap:4px; }
.inv-found[hidden] { display:none; }
.inv-found-line { padding:6px 9px; background:var(--card-sunk); border:1.5px dashed var(--rule); border-radius:9px; font:500 13px/1.4 var(--sans); }
.inv-rooms { list-style:none; margin:0; padding:0; display:grid; gap:6px; }
.inv-room { display:flex; align-items:center; gap:8px; }
/* Only the room you stand in is offered: .inv-room declares a display. */
.inv-room[hidden] { display:none; }
.inv-room-name { flex:1 1 auto; font:600 13px/1.3 var(--sans); }
.inv-room.is-here .inv-room-name { color:var(--ink); }
.inv-room.is-searched .inv-room-name { color:var(--ink-faint); text-decoration:line-through; }

/* Every statement gathered, and the two minutes it takes to break one. */
.inv-cards { list-style:none; margin:0; padding:0; display:grid; gap:7px; max-height:320px; overflow-y:auto; }
.inv-card { position:relative; padding:9px 11px; background:var(--card-sunk); border:1.5px solid var(--rule); border-radius:10px; }
.inv-card.is-true { border-color:var(--good); }
.inv-card.is-false { border-color:var(--bad); background:var(--bad-wash); }
.inv-card-source { margin:0 0 3px; font:700 12px/1.4 var(--sans); color:var(--ink-soft); }
.inv-card-text { margin:0 0 6px; font:500 13.5px/1.45 var(--sans); color:var(--ink); }
.inv-card-note { margin:5px 0 0; font:600 12px/1.4 var(--sans); color:var(--ink-soft); }
.inv-card.is-false .inv-card-note { color:var(--bad-ink); }
.inv-card.is-fact { border-style:dashed; }
.inv-lie { position:absolute; top:6px; right:8px; padding:1px 8px; border-radius:999px; background:var(--bad); color:var(--card); font:800 11px/1.5 var(--sans); }

/* The accusation, the score it leaves behind, and the truth when there is
   no ending card to carry it. */
.inv-accuse .act.primary { width:100%; }
.inv-accuse.is-now { border-color:var(--bad); box-shadow:3px 3px 0 var(--shadow); }
.inv-accuse.is-now .inv-hint { color:var(--bad-ink); font-weight:600; }
.inv-card.is-scene { border-color:var(--crime); border-style:solid; background:color-mix(in srgb, var(--crime) 8%, var(--card-sunk)); }
.inv-closing[hidden] { display:none; }
.inv-score { display:flex; flex-wrap:wrap; gap:8px; margin:10px 0 0; }
.inv-tile { flex:1 1 84px; padding:8px 10px; background:var(--card-sunk); border:1.5px solid var(--rule); border-radius:10px; }
.inv-tile b { display:block; font:700 22px/1.1 var(--font-title); font-variant-numeric:tabular-nums; }
.inv-tile span { display:block; margin-top:2px; color:var(--ink-soft); font:700 12px/1.3 var(--sans); }
.inv-cover { flex:1 1 100%; margin:4px 0 0; font:600 13px/1.45 var(--sans); color:var(--ink); }
.inv-truth { margin:10px 0 0; padding:9px 11px; background:var(--card-sunk); border:1.5px solid var(--rule); border-radius:10px; }
.inv-truth-who { margin:0 0 4px; font:700 13.5px/1.4 var(--sans); }
.inv-truth-list { list-style:none; margin:7px 0 0; padding:0; display:grid; gap:3px; font:500 12.5px/1.4 var(--sans); color:var(--ink-soft); }
#ending-online .inv-cover { margin:10px 0 0; }
#ending-online .inv-score { justify-content:center; }

/* The log, newest first: what the two of you have spent the clock on. */
.inv-log-list { list-style:none; margin:0; padding:0; display:grid; gap:4px; max-height:220px; overflow-y:auto; font:500 12.5px/1.4 var(--sans); color:var(--ink-soft); }
.inv-log-line { padding:3px 0; border-bottom:1px dotted var(--rule); }
.inv-log-line:last-child { border-bottom:0; }
.inv-log-list .inv-lie-exposed { color:var(--bad); font-weight:700; }
.inv-log-list .inv-clock-out { color:var(--bad); font-weight:700; }
@media (prefers-reduced-motion: reduce) {
  .inv-bar-fill { transition:none; }
  .cell.inv-pinged { animation:none; outline:3px solid var(--act); outline-offset:-3px; }
}

/* -- The Witness ---------------------------------------------------------
   One page, two seats, and almost nothing in common between them: the
   detective reads a meter and a partner's presence, the witness reads a menu
   of everything they are allowed to say. Both sets of controls live in the
   board's own ``#mode-panel``, so these rules are loaded with the board. */
.witness-box { display:grid; gap:6px; align-content:start; padding:10px 12px; background:var(--card); border:2px solid var(--outline); border-radius:12px; }
.witness-box[hidden] { display:none; }
.witness-table #timer-box, .witness-table #timer { display:none; }
.witness-box > h3.witness-head { margin:0; font:800 13px/1.3 var(--sans); color:var(--ink-soft); }
.witness-box p { margin:0; font:500 13.5px/1.45 var(--sans); color:var(--ink); }
.witness-box p.hint { color:var(--ink-soft); font-size:12.5px; }
.witness-box p[hidden] { display:none; }
.mode-panel .act[hidden] { display:none; }
.mode-panel .act { justify-self:start; }
.witness-role { font-weight:800 !important; }
.witness-code { font:800 18px/1.2 var(--sans); letter-spacing:.18em; font-variant-numeric:tabular-nums; }
.witness-meter { font-variant-numeric:tabular-nums; }
.witness-meter.is-ready { color:var(--good); font-weight:800 !important; }
.witness-cost { color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.witness-final { font-variant-numeric:tabular-nums; font-weight:700 !important; }
.witness-under { color:var(--good); font-weight:700 !important; }
.witness-over { color:var(--gold-text); font-weight:700 !important; }
.witness-penalty { color:var(--gold-text); font-variant-numeric:tabular-nums; }

/* The picker: everything true about one person, cheapest first, each item
   carrying what it costs and how many placements it would leave standing. */
.witness-select { width:100%; font:500 14px/1.2 var(--sans); color:var(--ink); background:var(--card); border:2px solid var(--outline); border-radius:9px; padding:7px 9px; }
.witness-filter { margin-top:2px; }
.witness-menu { max-height:260px; overflow-y:auto; display:grid; gap:4px; }
.witness-group { margin:4px 0 0 !important; font:800 12px/1.4 var(--sans) !important; color:var(--ink-faint, var(--ink-soft)) !important; }
.witness-options { list-style:none; margin:0; padding:0; display:grid; gap:4px; }
.witness-option { display:flex; flex-wrap:wrap; align-items:baseline; gap:6px; width:100%; padding:6px 8px; text-align:left; font:500 13px/1.4 var(--sans); color:var(--ink); background:var(--card-sunk); border:1.5px solid var(--rule); border-radius:8px; cursor:pointer; }
.witness-option:hover:not(:disabled) { border-color:var(--ink); }
.witness-option:disabled,.witness-option.is-said { color:var(--ink-soft); cursor:default; text-decoration:line-through; opacity:.65; }
.witness-text { flex:1 1 130px; }
.witness-price { padding:1px 7px; border:1.5px solid var(--outline); border-radius:999px; background:var(--card); font:800 11px/1.5 var(--sans); font-variant-numeric:tabular-nums; }
.witness-leaves { color:var(--ink-soft); font:600 11px/1.5 var(--sans); font-variant-numeric:tabular-nums; }
/* A count that stopped at its ceiling rather than arrived: said plainly,
   so it is not read as a number to compare against the others. */
.witness-leaves.is-open { color:var(--ink-faint, var(--ink-soft)); font-style:italic; }
.witness-said { list-style:decimal inside; margin:0; padding:0; display:grid; gap:3px; font:500 13px/1.4 var(--sans); }
.witness-said li { display:flex; align-items:baseline; gap:6px; }
.witness-said .witness-text { flex:1 1 auto; }
/* A struck statement stays said and paid for: crossed out, on both boards
   (the cards' own rule is the board's, in style.css). */
.witness-said li.is-struck .witness-text { text-decoration:line-through; opacity:.55; }
.witness-said li { flex-wrap:wrap; }
.witness-said-who { display:inline-flex; align-items:center; gap:5px; flex:0 0 auto; }
.witness-said-who b { font-weight:800; }
/* A face, wherever the panel names somebody. */
.witness-face { display:inline-block; flex:none; width:22px; height:22px; overflow:hidden; border-radius:50%; background:var(--surface-2); border:1.5px solid var(--outline); vertical-align:middle; }
.witness-face .face { display:block; width:100%; height:100%; }
/* Who to talk about, by face: the strip above the list. */
.witness-faces { display:flex; flex-wrap:wrap; gap:6px; }
.witness-face-pick { display:flex; flex-direction:column; align-items:center; gap:2px; width:52px; padding:3px 2px; color:var(--ink); background:none; border:1.5px solid transparent; border-radius:9px; cursor:pointer; font:600 11px/1.2 var(--sans); }
.witness-face-pick .witness-face { width:34px; height:34px; }
.witness-face-pick[aria-pressed="true"] { border-color:var(--outline); background:var(--card-sunk); }
.witness-face-pick[aria-pressed="true"] .witness-face { box-shadow:0 0 0 2.5px var(--act); }
.witness-face-name { max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.witness-locked #board .cell.occupied { cursor:pointer; }
.witness-locked #board .cell.witness-subject { box-shadow:inset 0 0 0 3px var(--act); }
/* The two the case turns on, on the witness's plan only. */
.cell.truth-victim .occupant .token-face { box-shadow:0 0 0 1.5px var(--outline), 0 0 0 max(3px, calc(var(--cell) * 0.07)) var(--crime); }
.truth-tag { position:absolute; left:50%; bottom:-3px; z-index:7; transform:translateX(-50%); padding:0 4px; pointer-events:none; white-space:nowrap; font:800 clamp(7px, calc(var(--cell) * 0.16), 10px)/1.35 var(--sans); color:var(--ink); background:var(--surface); border:1.5px solid var(--outline); border-radius:5px; }
.truth-tag.is-victim { color:var(--crime-text); border-color:var(--crime); }
/* A card from the witness, said where the detective is looking. */
.table-toast.witness-card-toast { display:flex; align-items:center; gap:8px; }
.witness-card-toast .witness-face { width:28px; height:28px; border-color:var(--ground); }
.witness-turn { font-weight:800 !important; }
.witness-turn.is-mine { color:var(--good); }
.witness-turn[hidden],.witness-pace[hidden] { display:none; }
.witness-pace { font:700 12.5px/1.3 var(--sans); color:var(--ink-soft); }
.witness-share { display:flex; }
.witness-offer { font-weight:700 !important; }
.witness-next { display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
/* The detective's signals: free, one every five seconds. */
.witness-signal-row { display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.witness-signal-row .witness-select { width:auto; flex:1 1 120px; }
.witness-signals { list-style:none; margin:4px 0 0; padding:0; display:grid; gap:3px; max-height:132px; overflow:auto; font:600 12.5px/1.4 var(--sans); }
.witness-signals[hidden] { display:none; }
.witness-signal { padding:4px 8px; background:var(--card-sunk); border:1.5px solid var(--rule); border-radius:8px; }
.witness-signal.is-new { animation:witness-signal 2s ease-out 1; }
@keyframes witness-signal {
  0%,50% { border-color:var(--gold); background:var(--gold-wash); }
  100% { border-color:var(--rule); background:var(--card-sunk); }
}

/* Both partners see the same face for the same person. */
.witness-table [data-photo-next] { display:none; }

/* The witness's plan is a photograph, not a notebook: everybody is already
   where they stood, and nothing on it may be moved. The bar of people and
   tools goes with the pencil. */
.witness-locked .bar,
.witness-locked .rail .focus,
.witness-locked #accusation,
.witness-locked .done-toggle,
.witness-locked .line-strike,
.witness-locked .focus-actions { display:none !important; }
.witness-locked #board .cell { cursor:default; }
.witness-locked #plan { outline:2px dashed var(--rule); outline-offset:5px; }
.witness-pinging #board .cell { cursor:crosshair; }

/* The detective's board, laid over the witness's own as the faintest thing
   on it: an initial where they put somebody, a count where they pencilled. */
.witness-ghost { position:absolute; right:3px; bottom:2px; z-index:6; pointer-events:none; font:800 11px/1 var(--sans); color:var(--ink-soft); opacity:.75; }
.witness-ghost.witness-notes { right:auto; left:3px; font-weight:600; opacity:.6; }

/* A ping says nothing; it only points. Two seconds, and gone. */
.cell.ping-flash { animation:witness-ping 2s ease-out 1; }
@keyframes witness-ping {
  0%,60% { box-shadow:inset 0 0 0 3px var(--act), inset 0 0 0 5px var(--outline); }
  100% { box-shadow:inset 0 0 0 3px transparent; }
}
@media (prefers-reduced-motion:reduce) {
  .cell.ping-flash { animation:none; box-shadow:inset 0 0 0 3px var(--act); }
}
@media (min-width:960px) {
  /* On a wide page the witness's panel is the game: a wider rail, and a menu
     as tall as the rail once it is scrolled to, with a scroll of its own. */
  .app.witness-seat { --rail-w: 400px; }
  .witness-seat .witness-menu { max-height:max(260px, calc(100dvh - var(--topbar-h, 64px) - 250px)); }
}
@media (max-width:959px) {
  /* The log and the pointer stay: the witness takes a card back and points
     at the plan from a phone too. They are kept short instead. */
  .witness-locked .witness-said { max-height:132px; overflow:auto; }
  .witness-locked .witness-menu { max-height:240px; }
  .witness-faces { flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; }
  .table-join input { width:100%; }
}
@media (prefers-reduced-motion:reduce) {
  .witness-signal.is-new { animation:none; border-color:var(--gold); }
  .table-toast { transition:none; }
}

/* -- The door that needs an account ------------------------------------- */
.online-content h1 { margin:0 0 12px; font:700 26px/1.2 var(--font-title); letter-spacing:-0.01em; color:var(--ink); }
.signin { max-width:560px; margin-top:48px; }
.signin-card { padding:22px 22px 18px; background:var(--card); border:2px solid var(--outline); border-radius:12px; box-shadow:4px 4px 0 var(--shadow); }
.signin-card p { margin:0 0 12px; font:500 15px/1.5 var(--sans); color:var(--ink); }
.signin-card .hint { font-size:13px; color:var(--ink-soft); }
.signin-card .signin-kicker { margin:0 0 4px; font:800 11px/1.3 var(--sans); text-transform:uppercase; letter-spacing:.09em; color:var(--gold-text); }
.signin-card .signin-case { margin:0 0 6px; font:700 17px/1.3 var(--sans); }
.signin-card .signin-lead { margin:0 0 18px; padding-bottom:16px; border-bottom:1px solid var(--rule); color:var(--ink-soft); }
/* -- Who may play: the administrator's approval list -------------------- */
.online-content[data-page="players"] { max-width:1180px; }
.players-list { margin:0 0 18px; }
.online-content table.players-table code { font:600 11.5px/1 ui-monospace, monospace; }
.players-add input { width:24em; max-width:100%; font:500 13px/1.2 ui-monospace, monospace; letter-spacing:0; text-transform:none; }
.online-status.access-note { font:500 13px/1.4 var(--sans); color:var(--ink-soft); }
