#wall { max-width: 1500px; margin: 0 auto; padding: 16px; }
#room { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
@media (max-width: 900px) { #room { grid-template-columns: minmax(0, 1fr); } }

.player { position: relative; background: #000; border-radius: var(--r-lg); overflow: hidden; aspect-ratio: 16 / 9; }
.player video { width: 100%; height: 100%; display: block; background: #000; }
.offline { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; background: var(--panel);
  pointer-events: none; overflow-y: auto; }   /* never eats taps meant for the controls; its own buttons opt back in */
.offline button, .offline a, .offline select { pointer-events: auto; }
.off-in { padding: 16px; max-width: 560px; width: 100%; }
/* wall off: the box sizes to the pre-show instead of a fixed 16:9 black hole */
.player.off { aspect-ratio: auto; min-height: 200px; }
.player.off video { display: none; }
.player.off .offline { position: relative; inset: auto; min-height: 200px; }
.player.off .chat-toggle { z-index: 2; }
[data-member][hidden], .controls .row[hidden], .controls .btn[hidden], .controls input[hidden] { display: none !important; }
.unmute { position: absolute; left: 12px; bottom: 12px; border: 0; border-radius: var(--r-pill); padding: 8px 14px; min-height: 44px;
  background: rgba(17,18,26,.8); color: var(--fg); font: inherit; cursor: pointer; }
.unmute[hidden], .offline[hidden], #room[hidden], #gate[hidden], .scrim[hidden], .badge[hidden] { display: none; }

.bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 10px 0; }
.bar .pill { font-size: 12px; padding: 3px 10px; }
#sync.ok { color: var(--green); background: var(--green-soft); }
#sync.meh { color: var(--gold); }
#sync.bad { color: var(--red); background: var(--red-soft); }

.tiles { display: grid; gap: 6px; }
.tiles:empty { display: none; }
.tile { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; min-width: 0; padding: 6px 8px 6px 12px; font-size: 13px;
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r-sm); }
.tile .num { color: var(--muted); font-variant-numeric: tabular-nums; min-width: 1ch; }
.tile .lbl { flex: 1 1 140px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile.sound { box-shadow: inset 3px 0 0 var(--accent); }
.tile > span.small { order: 1; white-space: nowrap; }
.tile > button { order: 2; }
.tile > button.star { order: 3; }
.tile button { border: 1px solid var(--line); background: transparent; color: var(--fg-2); border-radius: var(--r-sm);
  font: inherit; font-size: 12px; padding: 3px 10px; cursor: pointer; white-space: nowrap; }
.tile button:hover { color: var(--fg); border-color: var(--line-strong); }
button.star { color: var(--muted); }
button.star[aria-pressed="true"] { color: var(--gold); }

.props { display: grid; gap: 8px; margin-bottom: 10px; }
.props:empty { display: none; }
.prop { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; background: var(--panel2); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); padding: 8px 12px; }
.prop .what { flex: 1 1 220px; min-width: 0; overflow-wrap: anywhere; }
.prop .tally { font-variant-numeric: tabular-nums; color: var(--muted); font-size: 13px; }
.prop button { border: 1px solid var(--line); background: var(--panel); color: var(--fg); border-radius: var(--r-sm);
  font: inherit; padding: 4px 12px; cursor: pointer; }
.prop button.mine { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.prop .left { font-variant-numeric: tabular-nums; font-size: 12px; color: var(--gold); min-width: 34px; text-align: right; }

.controls summary { cursor: pointer; font-weight: 600; }
#ownerNote { margin-left: 8px; font-size: 12px; font-weight: 400; }
.controls .row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
/* "Change the wall": Screens / Streams / Spectrum / Local news / Wall settings */
.ctl-sec { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); }
.sheet-head + .ctl-sec { margin-top: 8px; padding-top: 0; border-top: 0; }
.ctl-sec[hidden] { display: none; }
.ctl-h { margin: 0 0 8px; font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.ctl-h label { cursor: pointer; }
.ctl-h + .row { margin-top: 0; }
.ctl-lbl { color: var(--muted); font-size: 13px; }
.ctl-note { margin: 16px 0 0; }
.jev-line { flex-basis: 100%; }
.controls select, .controls input, .chat input { background: var(--panel2); color: var(--fg); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 6px 8px; font: inherit; }
.controls input { flex: 1 1 220px; min-width: 0; }
.controls .tiles { margin: 0; }
.small { font-size: 12px; }
.sheet-head, .sum-short, .vstrip, .vcount { display: none; }

.side { display: grid; gap: 16px; }
.side h3 { margin: 0 0 10px; font-size: 14px; }
.viewers summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; }
.viewers > summary::before { content: none !important; }
.viewers ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.viewers li { display: flex; gap: 8px; align-items: center; font-size: 14px; min-width: 0; }
.viewers li > span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viewers li.away { opacity: .45; }
.viewers li .tag { font-size: 11px; color: var(--muted); }
.av { width: 26px; height: 26px; border-radius: 50%; flex: none; display: grid; place-items: center; font-size: 11px; font-weight: 700;
  background: var(--accent-soft); color: var(--accent); object-fit: cover; }

.chat { display: flex; flex-direction: column; height: min(70vh, 640px); }
@media (max-width: 900px) { .chat { height: 60vh; } }
.chat-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.chat-head h3 { margin: 0; }
.ding { border: 0; background: none; color: var(--fg); font: inherit; font-size: 15px; line-height: 1; cursor: pointer;
  border-radius: var(--r-pill); width: 32px; height: 32px; display: grid; place-items: center; }
.ding:hover { background: var(--panel2); }
.ding[aria-pressed="false"] { opacity: .6; }
#msgs { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 6px;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
#msgs li { display: flex; gap: 8px; font-size: 14px; line-height: 1.35; word-break: break-word; overflow-wrap: anywhere; }
#msgs li .who { font-weight: 600; color: var(--accent2); margin-right: 4px; }
#msgs li.sys { color: var(--muted); font-style: italic; font-size: 13px; }
#msgs li .mod { margin-left: auto; opacity: 0; border: 0; background: none; color: var(--muted); cursor: pointer; font: inherit; font-size: 12px; }
#msgs li .mod + .mod { margin-left: 0; }
#msgs li:hover .mod, #msgs li .mod:focus-visible { opacity: 1; }
@media (hover: none) { #msgs li .mod { opacity: .6; min-width: 44px; min-height: 44px; margin: -12px 0; } }
#chatForm { display: flex; gap: 8px; margin-top: 10px; }
#chatForm input { flex: 1; min-width: 0; }

.bar .btn { cursor: pointer; border: 0; font: inherit; }
.bar [hidden] { display: none !important; }
.bar .vol { width: 90px; accent-color: var(--accent); cursor: pointer; flex: none; }
#pipBtn[aria-pressed="true"] { color: var(--accent); }
.player:fullscreen, .player:-webkit-full-screen { background: #000; display: flex; align-items: center; justify-content: center; }
.player:fullscreen video, .player:-webkit-full-screen video { width: 100%; height: 100%; object-fit: contain; }

.live-row { align-items: flex-start; }
.live-games { display: flex; flex-wrap: wrap; gap: 6px; }
.live-games .btn:disabled { cursor: default; }
.live-games .pool { display: inline-flex; align-items: center; gap: 4px; }
.pool button.star { border: 0; background: none; font-size: 15px; cursor: pointer; padding: 4px; }
/* election night: the Spectrum lineup, one row per leaning */
.spectrum { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.spectrum .spec-grp { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.spectrum .spec-grp > b { min-width: 6.5em; font-size: 13px; color: var(--muted); font-weight: 500; }
.spectrum .btn:disabled { cursor: default; }

/* the chat toggle + unread badge only show in phone landscape (below) */
.chat-toggle { display: none; }
.badge { position: absolute; top: -3px; right: -3px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--accent2); color: var(--accent-ink); font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; }
.scrim { position: fixed; inset: 0; z-index: 59; background: rgba(8,9,14,.55); }

/* ── phones, portrait: the video stuck on top, chat fills the rest, the input sits above the keyboard ──
   body.inroom is pinned to the visual viewport (--vvh / --vvtop from wall.js), so the iOS keyboard shrinks the chat
   instead of covering the input or scrolling the video away. Keep this query in step with PORTRAIT in wall.js. */
@media (max-width: 700px) and (orientation: portrait), (max-width: 700px) and (min-height: 501px) {
  body.inroom { position: fixed; left: 0; right: 0; top: var(--vvtop, 0px); height: var(--vvh, 100dvh);
    display: flex; flex-direction: column; overflow: hidden; }
  body.inroom header { position: static; flex: none; flex-wrap: nowrap; gap: 12px;
    padding: max(2px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) 2px max(12px, env(safe-area-inset-left)); }
  body.inroom .brand { font-size: 16px; white-space: nowrap; }
  body.inroom .nav { width: auto; order: 0; gap: 4px; overflow: visible; }
  body.inroom .nav a { font-size: 13px; padding: 12px 6px; }
  body.inroom #navRight { display: none; }
  body.inroom #wall { flex: 1; min-height: 0; display: flex; max-width: none; margin: 0; padding: 0; }

  #room { flex: 1; min-height: 0; gap: 0; align-items: stretch;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto auto auto minmax(0, 1fr);
    grid-template-areas: "player player" "bar bar" "viewers ctl" "props props" "chat chat"; }
  .stage, .side { display: contents; }
  .player { grid-area: player; border-radius: 0; }
  body:not(.public) .player { width: 100%; min-height: calc(100vw * 9 / 16); }   /* never squeezed by a short room */
  /* the phone grid is fixed-height (player · bar · strip · chat): panels without an area pushed the player to 0 px.
     Bets and the live feed live in the Election sheet on phones instead (wall-election.js moves them there). */
  #room > .stage > #betsPanel, #room > .stage > .lv-feed { display: none; }
  .unmute { left: 8px; bottom: 8px; }

  .bar { grid-area: bar; margin: 0; padding: 4px max(8px, env(safe-area-inset-left)); gap: 4px; flex-wrap: nowrap; min-width: 0;
    border-bottom: 1px solid var(--line); }
  .bar .btn { min-width: 44px; min-height: 44px; padding: 0 8px; font-size: 18px; display: inline-grid; place-items: center; flex: none; }
  .bar .lbl, .bar .act, #wallName, #mirror { display: none; }
  body:not(.public) .bar #count, .bar .vol { display: none !important; }   /* phones: hardware volume; the strip below shows who is here */
  .bar #elecBtn .lbl { display: inline; font-size: 14px; font-weight: 600; }
  .bar #elecBtn { display: inline-flex; gap: 4px; align-items: center; }
  .bar #sync { margin-left: auto; }
  .bar .pill:not(.btn) { white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

  /* one slim row under the bar: the avatar strip (→ who's watching) and the "change the wall" sheet */
  .viewers, .controls { border: 0; border-radius: 0; box-shadow: none; background: none; padding: 0; min-width: 0; }
  .viewers { grid-area: viewers; }
  .controls { grid-area: ctl; }
  .viewers > summary, .controls > summary { min-height: 48px; display: flex; align-items: center; gap: 8px; padding: 0 12px;
    list-style: none; border-bottom: 1px solid var(--line); }
  .controls > summary::before { content: none !important; }   /* hqstyle's ▸/▾: these open as sheets */
  .viewers > summary h3 { display: none; }
  .vstrip { display: flex; flex: none; padding-right: 8px; }
  .vstrip .av { width: 28px; height: 28px; border: 2px solid var(--bg); margin-right: -8px; }
  .vstrip .more { background: var(--panel2); color: var(--muted); }
  .vcount { display: block; flex: 1; min-width: 0; font-size: 14px; color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .controls > summary { color: var(--accent); font-weight: 600; font-size: 14px; white-space: nowrap; }
  .controls > summary .sum-full, .controls > summary #ownerNote { display: none; }
  .controls > summary .sum-short { display: inline; padding: 6px 12px; border: 1px solid var(--line); border-radius: var(--r-pill); }

  /* the sheets: bottom sheets over the chat */
  .sheet-host[open] > .sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    max-height: calc(var(--vvh, 100dvh) - 72px); overflow-y: auto; overscroll-behavior: contain;
    background: var(--panel); border-top: 1px solid var(--line-strong); border-radius: 16px 16px 0 0; box-shadow: var(--shadow-lg);
    padding: 4px max(16px, env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left)); }
  .sheet-head { display: flex; align-items: center; justify-content: space-between; position: sticky; top: -4px; z-index: 1;
    background: var(--panel); padding: 6px 0; border-bottom: 1px solid var(--line); }
  .sheet-done { min-height: 44px; padding: 0 16px; }
  .viewers ul { gap: 2px; padding-top: 6px; }
  .viewers li { min-height: 44px; font-size: 15px; }
  .viewers li .av { width: 32px; height: 32px; font-size: 12px; }
  .controls .row { margin-top: 14px; }
  .controls select, .controls input, .chat input { font-size: 16px; min-height: 44px; }
  .controls select { max-width: 100%; }
  .controls .btn, .live-games .btn, .tile button { min-height: 44px; }
  .controls .row > span:not(.muted) { flex-basis: 100%; }
  .controls .row label { display: flex; align-items: center; gap: 8px; flex: 1 1 100%; }
  .controls .row label select { flex: 1; min-width: 0; }
  .live-row > span:first-child { flex-basis: 100%; }
  .live-games { width: 100%; }
  .tile { padding: 6px 8px 6px 12px; font-size: 14px; }
  .tile .lbl { flex: 1 1 calc(100% - 4em); }
  .tile button { min-width: 44px; }
  .ctl-sec { margin-top: 18px; }
  .spectrum .spec-grp > b { flex-basis: 100%; }

  .props { grid-area: props; margin: 0; padding: 8px 12px; max-height: 34vh; overflow-y: auto; border-bottom: 1px solid var(--line); }
  .prop { gap: 8px; padding: 8px 10px; }
  .prop .what { flex-basis: 100%; font-size: 14px; }
  .prop .tally { flex: 1; }
  .prop button { min-width: 52px; min-height: 44px; font-size: 16px; }

  .chat { grid-area: chat; height: auto; min-height: 0; border: 0; border-radius: 0; box-shadow: none;
    padding: 6px max(12px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); }
  .chat-head { margin-bottom: 6px; }
  .chat-head h3 { font-size: 13px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
  .ding { width: 44px; height: 44px; margin: -6px -10px -6px 0; font-size: 18px; }
  #msgs li { font-size: 15px; }
  #chatForm { margin-top: 8px; }
  #chatForm .btn { min-height: 44px; padding: 0 16px; }
  #chatErr:empty { display: none; }

  /* keyboard open: only the video and the chat stay */
  body.kb header, body.kb .bar, body.kb .viewers, body.kb .controls, body.kb .props { display: none; }
  body.kb .chat { padding-bottom: 6px; }
  body.kb .chat-head { display: none; }
}

/* ── phones, landscape: the video is the whole screen; chat is a see-through overlay on the right ──
   Keep this query in step with LANDSCAPE in wall.js. */
@media (orientation: landscape) and (max-height: 500px) {
  body.inroom { position: fixed; inset: 0; overflow: hidden; background: #000; }
  body.inroom header { display: none; }
  body.inroom #wall { max-width: none; margin: 0; padding: 0; }
  #room { display: block; }
  .stage, .side { display: contents; }
  .player { position: fixed; inset: 0; z-index: 1; border-radius: 0; aspect-ratio: auto; }
  .player video { object-fit: contain; }
  .unmute { left: max(12px, env(safe-area-inset-left)); bottom: max(12px, env(safe-area-inset-bottom)); z-index: 4; }
  .viewers, .controls, #wallName, #mirror, .bar .lbl, .bar .act { display: none; }
  .bar #elecBtn .lbl { display: inline; font-size: 14px; font-weight: 600; }
  .bar #elecBtn { display: inline-flex; gap: 4px; align-items: center; }
  .player.off { position: fixed; inset: 0; min-height: 0; }
  .player.off .offline { position: absolute; inset: 0; min-height: 0; padding-top: 56px; }

  .bar { position: fixed; z-index: 5; margin: 0; flex-wrap: nowrap; gap: 6px; pointer-events: none;
    top: max(8px, env(safe-area-inset-top)); left: max(8px, env(safe-area-inset-left)); }
  .bar > * { pointer-events: auto; transition: opacity .4s ease; }
  .bar .pill { background: rgba(17,18,26,.66); }
  .bar .btn { min-width: 44px; min-height: 44px; font-size: 18px; display: inline-grid; place-items: center; padding: 0 10px; }
  /* idle over a running stream: everything fades but the Election button */
  body.idle .bar > :not(#elecBtn) { opacity: 0; pointer-events: none; }

  .props { position: fixed; z-index: 5; margin: 0; left: max(8px, env(safe-area-inset-left)); top: 64px;
    max-width: min(46vw, 360px); max-height: calc(100% - 140px); overflow-y: auto; }
  .prop { background: rgba(31,34,48,.86); padding: 6px 8px; gap: 6px; }
  .prop .what { flex-basis: 100%; font-size: 13px; }
  .prop button { min-width: 44px; min-height: 44px; }

  .chat { position: fixed; z-index: 6; right: 0; top: var(--vvtop, 0px); height: var(--vvh, 100%);
    width: min(42vw, 340px); border: 0; border-radius: 0; box-shadow: none;
    background: linear-gradient(90deg, rgba(17,18,26,.35), rgba(17,18,26,.72) 30%);
    backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
    padding: max(8px, env(safe-area-inset-top)) max(10px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) 14px;
    opacity: 0; visibility: hidden; transform: translateX(12px);
    transition: opacity .4s ease, transform .4s ease, visibility 0s linear .4s; }
  body.chat-on .chat { opacity: 1; visibility: visible; transform: none; transition: opacity .4s ease, transform .4s ease; }
  .chat-head { margin-bottom: 4px; }
  .chat-head h3 { font-size: 12px; color: var(--fg-2); }
  .ding { width: 44px; height: 44px; margin: -8px -6px -8px 0; }
  #msgs li { font-size: 14px; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
  #msgs li .mod { display: none; }   /* moderate from portrait or desktop; keep the overlay clean */
  #msgs li .av { width: 22px; height: 22px; font-size: 10px; }
  #chatForm { margin-top: 6px; }
  .chat input { font-size: 16px; min-height: 44px; background: rgba(31,34,48,.9); }
  #chatForm .btn { min-height: 44px; }
  #chatErr:empty { display: none; }

  .chat-toggle { display: grid; place-items: center; position: fixed; z-index: 7; width: 44px; height: 44px;
    right: max(12px, env(safe-area-inset-right)); bottom: max(12px, env(safe-area-inset-bottom));
    border: 1px solid rgba(255,255,255,.12); border-radius: 50%; background: rgba(17,18,26,.66); color: var(--fg);
    font-size: 18px; cursor: pointer; transition: opacity .4s ease; }
  body.chat-on .chat-toggle { right: calc(min(42vw, 340px) + 10px); }
  body.idle:not(.chat-on) .chat-toggle { opacity: .55; }
}

/* ---- join screen (#gate): a centred card on desktop, a full-width sheet on phones ---- */
.gate { --discord: #5865f2; --discord-hover: #4752c4; display: flex; justify-content: center; padding: clamp(24px, 8vh, 72px) 0 32px; }
.gate-card { width: 100%; max-width: 440px; background: var(--card); border: 1px solid var(--border); border-radius: 18px;
  padding: 32px 28px 26px; box-shadow: var(--shadow); color: var(--text); }
@media (prefers-reduced-motion: no-preference) {
  .gate-card { animation: gate-in .28s ease-out both; }
  @keyframes gate-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}
.gate-kicker { margin: 0 0 6px; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.gate h1 { margin: 0; font-size: 30px; line-height: 1.15; font-weight: 800; letter-spacing: -.01em; color: var(--text); }
.gate-lede { margin: 8px 0 0; font-size: 16px; line-height: 1.45; color: var(--fg-2); }
.gate-peek { display: inline-flex; align-items: center; gap: 8px; margin: 16px 0 0; padding: 6px 12px; border-radius: var(--r-pill);
  background: var(--panel2); border: 1px solid var(--border); font-size: 14px; color: var(--text-muted); max-width: 100%; }
.gate-peek #peekText { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.gate-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--faint); }
.gate-peek.on { color: var(--text); }
.gate-peek.on .gate-dot { background: var(--green); }
.gate-peek.empty { visibility: hidden; }   /* reserved, so the buttons below never move when it fills in */
.gate-guest[hidden], .gate-roles[hidden] { display: none; }
.gate-msg { margin: 14px 0 0; font-size: 14px; color: var(--gold); }
.gate-msg:empty { display: none; }

.gate-discord { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; min-height: 52px; margin-top: 24px;
  padding: 0 18px; border-radius: 12px; background: var(--discord); color: #fff; font-size: 17px; font-weight: 700;
  text-decoration: none; transition: background-color var(--t); }
.gate-discord:hover { background: var(--discord-hover); color: #fff; text-decoration: none; }
.gate-discord svg { flex: none; }
.gate-sub { margin: 8px 0 0; font-size: 13px; color: var(--text-muted); text-align: center; }

.gate-or { display: flex; align-items: center; gap: 12px; margin: 22px 0 16px; color: var(--faint); font-size: 12px;
  text-transform: uppercase; letter-spacing: .08em; }
.gate-or::before, .gate-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.gate-label { display: block; margin-bottom: 8px; font-size: 15px; font-weight: 700; color: var(--text); }
.gate-field { display: flex; gap: 8px; }
.gate-field input { flex: 1; min-width: 0; min-height: 48px; padding: 0 14px; border-radius: 12px; border: 1px solid var(--line-strong);
  background: var(--bg); color: var(--text); font: inherit; font-size: 16px;   /* 16px: no iOS zoom on focus */
  transition: border-color var(--t), box-shadow var(--t); }
.gate-field input::placeholder { color: var(--faint); }
.gate-field input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
.gate-field input[aria-invalid="true"] { border-color: var(--red); }
.gate-field input[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--red-soft); }
.gate-join { flex: none; min-height: 48px; min-width: 88px; padding: 0 20px; border: 0; border-radius: 12px; background: var(--accent);
  color: var(--accent-ink); font: inherit; font-size: 16px; font-weight: 700; cursor: pointer; transition: filter var(--t); }
.gate-join:hover { filter: brightness(1.08); }
.gate-join:disabled { opacity: .6; cursor: progress; }
.gate-err { margin: 8px 0 0; font-size: 14px; line-height: 1.4; color: var(--red); }
.gate-err:empty { display: none; }
.gate-discord:focus-visible, .gate-join:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }

.gate-roles { margin: 20px 0 0; font-size: 13px; line-height: 1.45; color: var(--text-muted); text-align: center; }

@media (max-width: 560px) {
  body:not(.inroom) { min-height: 100dvh; display: flex; flex-direction: column; }
  body:not(.inroom) #wall { flex: 1; display: flex; flex-direction: column; width: 100%; }
  .gate { flex: 1; padding: 20px 0 0; margin: 0 -16px -16px; align-items: stretch; }
  .gate-card { max-width: none; border-radius: 22px 22px 0 0; border-bottom: 0; border-left: 0; border-right: 0;
    padding: 28px 20px calc(28px + env(safe-area-inset-bottom)); box-shadow: 0 -8px 28px rgba(0,0,0,.35); }
  .gate h1 { font-size: 28px; }
}

/* ---- the pre-show while the wall is off (filled by wall-election.js on election night) ---- */
.offline:has(.preshow:not([hidden])) #offGeneric { display: none; }
.preshow[hidden] { display: none; }
.preshow { display: grid; gap: 10px; text-align: center; }
.ps-kicker { margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.ps-title { margin: 0; text-transform: none; letter-spacing: 0; font-size: clamp(18px, 3.4vw, 26px); line-height: 1.2; font-weight: 800; color: var(--fg); }
.ps-count { margin: 0; font-size: clamp(22px, 5vw, 34px); font-weight: 800; font-variant-numeric: tabular-nums; color: var(--gold); }
.ps-next { margin: 0; font-size: 13px; line-height: 1.5; color: var(--fg-2); }
.ps-next b { color: var(--fg); }
.ps-bal { text-align: left; }
.ps-bal .el-nums b { white-space: nowrap; font-size: 16px; }
.ps-open { justify-self: center; display: inline-flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 22px; border: 0;
  border-radius: 12px; background: var(--accent); color: var(--accent-ink); font: inherit; font-size: 16px; font-weight: 700; cursor: pointer; }
.ps-open:hover { filter: brightness(1.08); }
.ps-open:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; }
@media (orientation: landscape) and (max-height: 500px) {
  .preshow { gap: 6px; }
  .ps-next { font-size: 12px; }
}

/* status badges stay quiet: muted text, a small red dot for live / on air */
.live-on { color: var(--fg-2); }
.live-on::before { content: ""; display: inline-block; width: 6px; height: 6px; margin-right: 5px; border-radius: 50%;
  background: var(--bad); vertical-align: 1px; }

/* Desktop (≥ 1400 px): the whole width — a bigger video and map — and a wider right rail that stays in view while the main
   column scrolls: who's watching, the chat (filling what's left of the screen) and the live updates feed under it. */
@media (min-width: 1400px) {
  #wall { max-width: none; padding: 16px 24px; }
  #room { grid-template-columns: minmax(0, 1fr) clamp(380px, 24vw, 520px); }
  .side { position: sticky; top: 12px; max-height: calc(100vh - 24px); grid-template-rows: auto minmax(0, 1fr) auto; }
  .side .chat { height: auto; min-height: 320px; }
  .side .lv-feed { max-height: 38vh; overflow-y: auto; }
}

/* the top nav is for logged-in members only (wall.js unhides it); friends and public viewers see the page's own name */
.nav[hidden] { display: none !important; }

/* public mode (the plain page, no login): live election data + the chat read-only — no stream, no votes, no viewer list */
.public-note { margin: 0 0 12px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px;
  color: var(--muted); font-size: 13px; text-align: center; }
.pub-login { font-size: 13px; color: var(--muted); }
body.public .controls, body.public .viewers, body.public #props { display: none !important; }
@media (max-width: 700px) and (orientation: portrait), (max-width: 700px) and (min-height: 501px) {
  body.public.inroom #wall { flex-direction: column; }
  body.public.inroom #room { flex: 1; display: block; overflow-y: auto; padding: 8px; }
  body.public .bar { flex-wrap: wrap; }
  body.public.inroom .stage, body.public.inroom .side { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
  body.public.inroom .stage > *, body.public.inroom .side > * { grid-area: auto; margin: 0; }
  body.public .chat #msgs { max-height: 40vh; }
  body.public .public-note { margin: 0; border-radius: 0; border-width: 0 0 1px; padding: 6px 12px; font-size: 12px; }
}

/* DJ Jev in the viewer list: a plain small tag */
.viewers li .tag.jev-tag { padding: 0 6px; border: 1px solid var(--line); border-radius: var(--r-sm); }

/* ---- full screen: the chat floating over the video, Twitch-style (wall.js fchat) ----
   body.fs = the player box is fullscreen (requestFullscreen) or pseudo-fullscreen (body.pfs: iPhone, where only the bare
   <video> can go native-fullscreen and nothing overlays that — the box is pinned over the whole viewport instead). */
.fchat, .fs-ctl { display: none; }
body.pfs { overflow: hidden; overscroll-behavior: none; touch-action: none; }
body.pfs header, body.pfs .bar, body.pfs .chat-toggle { visibility: hidden; }
body.pfs .player { position: fixed; inset: 0; z-index: 90; width: 100vw; height: 100vh; height: 100dvh; max-width: none;
  aspect-ratio: auto; border-radius: 0; margin: 0; background: #000; }
body.pfs .player video { width: 100%; height: 100%; object-fit: contain; }
/* held upright: the player box (video, floating chat, its buttons) turns 90° so the 16:9 picture fills the long edge */
@media (orientation: portrait) {
  body.pfs .player { inset: auto; top: 0; left: 0; width: 100vh; width: 100dvh; height: 100vw; height: 100dvw;
    transform-origin: top left; transform: translateX(100vw) rotate(90deg); }
  body.pfs .fchat { right: 14px; bottom: 68px; width: min(40%, 400px); }
  body.pfs .fs-ctl { right: 12px; bottom: 12px; }
}
body.fs .chat-toggle { display: none !important; }
body.fs .fchat { display: flex; flex-direction: column; justify-content: flex-end; gap: 8px; position: absolute; z-index: 3;
  right: max(14px, env(safe-area-inset-right)); bottom: calc(max(12px, env(safe-area-inset-bottom)) + 56px);
  width: min(44%, 400px); max-height: 60%; pointer-events: none; }
.fmsgs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; overflow: hidden; }
.fmsgs li { color: #fff; font-size: clamp(14px, 1.7vw, 24px); line-height: 1.3; font-weight: 500; overflow-wrap: anywhere;
  text-shadow: 0 0 2px #000, 0 0 2px #000, 0 1px 3px rgba(0,0,0,.95), 0 0 8px rgba(0,0,0,.6);
  animation: fchat-in .25s ease-out both; transition: opacity 1s ease; }
.fmsgs li b { font-weight: 700; margin-right: .4em; }
.fmsgs li.guest b { color: #e6e6e6; }
.fmsgs li.sys { color: var(--accent, #FFB000); font-weight: 600; }
.fmsgs li.gone { opacity: 0; }
@keyframes fchat-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
body.fchat-off .fmsgs { display: none; }
.fchat-form { display: flex; gap: 6px; pointer-events: auto; }
.fchat-form[hidden] { display: none; }
.fchat-form input { flex: 1; min-width: 0; font-size: 16px; min-height: 40px; border-radius: 10px; padding: 0 10px;
  border: 1px solid rgba(255,255,255,.18); background: rgba(17,18,26,.82); color: var(--fg); }
.fchat-form .btn { min-height: 40px; }
body.fs .fs-ctl { display: flex; gap: 8px; position: absolute; z-index: 4;
  right: max(12px, env(safe-area-inset-right)); bottom: max(12px, env(safe-area-inset-bottom)); }
.fs-ctl button { width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(255,255,255,.14); cursor: pointer;
  background: rgba(17,18,26,.6); color: var(--fg); font-size: 18px; display: grid; place-items: center; padding: 0;
  transition: opacity .4s ease; }
.fs-ctl button[hidden] { display: none; }
#fchatBtn[aria-pressed="false"] { opacity: .5; }
body.fs.fs-idle .fs-ctl button { opacity: 0; }
body.public .fchat-form, body.public #fsayBtn { display: none !important; }

/* ---- one button style per role on this page: primary (accent fill: Send, Join), secondary (everything else), chip
   (.el-chip / .el-segbtn in wall-election.css). hqstyle's plain .btn is an accent fill, which made every control shout. ---- */
#wall .btn:not(.pill):not(.primary) { background: var(--panel2); color: var(--fg); border: 1px solid var(--line); border-radius: var(--r-sm);
  font: inherit; font-size: 13px; font-weight: 500; line-height: 1.3; padding: 6px 12px; }
#wall .btn:not(.pill):not(.primary):hover { filter: none; border-color: var(--line-strong); }
#wall .btn.ghost { background: transparent; color: var(--fg-2); }
#wall .btn[aria-pressed="true"] { border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); color: var(--accent); }
#wall .btn:disabled { opacity: .5; }
#wall .btn .small { margin-left: 6px; font-weight: 400; }
#wall .btn.primary { border-radius: var(--r-sm); padding: 8px 16px; }

/* phones: the Bets panel and the Live updates feed are sections of the Election sheet (wall-election.js placePanels) */
.elec .lv-feed, .elec .bets { margin: 16px 0 0; padding: 12px 0 0; border: 0; border-top: 1px solid var(--line); border-radius: 0;
  background: none; box-shadow: none; }

/* no votes: only the owner/admins get the wall controls; everyone else asks DJ Jev in chat */
body.no-control .controls, body.no-control #props, body.no-control .tile button { display: none !important; }
body.no-control #chatIn::placeholder { color: var(--muted); }

/* no purple on this page: hqstyle's second accent (chat names, the unread badge, bettors) is the main accent here */
:root { --accent2: var(--accent); }

/* ---- icons: small white glyphs (web/static/icons/*.svg used as masks) in place of emoji ---- */
.i { display: inline-block; flex: none; width: clamp(14px, 1.15em, 18px); height: clamp(14px, 1.15em, 18px); vertical-align: -0.2em;
  background-color: #fff; -webkit-mask: var(--i) center / contain no-repeat; mask: var(--i) center / contain no-repeat; }
.i-volume { --i: url(/icons/volume.svg); }
.i-mute { --i: url(/icons/mute.svg); }
.i-chat { --i: url(/icons/chat.svg); }
.i-pencil { --i: url(/icons/pencil.svg); }
.i-fullscreen { --i: url(/icons/fullscreen.svg); }
.i-pip { --i: url(/icons/pip.svg); }
.i-bell { --i: url(/icons/bell.svg); }
.i-bell-off { --i: url(/icons/bell-off.svg); }
.i-star { --i: url(/icons/star.svg); }
.i-star-outline { --i: url(/icons/star-outline.svg); }
.i-close { --i: url(/icons/close.svg); }
.fs-ctl .i, .chat-toggle .i, .ding .i, .bar .ico { width: 18px; height: 18px; }
.unmute .i { margin-right: 4px; }
