/* Oddball as election night: candidates on posters, a ballot you write a name on, and the count.
   Poster blue carries the screen, white is ballot paper, black is ink, red is only ever the pen. */

:root {
  --blue: #123a8c;        /* the shell: poster blue */
  --blue-deep: #0c2a6b;   /* bars, fields */
  --blue-ink: #0a2259;
  --blue-soft: #c9d6f2;   /* secondary text on blue */
  --blue-line: rgba(255, 255, 255, .22);
  --paper: #ffffff;       /* ballot paper */
  --ink: #0d0d0d;
  --ink-soft: #4b5468;    /* secondary text on paper */
  --rule: #0d0d0d;
  --red: #e63b2e;         /* the pen: your mark, and the oddball */
  --red-deep: #b8261b;

  --font: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --hand: "Caveat", "Segoe Print", cursive;
  --r: 6px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; background: var(--blue); color: #fff; }
body {
  font: 400 17px/1.45 var(--font); font-stretch: 100%;
  min-height: 100dvh; overscroll-behavior-y: none; -webkit-font-smoothing: antialiased;
  caret-color: var(--red);
}
::selection { background: var(--red); color: #fff; }
main { max-width: 540px; margin: 0 auto; padding: 0 16px calc(150px + var(--safe-bottom)); overflow-x: clip; }
h1, h2, h3, p { margin: 0; }
h1, h2 { text-wrap: balance; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }
.paper :focus-visible, .ballot :focus-visible { outline-color: var(--red); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.num { font-variant-numeric: tabular-nums; }

/* ---------- display type: expanded, heavy, like a poster ---------- */

.display { font-weight: 900; font-stretch: 125%; letter-spacing: -.02em; line-height: 1.02; }

/* ---------- candidate posters: every player has one ---------- */

.face {
  position: relative; flex: none; overflow: hidden; border-radius: var(--r);
  background: var(--blue-ink); color: #fff; display: grid; place-items: center;
  font-weight: 900; font-stretch: 125%; letter-spacing: -.02em;
}
.face img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.face.xs { width: 32px; height: 32px; font-size: 12px; border-radius: 4px; }
.face.s { width: 40px; height: 40px; font-size: 14px; }
.face.m { width: 56px; height: 56px; font-size: 18px; }
.face.l { width: 88px; height: 88px; font-size: 28px; }
.face.off { opacity: .45; }
.face.mine { box-shadow: 0 0 0 2px var(--blue), 0 0 0 4px #fff; }
.face.odd { box-shadow: 0 0 0 2px var(--blue), 0 0 0 4px var(--red); }

.poster {
  display: grid; grid-template-rows: auto auto; border: 0; padding: 0; text-align: left;
  background: var(--paper); color: var(--ink); border-radius: var(--r); overflow: hidden;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .25);
  transition: transform .14s cubic-bezier(.2, .8, .2, 1), box-shadow .14s;
}
.poster .face { width: 100%; height: auto; aspect-ratio: 1; border-radius: 0; font-size: 44px; }
/* no photo: the name itself is the poster, set big in poster lettering */
.poster .face.text { place-items: end start; padding: 10px; background: var(--blue-ink); container-type: inline-size; }
.poster .face.text .pname { font-weight: 900; font-stretch: 125%; letter-spacing: -.03em; line-height: .92; text-align: left;
  /* sized from the tile width and the grid's longest name, so every name fits on one line, whole */
  font-size: min(44px, calc((100cqi - 4px) / (var(--len) * .74))); white-space: nowrap; }
.poster { position: relative; grid-template-rows: 1fr auto; }
.poster .face.text { height: 100%; }
.poster .label { position: absolute; top: 8px; left: 8px; background: var(--paper); color: var(--ink-soft); font-size: 12px; font-weight: 800; padding: 2px 7px; border-radius: 3px; }
.poster[aria-pressed="true"] .label { color: var(--red-deep); } /* small red text uses the deeper red for contrast */
.poster .band { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-top: 2px solid var(--rule); }
.poster .band .name { font-weight: 800; font-size: 17px; line-height: 1.15; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.poster .band .note { font-size: 13px; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
.poster[aria-pressed="true"] { transform: translateY(-3px); box-shadow: 0 0 0 4px var(--red), 0 10px 20px rgba(0, 0, 0, .4); }
.poster[aria-pressed="true"] .band .note { color: var(--red-deep); }
.posters { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.posters.three { grid-template-columns: repeat(3, 1fr); gap: 8px; }
.posters.three .band .note { font-size: 11px; }
.game .posters .face { aspect-ratio: 5 / 4; }

/* ---------- buttons, fields ---------- */

.btn {
  display: block; width: 100%; min-height: 56px; padding: 14px 20px;
  border: 0; border-radius: var(--r); background: var(--paper); color: var(--ink);
  font-weight: 800; font-size: 18px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .25);
  transition: transform .06s, background .12s;
}
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { background: var(--blue-deep); color: var(--blue-soft); box-shadow: none; cursor: default; }
.btn.plain { background: transparent; color: #fff; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .7); }
.btn.small { width: auto; min-height: 44px; padding: 0 18px; font-size: 16px; }
.link { border: 0; background: none; padding: 12px 0; min-height: 48px; color: var(--blue-soft); font-weight: 600; text-decoration: underline; text-underline-offset: 4px; }

.field {
  display: block; width: 100%; min-height: 56px; padding: 14px 16px;
  background: var(--paper); color: var(--ink); border: 2px solid var(--paper); border-radius: var(--r);
  font-size: 18px; font-weight: 600; outline: none;
}
.field::placeholder { color: #6b7385; font-weight: 400; }
.field:focus { border-color: var(--red); }
.field.code { text-transform: uppercase; letter-spacing: .2em; font-weight: 900; font-stretch: 125%; }
.field.code::placeholder { letter-spacing: normal; text-transform: none; font-stretch: 100%; }
.label { display: block; font-weight: 600; color: var(--blue-soft); margin-bottom: 8px; font-size: 15px; }
.hint { font-size: 15px; color: var(--blue-soft); }
.row { display: flex; gap: 10px; align-items: center; }

.choice { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; border: 2px solid #fff; border-radius: var(--r); overflow: hidden; }
.choice button { border: 0; background: none; min-height: 46px; font-weight: 800; color: #fff; }
.choice button + button { border-left: 2px solid #fff; }
.choice button[aria-pressed="true"] { background: #fff; color: var(--ink); }
.choice button:disabled:not([aria-pressed="true"]) { color: var(--blue-soft); cursor: default; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { border: 2px solid rgba(255, 255, 255, .6); background: none; border-radius: var(--r); min-height: 44px; padding: 0 14px; font-weight: 700; }
.chip[aria-pressed="true"] { background: #fff; color: var(--ink); border-color: #fff; }
.chip:disabled { cursor: default; }

.stepper { display: flex; align-items: center; gap: 14px; }
.stepper button { width: 48px; height: 48px; border-radius: var(--r); border: 2px solid #fff; background: none; font-size: 24px; font-weight: 800; }
.stepper .value { font-weight: 900; font-stretch: 125%; font-size: 26px; min-width: 2.4em; text-align: center; }

/* ---------- home ---------- */

.home { padding-top: max(9vh, 32px); display: grid; gap: 14px; }
.wordmark { font-size: clamp(54px, 17vw, 84px); }
.lede { font-size: 19px; color: var(--blue-soft); margin: 6px 0 14px; max-width: 28ch; }
.photo-pick { display: flex; align-items: center; gap: 14px; border: 0; background: none; padding: 4px 0; text-align: left; }
.photo-pick .face { border: 2px dashed rgba(255, 255, 255, .7); background: transparent; }
.icon { width: 22px; height: 22px; }
.stepper button { display: grid; place-items: center; }
.photo-pick .face.has { border: 0; }
.photo-pick b { display: block; font-weight: 800; }
.photo-pick small { display: block; color: var(--blue-soft); font-size: 14px; }
.join { margin-top: 14px; padding-top: 22px; border-top: 1px solid var(--blue-line); }
.join .row .field { flex: 1; min-width: 0; }
.join .row .btn { width: auto; flex: none; padding: 0 24px; }

/* ---------- lobby ---------- */

.lobby { padding-top: 26px; }
.code-block { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.code-block .code { font-size: 48px; letter-spacing: .06em; }
.code-help { color: var(--blue-soft); margin: 4px 0 22px; }
.group { padding: 22px 0; border-top: 1px solid var(--blue-line); }
.group h2 { font-size: 19px; font-weight: 800; margin-bottom: 14px; }
.group .explain { margin-top: 10px; }
.roster { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 12px; }
.roster .poster { box-shadow: none; }
.roster .poster .face { font-size: 30px; }
.roster .band { padding: 8px 10px; }
.roster .band .name { font-size: 15px; }
.lobby-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; margin-top: 16px; }

/* ---------- top bar: scores always visible ---------- */

.topbar {
  position: sticky; top: 0; z-index: 10;
  margin: 0 -16px; padding: calc(10px + env(safe-area-inset-top, 0px)) 16px 12px;
  background: var(--blue-deep); box-shadow: 0 4px 12px rgba(0, 0, 0, .35);
}
.topbar-line { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; font-size: 15px; color: var(--blue-soft); }
.topbar-line strong { color: #fff; font-weight: 800; }
.menu-btn { border: 0; background: none; color: #fff; font-weight: 600; min-height: 36px; padding: 0 2px; text-decoration: underline; text-underline-offset: 4px; }
.scores { display: flex; gap: 14px; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 4px 16px; }
.scores::-webkit-scrollbar { display: none; }
/* a fade at the right edge says the strip scrolls when there are more players than fit */
.scores { mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); }
.score { flex: none; display: flex; align-items: center; gap: 8px; }
.score .pts { font-weight: 900; font-stretch: 125%; font-size: 20px; }
/* hollow until done: looked at the secret, or voted */
.score .mark { width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--blue-soft); }
.score.done .mark { background: #fff; border-color: #fff; }

/* ---------- game ---------- */

.status { margin: 22px 0 16px; }
.status h2 { font-size: 28px; }
.status p { color: var(--blue-soft); margin-top: 8px; }

/* the secret: a folded ballot, opened only while you hold it */
.secret {
  position: relative; border-radius: var(--r); background: var(--paper); color: var(--ink);
  height: 220px; margin-bottom: 18px; overflow: hidden; display: grid; place-items: center; text-align: center;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; touch-action: none;
}
.secret .open-face { padding: 24px; display: grid; gap: 10px; justify-items: center; }
.secret .word { font-size: clamp(32px, 10vw, 46px); overflow-wrap: anywhere; }
.secret .photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.secret .spy { font-size: 40px; color: var(--red); }
.secret .sub { color: var(--ink-soft); font-weight: 600; max-width: 26ch; }
.secret .cover {
  position: absolute; inset: 0; display: grid; align-content: center; justify-items: center; gap: 12px; padding: 18px 20px;
  background: var(--paper); color: var(--ink); cursor: pointer;
}
/* the outside of a folded ballot: a printed header and an empty write-in box */
.secret .slip-head { justify-self: stretch; display: flex; justify-content: space-between; font-size: 13px; font-weight: 700; color: var(--ink-soft); padding-bottom: 8px; border-bottom: 2px solid var(--rule); }
.secret .slip-box { width: 128px; height: 56px; border: 2px solid var(--rule); border-radius: 4px; }
.secret .cover b { font-weight: 900; font-stretch: 125%; font-size: 22px; color: var(--blue); }
.secret.open .cover { display: none; }

.timer { font-size: 72px; margin: 6px 0 2px; font-variant-numeric: tabular-nums; }
.timer.low { color: #ffb4ab; }
.order { margin: 18px 0; display: grid; gap: 8px; }
.order .line { display: flex; align-items: center; gap: 12px; font-weight: 700; }
.order .line .n { width: 1.6em; color: var(--blue-soft); font-weight: 800; }

/* the ballot: your vote, written in red pen */
.ballot { background: var(--paper); color: var(--ink); border-radius: var(--r); padding: 14px 16px 16px; }
.ballot .head { display: flex; justify-content: space-between; font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.ballot .field-line { margin-top: 6px; min-height: 58px; border-bottom: 2px solid var(--rule); display: flex; align-items: flex-end; padding-bottom: 2px; }
.ballot .written { font-family: var(--hand); font-weight: 700; font-size: 44px; line-height: 1; color: var(--red); padding-right: .25em; }
.ballot .written.new { animation: write .5s cubic-bezier(.3, .7, .2, 1) both; }
.ballot .empty { color: #6b7385; font-weight: 600; padding-bottom: 8px; }
/* the handwriting leans past its box, so the reveal ends wider than the text */
@keyframes write { from { clip-path: inset(-.3em 100% -.3em -.2em); } to { clip-path: inset(-.3em -.4em -.3em -.2em); } }

.options { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.option {
  position: relative; border: 0; border-radius: var(--r); background: var(--paper); color: var(--ink);
  min-height: 72px; padding: 12px; font-weight: 800; font-size: 17px; overflow: hidden;
}
.option.has-photo { min-height: 124px; padding: 0; }
.option img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.option[aria-pressed="true"] { box-shadow: 0 0 0 4px var(--red); }

/* the count */
.verdict { margin: 22px 0 18px; display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; align-items: center; }
.verdict .face { grid-row: span 2; }
.verdict h2 { font-size: 30px; }
.verdict p { color: var(--blue-soft); }
.tally { background: var(--paper); color: var(--ink); border-radius: var(--r); padding: 6px 14px; }
.tally .line { display: grid; grid-template-columns: 40px 1fr auto; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid #d9dde6; }
.tally .line:last-child { border-bottom: 0; }
.tally .who { font-weight: 800; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.tally .tag { font-size: 12px; font-weight: 800; color: #fff; background: var(--red-deep); border-radius: 3px; padding: 1px 6px; }
.tally .track { height: 10px; background: #e6e9f0; border-radius: 2px; margin-top: 6px; overflow: hidden; }
.tally .bar { height: 100%; background: var(--blue); transform-origin: left; animation: grow .6s cubic-bezier(.2, .8, .2, 1) both; }
.tally .line.odd .bar { background: var(--red); }
.tally .line.tie .bar { background: repeating-linear-gradient(45deg, var(--ink) 0 3px, transparent 3px 6px); }
.tally .count { font-weight: 900; font-stretch: 125%; font-size: 22px; }
.tally .by { font-size: 13px; color: var(--ink-soft); margin-top: 4px; }
@keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.reveal-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.reveal-cards.one { grid-template-columns: 1fr; }
.mini { border-radius: var(--r); background: var(--paper); color: var(--ink); overflow: hidden; }
.mini .pic { aspect-ratio: 4 / 3; width: 100%; object-fit: cover; display: block; }
.mini .cap { padding: 10px 12px 12px; border-top: 2px solid var(--rule); }
.mini .cap .who { font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.mini .cap .what { font-weight: 900; font-stretch: 112%; font-size: 19px; line-height: 1.15; }
.mini.odd .cap { border-top-color: var(--red); }
.mini.odd .cap .what { color: var(--red); }
.credit { font-size: 12px; color: var(--blue-soft); margin-top: 6px; }
.credit a { color: inherit; }
.section { font-size: 17px; font-weight: 800; margin: 24px 0 10px; }
.points .line { display: flex; align-items: center; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid var(--blue-line); }
.points .line:last-child { border-bottom: 0; }
.points .left { display: flex; align-items: center; gap: 12px; font-weight: 700; }
.points .gain { color: var(--blue-soft); font-weight: 700; margin-right: 10px; }
.points .pts { font-weight: 900; font-stretch: 125%; font-size: 20px; }

/* ---------- bottom bar ---------- */

.actionbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10;
  padding: 18px 16px calc(14px + var(--safe-bottom));
  background: linear-gradient(to top, var(--blue) 72%, rgba(18, 58, 140, 0));
}
.actionbar > * { max-width: 508px; margin: 0 auto; }
.waiting { text-align: center; color: var(--blue-soft); padding: 16px 8px; font-weight: 600; }

/* ---------- sheet, toast, connection ---------- */

dialog.sheet {
  width: 100%; max-width: 540px; margin: auto auto 0; border: 0; max-height: 88dvh; overflow-y: auto;
  padding: 24px 16px calc(20px + var(--safe-bottom));
  background: var(--blue-deep); color: #fff; border-radius: 12px 12px 0 0;
}
dialog.sheet::backdrop { background: rgba(0, 0, 0, .6); }
dialog.sheet .stack { display: grid; gap: 12px; }
/* leaving is set apart from everything else */
dialog.sheet .leave { margin-top: 28px; color: #ffb4ab; box-shadow: inset 0 0 0 2px #ffb4ab; }

#toast {
  position: fixed; left: 50%; bottom: calc(100px + var(--safe-bottom)); z-index: 50;
  transform: translate(-50%, 16px); opacity: 0; pointer-events: none;
  max-width: calc(100% - 32px); width: max-content;
  font-weight: 800; padding: 13px 18px; border-radius: var(--r);
  background: #ffb4ab; color: var(--ink);
  box-shadow: 0 8px 20px rgba(0, 0, 0, .35);
  transition: opacity .18s, transform .18s;
}
#toast.ok { background: var(--paper); color: var(--ink); }
#toast.show { opacity: 1; transform: translate(-50%, 0); }
.offline-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40; text-align: center;
  background: #ffb4ab; color: var(--ink); font-size: 14px; font-weight: 800;
  padding: calc(6px + env(safe-area-inset-top, 0px)) 8px 6px;
}
.connecting { padding-top: 40vh; text-align: center; color: var(--blue-soft); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
