/* A picture round question: one image above the question. The 286 set on a phone is 10-31 KB and the
   1080 set on the TV up to 479 KB, and either way it must never push the choices off the screen - so
   the height is capped rather than left to the browser. */
.picture {
  display: block;
  margin: 0 auto 12px;
  max-width: 100%;
  max-height: 52vh;
  width: auto;
  height: auto;
  border-radius: 8px;
}

/* THE HOST CONSOLE ON A PHONE. He hosts standing up, walking the room, one hand on the phone - a
   Samsung S21+ on a dark floor. So the two things he must never scroll for are the question he is
   reading (top) and the button that moves the night on (stuck to the bottom). The scores are a
   glance, not a table. Everything else - the pack, the clear ladder, the log, the player table -
   sits below, because that is where he has time to look at it. The orange is provisional: it is the
   app's accent today and the brand colours land with his logo. */
.host-strip {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 8px 4px;
  margin: 0 0 10px;
  background: #0d0d0d;
  border-bottom: 1px solid #333;
  font-size: 0.85rem;
}
.host-strip .host-phase { font-weight: 700; }
.host-strip .host-locked { color: #ffa640; }
.host-strip .host-state { margin-left: auto; color: #9a9a9a; }

.host-card {
  border: 1px solid #3a3a3a;
  border-radius: 12px;
  padding: 12px 14px;
  margin-bottom: 12px;
}
.host-card h3 {
  margin: 0 0 10px;
  font-size: 1.2rem;
  line-height: 1.32;
}
/* THE PICTURE SWITCH: his control over one question's picture, on his console only. A question that has
   its picture switched off shows the picture dimmed and dashed here, because he cannot judge a picture he
   cannot see - and the room is never told about it at all. */
.host-picture-switch { display: flex; align-items: center; gap: 8px; margin: 8px 0; font-size: 0.95rem; }
.host-picture-switch input { width: 1.1rem; height: 1.1rem; }
.picture.picture-off { opacity: 0.4; border: 1px dashed #6a6a6a; border-radius: 10px; }
.host-picture-hidden { margin: 2px 0 8px; color: #ffa640; font-size: 0.9rem; }
/* THE PROOF ON HIS CONSOLE: the page and the sentence. Deliberately plain and small - it is read when
   somebody argues, not while he is reading the question out. */
/* THE GENERATOR'S OWN PROOF COLUMN: the page a question came from, the sentence the answer sits in, and
   the picture with its risk note. Small type on purpose - it is read when a question is being judged, not
   when it is being read out. */
.gen-source { margin: 6px 0 2px; font-size: 0.82rem; color: #7fd6c8; word-break: break-all; }
.gen-source a { color: #7fd6c8; }
.gen-quote { margin: 2px 0 6px; font-size: 0.82rem; color: #b9b9b9; font-style: italic; }
.gen-risk { margin: 4px 0; font-size: 0.82rem; color: #ffa640; }
/* WHAT JUST HAPPENED, said where he is looking: a pack loaded, or a file that was not a pack. */
/* SKIP sits beside the big button but never where a thumb rests: the big button runs the night, this one
   throws a question away. */
.host-skip { width: 100%; margin-top: 8px; padding: 10px 12px; border-radius: 10px; border: 1px solid #6a4a2a; background: #241a10; color: #ffa640; font-size: 0.95rem; }
/* THE INSTALL OFFER: one button for Chrome and Edge, one sentence for Safari. Never in the way. */
.install-box { margin: 4px 0 0; }
.install-btn {
  width: 100%; min-height: 48px; border-radius: 12px; border: 1px solid #3a4a48; background: #0f1a18;
  color: #7fd6c8; font-size: 1rem; font-weight: 700;
}
.install-box p { margin: 8px 0 0; color: #9a9a9a; font-size: 0.8rem; text-align: center; line-height: 1.45; }

/* THE CONSENT LINE under the join form - the same promise the old app makes, on the same published pages. */
.consent { margin: 14px 0 12px; color: #b9b9b9; font-size: 0.82rem; line-height: 1.5; text-align: center; }
.consent a { color: #7fd6c8; text-decoration: underline; }

/* THE HOST PHONE CONTROL: one hand, a dark room, four buttons. Nothing else competes with them. */
body[data-role="control"] main#view { max-width: 520px; margin: 0 auto; padding: 12px 14px 22px; }
.ctl-where { margin: 0 0 8px; color: #ffd200; font-weight: 700; font-size: 0.9rem; letter-spacing: 0.04em; }
.ctl-question { margin: 0 0 10px; font-size: 1.5rem; line-height: 1.25; font-weight: 700; }
.ctl-choices { list-style: none; margin: 0 0 14px; padding: 0; font-size: 1.1rem; }
.ctl-choices li { padding: 6px 0; color: #cfcfcf; }
.ctl-choices li.right { color: #7ee081; font-weight: 700; }
/* THE ANSWER CLOCK, per round: three small choices that never compete with the four buttons. */
.ctl-clocks { display: flex; align-items: center; gap: 8px; margin: 10px 0 4px; }
.ctl-clock-label { color: #8f8f8f; font-size: 0.8rem; letter-spacing: 0.04em; text-transform: uppercase; }
.ctl-clock { flex: 1 1 0; min-height: 40px; border-radius: 10px; border: 1px solid #3a3a3a; background: #141414; color: #b9b9b9; font-weight: 700; }
.ctl-clock.on { border-color: #7fd6c8; color: #7fd6c8; background: #0f1a18; }
.ctl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ctl-btn {
  min-height: 92px; border-radius: 16px; border: 1px solid #333; background: #141414; color: #8f8f8f;
  font-size: 1rem; font-weight: 700; letter-spacing: 0.03em; padding: 10px;
}
.ctl-btn:disabled { opacity: 0.45; }
/* exactly one light: the next thing to do */
.ctl-btn.ctl-next { background: #ffd200; border-color: #ffd200; color: #101010; font-size: 1.15rem; opacity: 1; }
.ctl-bad { margin: 12px 0; padding: 10px; border-radius: 10px; border-left: 3px solid #ff6b6b; background: #241010; color: #ffb3b3; font-size: 0.9rem; }
.ctl-status { margin: 12px 0 0; color: #8f8f8f; font-size: 0.85rem; text-align: center; }
/* START QUIZ: the only thing on the page before the night begins, and unmissable. */
/* WHICH QUIZ, AND WHERE TO START: two selects, on the one screen he opens at 19:00. */
.ctl-pick { display: grid; gap: 6px; margin: 18px 0 6px; }
.ctl-pick label { color: #8f8f8f; font-size: 0.8rem; letter-spacing: 0.04em; text-transform: uppercase; }
.ctl-pick select {
  width: 100%; min-height: 50px; border-radius: 12px; border: 1px solid #3a3a3a; background: #141414;
  color: #f0f0f0; font-size: 1rem; padding: 0 10px;
}
.ctl-start {
  display: block; width: 100%; min-height: 140px; margin: 26px 0 10px; border-radius: 20px; border: 0;
  background: #ffd200; color: #101010; font-size: 1.7rem; font-weight: 800; letter-spacing: 0.06em;
}
.ctl-start:disabled { opacity: 0.7; }
.ctl-banner { margin: 0 0 10px; padding: 10px; border-radius: 10px; background: #241a10; border-left: 3px solid #ffa640; color: #ffa640; font-weight: 700; }
/* END ROUND / END NIGHT / PRIZE GIVING: his run sheet's last three actions, small and out of the way. */
.ctl-ends { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 14px; }
.ctl-small { min-height: 56px; border-radius: 12px; border: 1px solid #3a3a3a; background: #141414; color: #cfcfcf; font-size: 0.82rem; font-weight: 700; letter-spacing: 0.03em; }
.ctl-small.on { border-color: #ffd200; color: #ffd200; }
.ctl-under { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ctl-skip { width: 100%; margin-top: 12px; padding: 10px; border-radius: 10px; border: 1px solid #6a4a2a; background: #241a10; color: #ffa640; font-size: 0.9rem; }

/* THE NIGHT VIEW: the stage is the question, one button and Skip; everything else is the workshop and is
   display:none until he asks for it. */
.host-hidden { display: none !important; }
.host-clean-toggle { margin: 6px 0 9px; padding: 7px 10px; border-radius: 999px; border: 1px solid #3a4a48; background: #0f1a18; color: #7fd6c8; font-size: 0.85rem; }
.host-where { margin: 2px 0 10px; color: #ffd200; font-weight: 700; letter-spacing: 0.04em; font-size: 0.95rem; }
.rehearsal-tag { margin: 8px 0; padding: 8px 10px; border-left: 3px solid #ffa640; background: #241a10; color: #ffa640; font-size: 0.9rem; font-weight: 700; }
.host-note { margin: 8px 0; padding: 8px 10px; border-left: 3px solid #7fd6c8; background: #101a18; color: #cfe9e3; font-size: 0.9rem; }
.host-source { margin: 10px 0 2px; font-size: 0.9rem; color: #7fd6c8; word-break: break-all; }
.host-source a { color: #7fd6c8; }
.host-quote { margin: 2px 0 8px; font-size: 0.9rem; color: #cfcfcf; font-style: italic; }
.host-choices {margin: 0; padding-left: 1.3rem; font-size: 1.05rem; }
.host-choices li { margin: 4px 0; }
.host-choices li.answer { color: #7ee081; font-weight: 700; }
.host-diff { color: #8f8f8f; font-size: 0.85rem; margin: 8px 0 0; }
.host-say {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-left: 3px solid #ff7a1a;
  background: #161616;
  font-size: 0.95rem;
}

/* The advance button. Thumb-sized, full width, and it never moves while he is talking. */
.host-advance {
  position: sticky;
  bottom: 0;
  z-index: 6;
  padding: 12px 0 16px;
  background: linear-gradient(180deg, rgba(13, 13, 13, 0) 0%, #0d0d0d 35%);
}
.host-advance .host-big {
  width: 100%;
  min-height: 64px;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  border-radius: 12px;
}
.host-advance .host-scores {
  margin: 10px 0 0;
  text-align: center;
  color: #b9b9b9;
  font-size: 0.9rem;
}

/* On a laptop the same layout still works, it just stops shouting. */
@media (min-width: 760px) {
  .host-advance .host-big { min-height: 48px; font-size: 1rem; }
  .host-card h3 { font-size: 1.1rem; }
}

/* The base sheet caps the reading column at 700px, which is right for a phone in someone's hand and
   completely wrong for a room screen: it held the whole layout to 700px of a 1902px TV and wrapped
   the board head word by word. The screen uses the whole screen. */
body[data-role="screen"] main#view { max-width: none; width: 100%; margin: 0; padding: 0; }

/* THE ROOM SCREEN.
   ----------------------------------------------------------------------------------------------------
   He showed me a photograph of his television (2026-10-27) with the browser at 33% and at 67%: at 33%
   everything was miniature; at 67% the sentences were readable but the PICTURE WAS CUT. Zoom was his
   workaround for a layout written for a 1920 television, and it should never be needed.

   So this is sized in VIEWPORT units throughout - vw for type, vh for the picture and the QR - which means
   the same page fills a 1366 laptop, a 1920 television and a projector, at 100% zoom, with nothing clipped:
     - every type size has a floor and a ceiling so it reads from the back of a room and cannot overflow;
     - the picture is capped by BOTH height and width, and uses object-fit: contain, so a tall or wide
       image shrinks instead of being sliced;
     - the QR is more than twice the size it was;
     - the question takes the slack; the scoreboard always keeps its space.
   Gold is the leader. One colour, one meaning. */
body[data-role="screen"] { margin: 0; padding: 0; height: 100%; overflow: hidden; background: #0c0c0c; }
body[data-role="screen"] #flash { display: none; }
.screen-wrap {
  display: grid;
  grid-template-columns: minmax(18rem, 29%) 1fr;   /* his ask, 2026-11-01: the join column earns the space for a massive QR */
  /* THE FIT (his report, 2026-10-28: "The TV screen does not fit in the screen"). Measured on a
     1920x1080 television: this element was 16px too wide and 32px too tall, so every TV cropped the
     bottom and right edge. Cause: 100vw/100vh PLUS padding, counted on top of each other. Now the box
     includes its own padding, the width is 100% rather than 100vw (100vw counts the scrollbar), the
     height uses dvh where the browser knows it, and nothing inside is allowed to push the page past the
     glass - the rows shrink instead. Verified by measuring the rendered page, not by eye. */
  box-sizing: border-box;
  gap: 1.8vmin;
  padding: 1.8vmin 2.2vmin;
  height: 100vh;
  height: 100dvh;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
  box-sizing: border-box;
  overflow: hidden;
}
.screen-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.6vmin;
  border-right: 1px solid #262626;
  padding-right: 1.4vmin;
  text-align: center;
  min-height: 0;
}
/* THE NAME on the television: an eyebrow line and the app name under it, sized so "SMARTPHONE QUIZ" fits the
   join column on a 1366 screen without breaking a word. */
.screen-who { margin: 0; color: #ffd200; font-weight: 800; letter-spacing: 0.14em; font-size: clamp(0.9rem, 1.5vw, 2rem); }
.screen-brand h1 { font-size: clamp(1.3rem, 2.5vw, 3.6rem); }
/* THE VENUE CLOCK: big, on the join panel, readable from a table. Tabular figures so it does not jitter. */
.screen-now {
  margin: 0; font-size: clamp(2rem, 4.6vw, 6rem); font-weight: 800; letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums; color: #fff; line-height: 1;
}
/* HIS BADGE: the first thing the room sees. Sized against the screen, like everything else on this page. */
.screen-badge { width: min(17vh, 13vw); height: auto; display: block; }
/* THE APP'S NAME ON A PHONE. It is a long name, so it gets its own size and two sensible lines rather than
   the single-word treatment the old heading had. */
.join-name { font-size: 1.35rem; line-height: 1.18; letter-spacing: 0.02em; text-align: center; margin: 0 0 14px; }
.join-badge { display: block; width: 108px; height: auto; margin: 0 auto 10px; }
.screen-presents { margin: 0; color: #7fd6c8; letter-spacing: 0.18em; text-transform: uppercase; font-size: clamp(0.8rem, 1.15vw, 1.6rem); }
/* MEASURED ON A 1920x1080 TELEVISION (2026-10-28, mid-show): at this size "SMARTPHONE" was wider than the
   join column, so the first letters hung off the left edge, and the scan line fell off the bottom. The
   column now spaces its items instead of centring a too-tall stack, and every size below is in vmin - it
   scales with the SHORTER side of the screen, which is what actually runs out on a television. */
.screen-brand { justify-content: space-evenly; gap: 1.1vmin; overflow: hidden; }
.screen-brand h1 {
  margin: 0; max-width: 100%; font-size: clamp(1.1rem, 2.7vmin, 2.9rem); line-height: 1.05;
  letter-spacing: 0.02em; overflow-wrap: anywhere;
}
.screen-now { font-size: clamp(1.5rem, 6vmin, 5rem); }
.screen-badge { width: min(13vh, 12vmin); }
.screen-presents { font-size: clamp(0.6rem, 1.2vmin, 1.15rem); letter-spacing: 0.16em; }
.screen-who { font-size: clamp(0.7rem, 1.6vmin, 1.35rem); letter-spacing: 0.1em; }
.screen-qr canvas { width: min(28vh, 24vw); min-width: 140px; }
.screen-url { font-size: clamp(0.6rem, 1.15vmin, 1.15rem); }
.screen-scan { font-size: clamp(0.68rem, 1.4vmin, 1.4rem); }
/* THE QR CODE, BIG. It was 170-250px; it now takes the whole width of the join column, and the column
   itself grew, because the code is the only way a phone joins and it has to be scannable from the back
   of a room. Two older rules were fighting over this - both removed, this is the only one. */
.screen-qr { background: #fff; padding: 1.2vmin; border-radius: 1.4vmin; line-height: 0; width: 100%; }
/* capped by HEIGHT as well as width: a code that fills a phone-shaped column would push the join URL and
   the scan line off the bottom of a 16:9 television, which is exactly what the clipping showed. 44vh keeps
   the code enormous and still leaves room for the words underneath. */
.screen-qr canvas { display: block; width: min(100%, 44vh); height: auto; margin: 0 auto; }
.screen-url { margin: 0; font-size: clamp(0.85rem, 1.25vw, 1.7rem); color: #d8d8d8; word-break: break-all; font-weight: 700; }
.screen-scan { margin: 0; color: #ffa640; font-size: clamp(1rem, 1.55vw, 2.1rem); font-weight: 700; line-height: 1.12; }

/* The question takes the slack; the board never loses its space. */
.screen-main { display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 1.4vmin; min-height: 0; overflow: hidden; }
.screen-question {
  border: 1px solid #333; border-radius: 1.6vmin; padding: 2vmin 2.4vmin;
  min-height: 0; overflow: hidden; display: flex; flex-direction: column;
}
/* THE QUESTION ROW: picture top right, the question beside it, the choices underneath. */
.screen-top { display: flex; align-items: flex-start; gap: 2vmin; min-height: 0; flex: 0 0 auto; }
.screen-top h2 {
  flex: 1 1 auto; min-width: 0; margin: 0 0 1.6vmin;
  font-size: clamp(1.7rem, 3.1vw, 4.4rem); line-height: 1.12; letter-spacing: 0.005em;
}
/* CONTAIN, NOT COVER, AND CAPPED BOTH WAYS: the thing he saw cut off can now only get smaller. */
.screen-pic { flex: 0 0 auto; max-width: 30%; }
.screen-pic img {
  display: block; width: auto; height: auto; max-width: 100%; max-height: 32vh;
  object-fit: contain; border-radius: 1.2vmin; border: 1px solid #333; background: #111;
}
.screen-credit { margin: 0.6vmin 0 0; color: #8a8a8a; font-size: clamp(0.6rem, 0.8vw, 1rem); text-align: right; }
.screen-choices {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 1.1vmin 3vmin;
  font-size: clamp(1.3rem, 2.35vw, 3.2rem); line-height: 1.15;
}
.screen-clock { margin: 1.4vmin 0 0; color: #ffa640; font-size: clamp(1.2rem, 1.9vw, 2.6rem); font-weight: 700; }
.screen-answer { margin: 1vmin 0 0.4vmin; color: #7ee081; font-weight: 700; font-size: clamp(1.4rem, 2.5vw, 3.4rem); }
.screen-right { margin: 0.6vmin 0 0; color: #cfcfcf; font-size: clamp(1rem, 1.6vw, 2.1rem); }

/* PRACTICE: unmistakable, because the room must not think these three cost them points. */
.screen-practice {
  margin: 0; padding: 0.6vmin 1.4vmin; border-radius: 1vmin; align-self: flex-start;
  background: #241a10; border: 1px solid #ffa640; color: #ffa640;
  font-size: clamp(1rem, 1.6vw, 2.2rem); font-weight: 800; letter-spacing: 0.08em;
}
/* THE BANNER: END OF ROUND / FINAL SCORES / PRIZE GIVING. */
.screen-banner { border: 2px solid #ffd200; border-radius: 1.6vmin; padding: 1.6vmin 2vmin; background: #16120a; }
.screen-banner p { margin: 0; color: #ffd200; font-size: clamp(1.6rem, 3vw, 4.2rem); font-weight: 800; letter-spacing: 0.06em; }
.screen-banner-line { margin-top: 0.8vmin !important; color: #fff !important; font-size: clamp(1.3rem, 2.3vw, 3.2rem) !important; letter-spacing: 0.02em !important; }
.screen-banner.prize { border-color: #7ee081; background: #0f1a12; }
.screen-banner.prize p { color: #7ee081; }

/* THE BOARD: the room reads names and points, so they are big too. */
.screen-board { border-top: 2px solid #262626; padding-top: 1.2vmin; max-height: 42vh; overflow: hidden; }
.screen-board-head { display: flex; align-items: baseline; gap: 1.6vmin; margin-bottom: 0.8vmin; }
.screen-board-title { color: #ffd200; font-weight: 800; letter-spacing: 0.12em; font-size: clamp(1.2rem, 1.8vw, 2.4rem); }
.screen-board-date { color: #9a9a9a; font-size: clamp(0.85rem, 1.15vw, 1.5rem); }
.screen-live { margin-left: auto; color: #4a4a4a; font-weight: 800; letter-spacing: 0.1em; font-size: clamp(0.9rem, 1.2vw, 1.6rem); }
.screen-live.on { color: #35d07f; animation: livepulse 1.2s ease-in-out infinite; }
.screen-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 3vmin; }
.screen-cols.three { grid-template-columns: 1fr 1fr 1fr; }
.screen-col { list-style: none; margin: 0; padding: 0; }
.screen-cols .row {
  display: grid;
  grid-template-columns: 2.6em 1fr auto;
  align-items: baseline;
  gap: 1.2vmin;
  padding: 0.9vmin 1.2vmin;
  border-bottom: 1px solid #1f1f1f;
  /* the names and points are read from the back of the room, so they scale with the screen */
  font-size: clamp(1.05rem, 1.75vw, 2.4rem);
}
.screen-cols .rank { color: #6f6f6f; font-variant-numeric: tabular-nums; }
.screen-cols .who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.screen-cols .pts { color: #f0f0f0; font-weight: 700; font-variant-numeric: tabular-nums; }
.screen-cols .row.leader {
  background: linear-gradient(90deg, #3a2f12 0%, rgba(58, 47, 18, 0) 70%);
  border-left: 4px solid #ffd200;
  padding-left: 6px;
}
.screen-cols .row.leader .pts { color: #ffd200; }
/* The empty state is NOT a row: it carried the same class, so it inherited the three-column grid
   (2.2rem rank | name | points) and its sentence was squeezed into the 35px rank column, one word
   per line. He caught it on his own TV. A plain block, in the reading column, is what it needs. */
.screen-cols .row.empty {
  display: block;
  color: #9a9a9a;
  font-style: italic;
  padding: 12px 4px;
  border-bottom: none;
}

/* A picture in the picture round must not push the board off the screen. */
.screen-question .picture { max-height: 30vh; }

/* THE WALLPAPERS: his three cuts of the ember artwork, used at the sizes he made them for -
   desktop 3840x2160 (212 KB) for the room screen, tablet 2048x2732 portrait (179 KB) for the host
   console, mobile 1170x2532 (130 KB) for the players. No conversion needed: they arrived as webp at
   sensible weights. They carry no text and no venue mark, which is why they can be used at all - a
   venue logo in the app is the paid extra, not a default.
   Scrimmed twice: once across the whole page so the embers read as glow rather than glare, and again
   on each panel, because every word has to survive a glance from the back row. */
body[data-role="screen"] {
  background: #080808 url('/backgrounds/screen.webp') center / cover no-repeat fixed;
}
body[data-role="screen"]::before {
  content: '';
  position: fixed;
  inset: 0;
  background: linear-gradient(rgba(6, 6, 6, 0.45), rgba(6, 6, 6, 0.62));
  pointer-events: none;
  z-index: 0;
}
.screen-wrap { position: relative; z-index: 1; }
.screen-wrap > * { min-width: 0; min-height: 0; }
.screen-brand, .screen-question, .screen-board {
  background: rgba(9, 9, 9, 0.78);
  border: 1px solid #2b2b2b;
  border-radius: 16px;
  padding: 16px 18px;
}
.screen-board { border-top: 1px solid #2b2b2b; }

/* On a phone the wallpaper reads as texture only: a heavy scrim, because a question has to be
   legible in one glance, standing up, at the bar. */
body[data-role="player"] {
  background: linear-gradient(rgba(8, 8, 8, 0.88), rgba(8, 8, 8, 0.94)),
    url('/backgrounds/phone.webp') center / cover no-repeat fixed;
}
body[data-role="host"] {
  background: linear-gradient(rgba(8, 8, 8, 0.88), rgba(8, 8, 8, 0.94)),
    url('/backgrounds/host.webp') center / cover no-repeat fixed;
}

/* THE TWO PAGES THAT HAD NO WALLPAPER. Three had his ember artwork and two did not: the league table,
   and the dashboard - which was built later and shipped flat black. He spotted it by asking why the
   pages do not all look the same (2026-10-09), and he is right: it was the one page in this app that
   did not belong to the same sheet.
   The artwork stays one per SCREEN SHAPE, because that is why it exists in three sizes, and it is his
   own confirmed artwork: the league table is read on a phone, so it takes the phone one; the dashboard
   is read on his laptop, so it takes the wide one - and the phone artwork when the window is narrow,
   because the wide one is composed for a TV across a room, not for a laptop.
   Scrimmed the same way as the other pages: heavy on a phone, lighter on the laptop, and each panel
   still carries its own background so every word survives a glance. */
body[data-role="league"] {
  background: linear-gradient(rgba(8, 8, 8, 0.88), rgba(8, 8, 8, 0.94)),
    url('/backgrounds/phone.webp') center / cover no-repeat fixed;
}
body[data-role="dashboard"] {
  background: linear-gradient(rgba(8, 8, 8, 0.86), rgba(8, 8, 8, 0.93)),
    url('/backgrounds/screen.webp') center / cover no-repeat fixed;
}
body[data-role="league"] main#view, body[data-role="dashboard"] main#view {
  background: rgba(10, 10, 10, 0.68);
  border-radius: 14px;
  padding: 12px 14px;
}
@media (max-width: 620px) {
  body[data-role="dashboard"] {
    background: linear-gradient(rgba(8, 8, 8, 0.88), rgba(8, 8, 8, 0.94)),
      url('/backgrounds/phone.webp') center / cover no-repeat fixed;
  }
}
body[data-role="player"] main#view, body[data-role="host"] main#view {
  background: rgba(10, 10, 10, 0.68);
  border-radius: 14px;
  padding: 12px 14px;
}

/* QUIZ LEAGUE - the basic sheet.
 *
 * Deliberately small: colours, type, spacing, touch targets. The full mockup look (the pill
 * choices, the orange bokeh, the badge above the question) waits for the logo, because all of it
 * is built around that badge.
 *
 * Mobile first, and written for the room it is played in: a phone held in one hand, in a dark
 * venue, often by someone who has had a drink. So: one column, big type, tap targets nobody has
 * to aim at, and nothing important below the fold.
 */

/* OpenDyslexic, self-hosted. Venue wifi is the least reliable part of the night, so the readable
   type must not come from a CDN - and the phones now match the font the owner reads on his
   laptop. Two weights only; the sheet uses those two. */
@font-face {
  font-family: 'OpenDyslexic';
  src: url('/fonts/OpenDyslexic-Regular.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'OpenDyslexic';
  src: url('/fonts/OpenDyslexic-Bold.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
}

:root {
  --bg: #0c0c0c;
  --surface: #171717;
  --line: rgba(255, 255, 255, 0.14);
  --text: #fff;
  --muted: rgba(255, 255, 255, 0.62);
  --orange: #ff6a00;      /* the owner's orange, from the mockups */
  --right: #14b8a6;
  --wrong: #e5484d;
  --radius: 14px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: 'OpenDyslexic', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.5;
  padding: 16px;
  padding-top: calc(16px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: 14px;
}

main#view {
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

h1 { font-size: 1.4rem; margin: 0; }
h2 { font-size: 1.25rem; margin: 0; line-height: 1.35; }
p { margin: 0; }
ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
ol { margin: 0; padding-left: 1.3rem; }
a { color: var(--orange); }

/* the one line that tells you what just happened (a rejection, a reconnection) */
#flash { min-height: 1.2rem; margin: 0 auto; max-width: 520px; font-size: 0.8rem; color: var(--orange); }

/* Buttons are the game. Never smaller than a thumb, never a puzzle: solid orange is the thing to
   press, grey means there is nothing to do. */
button {
  font: inherit;
  font-weight: 700;
  width: 100%;
  min-height: 52px;
  padding: 12px 18px;
  color: #000;
  background: var(--orange);
  border: 2px solid var(--orange);
  border-radius: 999px;
  cursor: pointer;
  touch-action: manipulation;
}
button:disabled { background: #3a3a3a; border-color: #3a3a3a; color: rgba(255, 255, 255, 0.45); cursor: default; }
button:active:not(:disabled) { transform: scale(0.985); }

/* A choice is a dark pill with an orange rim; the one you picked fills in. The pad from the
   mockups, in four rules. */
button.choice { background: var(--bg); color: var(--text); text-align: left; }
button.choice[aria-pressed='true'] { background: var(--orange); color: #000; }

input, select {
  font: inherit;
  width: 100%;
  min-height: 48px;
  padding: 10px 12px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
}
input:focus, select:focus, button:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
label {
  display: block;
  margin-top: 8px;
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* scoreboard tables, on the host console and the season table */
table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
th, td { padding: 7px 5px; text-align: left; border-bottom: 1px solid var(--line); }
th { font-size: 0.62rem; font-weight: 400; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }

/* the countdown is the one number the whole room watches */
#clock { color: var(--orange); font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; }

/* the verdict after a reveal */
.verdict { font-weight: 700; }
.verdict.right { color: var(--right); }
.verdict.wrong { color: var(--wrong); }
.muted { color: var(--muted); font-size: 0.85rem; }

/* A laptop is a host console, not a phone: use the width for the controls and the table. */
@media (min-width: 700px) {
  body { font-size: 18px; }
  main#view { max-width: 700px; }
}

/* THE DASHBOARD. One tile per app, and every tile opens in its OWN window: this is where a night is
   set up, so it is a page of doors rather than another control panel. Two columns from 620px (his
   laptop), one on a phone, and the tiles are big enough to hit deliberately. */
.dash-grid { display: grid; grid-template-columns: 1fr; gap: 10px; margin: 0 0 20px; }
@media (min-width: 620px) { .dash-grid { grid-template-columns: 1fr 1fr; } }
.dash-tile {
  display: flex; flex-direction: column; gap: 4px; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); text-decoration: none;
}
.dash-tile:hover, .dash-tile:focus { border-color: var(--orange); }
.dash-tile strong { font-size: 1.05rem; font-weight: 600; }
.dash-tile span { color: var(--muted); font-size: 0.85rem; }
/* the dashboard uses the width of a laptop: the 700px reading column above is for a phone in a hand */
body[data-role="dashboard"] main#view { max-width: 900px; }

/* THE GENERATOR. A laptop page like the dashboard, and it wears one of his wallpapers like every other
   page (the league table and the dashboard shipped without one until he asked). A wide form at the top,
   then a table he reads down, with the verdict on each question beside it. */
body[data-role="generator"] {
  background: linear-gradient(rgba(8, 8, 8, 0.86), rgba(8, 8, 8, 0.93)),
    url('/backgrounds/screen.webp') center / cover no-repeat fixed;
}
body[data-role="generator"] main#view {
  max-width: 1040px;
  background: rgba(10, 10, 10, 0.68);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.gen-form label { display: block; font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }
.gen-form textarea, .gen-form input, .gen-form select {
  width: 100%; padding: 10px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; color: var(--text); font: inherit;
}
.gen-form textarea { resize: vertical; }
.gen-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin: 10px 0; }
@media (max-width: 620px) { .gen-grid { grid-template-columns: 1fr; } }
.gen-pill {
  display: inline-block; font-size: 0.58rem; font-weight: 700; letter-spacing: 0.08em;
  padding: 3px 8px; border-radius: 100px; border: 1px solid var(--line); color: var(--muted);
}
.gen-pill.ok { border-color: var(--right); color: var(--right); }
.gen-pill.warn { border-color: var(--orange); color: var(--orange); }
.gen-right { color: var(--right); font-weight: 700; }
.gen-bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0; }
/* the verdict reasons sit under the pill and must not stretch the column */
body[data-role="generator"] td p { margin: 4px 0 0; color: var(--muted); font-size: 0.75rem; }

/* the practice tag on the CONTROL page (it was wrongly using the TV's container) */
.ctl-practice {
  margin: 0 0 10px;
  padding: 10px 12px;
  border: 2px solid #ff6a00;
  border-radius: 10px;
  background: #1a1207;
  color: #ffb066;
  font-weight: 800;
  letter-spacing: .04em;
  text-align: center;
}
/* who was quickest during practice - no points, just the mechanism */
.screen-fastest {
  margin: 6px 0 0;
  font-size: .9rem;
  font-weight: 800;
  letter-spacing: .05em;
  color: #ffb066;
  text-align: center;
}

/* THE TWO BOARDS on the television (his ask, 2026-10-30): teams above, individuals below, each with its own
   numbering, because a team and an individual do not earn points the same way. */
.screen-board-half + .screen-board-half { margin-top: .8vmin; }
.screen-board-sub {
  margin: 0 0 .5vmin;
  font-size: clamp(.6rem, 1.15vmin, 1.1rem);
  font-weight: 800;
  letter-spacing: .16em;
  color: #9a9a9a;
  text-transform: uppercase;
}
.screen-board-sub.teams { color: #ffb066; }
.screen-board-sub.players { color: #7fd6c8; }
.row.team-row .who { color: #ffd200; }

/* the [T]/[P] tag on the host's roster: one tap flips a team to an individual or back */
.ctl-kind {
  min-width: 42px;
  min-height: 36px;
  border-radius: 8px;
  border: 1px solid #3a3a3a;
  font-weight: 800;
  letter-spacing: .06em;
}
.ctl-kind.team { background: #2a1a08; border-color: #ff6a00; color: #ffb066; }
.ctl-kind.player { background: #0e1a19; border-color: #2f6f66; color: #7fd6c8; }
.ctl-venue { display: flex; align-items: center; gap: 8px; margin: 0 0 6px; }
.ctl-venue input { width: 76px; text-transform: uppercase; letter-spacing: .12em; text-align: center; }
.ctl-venue label { color: #b9b9b9; font-weight: 700; }

/* which quiz is running, on the host's phone all night */
.ctl-packname { margin: -4px 0 10px; color: #9a9a9a; font-size: .82rem; letter-spacing: .02em; }

/* the run sheet line and the sudden-death panel on the host's phone */
.ctl-run { margin: -6px 0 8px; color: #b9b9b9; font-size: .85rem; letter-spacing: .03em; }
.ctl-run.soon { color: #ffb066; font-weight: 800; }
.ctl-run.stop { color: #ff8a5c; font-weight: 800; }
.ctl-sudden { margin: 10px 0; padding: 10px 12px; border: 2px solid #ff6a00; border-radius: 10px;
  background: #1a1207; color: #ffd200; font-weight: 800; letter-spacing: .04em; }
.ctl-sudden-btn { margin: 4px 0; }

/* the small buttons on the host's phone roster */
.ctl-mini { min-height: 34px; padding: 4px 8px; margin-right: 4px; border-radius: 8px; font-size: .72rem; }
body[data-role="control"] table { width: 100%; border-collapse: collapse; }
body[data-role="control"] td, body[data-role="control"] th { padding: 4px 6px; text-align: left; font-size: .82rem; }

/* the buttons he pushes during the night: BREAK (with an optional number of minutes), WE'RE BACK, STOP */
.ctl-night { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.ctl-night .ctl-small { flex: 1 1 auto; }
.ctl-night .ctl-break { background: #2a1a08; border-color: #ff6a00; color: #ffb066; font-weight: 800; }
.ctl-night .ctl-stop { background: #2a0f0f; border-color: #ff5c5c; color: #ffb3b3; font-weight: 800; }
.ctl-night .ctl-min { min-width: 46px; min-height: 34px; border-radius: 8px; border: 1px solid #3a3a3a;
  background: #141414; color: #9a9a9a; font-size: .72rem; }
.ctl-night .ctl-min.on { border-color: #ff6a00; color: #ffb066; background: #1a1207; }

/* THE BOTTOM OF THE HOST'S PHONE: the roster, then the break. He holds the phone in his left hand and a
   microphone in his right, so the things he reaches for least live furthest from his thumb, and the break
   row is one compact line rather than five full-width bars. */
.ctl-night {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 5px;
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid #2b2b2b;
}
.ctl-night .ctl-break { flex: 2 1 40%; min-height: 48px; background: #2a1a08; border-color: #ff6a00;
  color: #ffb066; font-weight: 800; letter-spacing: .08em; }
.ctl-night .ctl-min { flex: 0 0 auto; width: 52px; min-height: 48px; border-radius: 10px;
  border: 1px solid #3a3a3a; background: #141414; color: #9a9a9a; font-size: .8rem; font-weight: 700; }
.ctl-night .ctl-min.on { border-color: #ff6a00; color: #ffb066; background: #1a1207; }
.ctl-night .ctl-small { flex: 1 1 28%; min-height: 48px; }
.ctl-night .ctl-stop { background: #2a0f0f; border-color: #ff5c5c; color: #ffb3b3; font-weight: 800; }

/* THE QUESTION CARD on a player's phone: the brightest thing on the screen, with an orange edge so the eye
   lands on the question before anything else. His words: "could we add some colour to make it easier to READ
   the QUESTION ... the dyslexic font but it's a little too bland". */
.q-card {
  margin: 14px 0 10px;
  padding: 14px 16px;
  border-left: 5px solid #ff6a00;
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(255, 108, 1, .12), rgba(255, 108, 1, .03));
  box-shadow: 0 0 0 1px rgba(255, 108, 1, .18) inset;
}
.q-card h2 { margin: 0; color: #fff6e8; font-size: 1.45rem; line-height: 1.32; letter-spacing: .01em; }
/* before the clock: no answers yet, and it says so */
.q-waiting { margin: 4px 0 0; color: #ffb066; font-weight: 700; font-size: .95rem; }
/* the countdown, and its last five seconds */
body[data-role="player"] .clock { color: #ffb066; }
body[data-role="player"] .clock.hot { color: #ff5c5c; }

/* the countdown inside a break, big enough to read from the back */
.screen-break-left { margin: .6vmin 0 0; font-size: clamp(1.2rem, 3.4vmin, 3rem); font-weight: 800;
  letter-spacing: .06em; color: #ffb066; font-variant-numeric: tabular-nums; }

/* POOL or ROUNDS on the host's phone */
.ctl-mode { display: flex; align-items: center; gap: 6px; margin: 10px 0 6px; }
.ctl-mode-label { color: #9a9a9a; font-size: .8rem; letter-spacing: .06em; text-transform: uppercase; }
.ctl-mode-btn { flex: 1 1 auto; min-height: 40px; border-radius: 10px; border: 1px solid #3a3a3a;
  background: #141414; color: #8f8f8f; font-weight: 800; letter-spacing: .08em; font-size: .78rem; }
.ctl-mode-btn.on { border-color: #ff6a00; background: #1a1207; color: #ffb066; }

/* while a question is live the join column is gone and the question takes the whole television */
.screen-wrap.no-join { grid-template-columns: minmax(0, 1fr); }
.screen-wrap.no-join .screen-top h2 { font-size: clamp(1.6rem, 4.6vmin, 4rem); }

/* PREVIOUS sits quietly beside the three, because it is the one he reaches for by accident */
.ctl-back { min-height: 44px; }

/* the loop, two rows: the three he uses, then PREVIOUS and SKIP side by side in the space that was empty */
.ctl-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.ctl-grid .ctl-back { grid-column: 1 / span 1; }
.ctl-grid .ctl-skip-btn { grid-column: 2 / span 1; min-height: 44px; }

/* the CHANGE QUIZ button sits quietly under the pack name, full width so a thumb finds it */
.ctl-change-quiz { width: 100%; min-height: 46px; margin: 0 0 10px; }

/* THE JOIN PANEL, after his 2026-11-01 notes: the QR dominates the column, the name says welcome, and the
   promise sits under it. */
.screen-welcome {
  margin: 0; text-align: center; color: #ffd200; font-weight: 900;
  font-size: clamp(.7rem, 1.75vmin, 1.5rem); letter-spacing: .08em; line-height: 1.25;
}
.screen-tagline {
  margin: 0; text-align: center; color: #7fd6c8; letter-spacing: .12em;
  font-size: clamp(.55rem, 1.25vmin, 1.05rem); font-weight: 700;
}
/* the duplicate rule that capped the code is gone on purpose: see .screen-qr above */
.screen-url { word-break: break-all; }
/* one column of players, top to bottom */
.screen-col { column-count: 1; }

/* DID YOU KNOW - the fact under the revealed answer. It sits quieter than the answer itself: the answer
   is the news, the fact is the pleasure. Dark panel and gold text so it reads from the back of the room. */
.screen-fact {
  margin: 1.2vmin 0 0;
  padding: 1.2vmin 2vmin;
  border-left: .5vmin solid #ff6a00;
  background: rgba(255, 108, 1, .10);
  color: #ffd200;
  font-size: clamp(.8rem, 2.1vmin, 1.7rem);
  line-height: 1.35;
  text-align: left;
  font-style: italic;
}
.player-fact {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-left: 4px solid #ff6a00;
  background: #171514;
  color: #ffd200;
  font-size: .92rem;
  line-height: 1.45;
  border-radius: 0 8px 8px 0;
}

/* THE NAME, once. Small WELCOME TO over a big name - he caught the screen welcoming the room to itself. */
.screen-welcome {
  margin: 0.6vmin 0 0; text-align: center; color: #ffd200; font-weight: 900;
  font-size: clamp(.62rem, 1.55vmin, 1.35rem); letter-spacing: .18em;
}
.screen-who {
  margin: 0.2vmin 0 0.6vmin; text-align: center; color: #fff; font-weight: 900;
  font-size: clamp(.95rem, 2.6vmin, 2.4rem); letter-spacing: .06em; line-height: 1.08;
}

/* THE FACT, ON HIS CONSOLE, where he reads it aloud. Same size as the question (ctl-question is
   1.15rem at this breakpoint) because he is holding the phone at arm's length in a loud room, and gold on
   a dark panel so it never gets confused with the question itself. */
.ctl-fact {
  margin: 10px 0 4px;
  padding: 12px 14px;
  border-left: 5px solid var(--orange, #ff6a00);
  background: rgba(255, 106, 0, .12);
  color: #ffd200;
  font-size: 1.15rem;
  line-height: 1.42;
  font-weight: 700;
  border-radius: 0 10px 10px 0;
}

/* HE ASKS FOR ATTENTION TO LAND ON THE QUESTION, NOT ON LOG OUT (2026-11-01: "I like the bright colour of
   the LOG OUT but I would prefer the Attention drawn to Questions and Answers... The LOG OUT can be plain").
   So it becomes a quiet text button: still there, still tappable, no longer the loudest thing on the screen. */
.player-logout {
  background: transparent;
  color: #9a9a9a;
  border: 1px solid #3a3a3a;
  font-weight: 400;
  font-size: .8rem;
  min-height: 34px;
  padding: 4px 12px;
  width: auto;
  border-radius: 8px;
  margin: 2px 0 6px;
}
.player-logout:hover { color: #e6e6e6; border-color: #6a6a6a; }

/* and the question itself takes the weight: a brighter card, a thicker edge, so the eye lands here first */
.q-card {
  border: 2px solid rgba(255, 106, 0, .55) !important;
  box-shadow: 0 0 0 1px rgba(255, 106, 0, .18), 0 10px 30px rgba(0, 0, 0, .45);
}

/* THE DOOR, BIG AND CENTRED (his ask, 2026-11-01). While the room is arriving there is no question, so the
   whole middle of the television belongs to the way in. It disappears the moment a question goes up. */
.screen-join-stage {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1.6vmin; padding: 2vmin; min-height: 0; overflow: hidden; text-align: center;
}
.screen-join-title {
  margin: 0; color: #fff; font-weight: 900; letter-spacing: .16em;
  font-size: clamp(.9rem, 2.6vmin, 2.4rem);
}
.screen-join-qr { background: #fff; padding: 1.4vmin; border-radius: 1.6vmin; line-height: 0; }
.screen-join-qr canvas { display: block; width: min(56vh, 46vw); height: auto; }
.screen-join-url {
  margin: 0; color: #ffd200; font-weight: 900; letter-spacing: .04em;
  font-size: clamp(.85rem, 2.2vmin, 2rem); word-break: break-all;
}
.screen-join-scan {
  margin: 0; color: rgba(255,255,255,.72); font-size: clamp(.7rem, 1.6vmin, 1.4rem);
}

/* =====================================================================================
   THE PLAYER SCREEN, AS THE CROSSBAR ADVERT SHOWS IT (his brief, 2026-11-01: "LOOK AT THE PHONE IN
   THE ADVERT"). Sampled from his own artwork, not guessed: violet field, navy card, light violet
   outlines, yellow question mark, and the chosen answer filled hot orange with a glow.

   Player only - the television keeps its own black-and-orange look, because a television in a dark
   room wants black and a phone in a bright room wants this.
   ===================================================================================== */
body[data-role="player"] {
  --qs-bg-top: #4a1fa0;
  --qs-bg-bottom: #2c1269;
  --qs-card: #0d1233;
  --qs-outline: #8b7bff;
  --qs-yellow: #ffd200;
  --qs-green: #7ee35a;
  background: linear-gradient(160deg, var(--qs-bg-top) 0%, var(--qs-bg-bottom) 55%, #1d0a4a 100%);
  background-attachment: fixed;
  color: #fff;
  padding: 14px 14px calc(24px + env(safe-area-inset-bottom, 0px));
  gap: 12px;
}

/* the top line: the app name on the left, the countdown ring on the right */
body[data-role="player"] #who,
body[data-role="player"] h1,
body[data-role="player"] .name-line {
  color: #fff;
  font-weight: 900;
  letter-spacing: .02em;
  text-shadow: 0 2px 8px rgba(0, 0, 0, .5);
}
body[data-role="player"] #who { font-size: 1.05rem; }

/* THE QUESTION CARD: navy, deeply rounded, with the yellow question mark the advert has */
body[data-role="player"] .q-card {
  position: relative;
  background: var(--qs-card);
  border: 1px solid #2b2f63;
  border-radius: 22px;
  padding: 16px 16px 16px 62px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .55);
}
body[data-role="player"] .q-card::before {
  content: "?";
  position: absolute;
  left: 14px;
  top: 10px;
  color: var(--qs-yellow);
  font-size: 2.6rem;
  line-height: 1;
  font-weight: 900;
  text-shadow: 0 3px 0 rgba(0, 0, 0, .35);
}
body[data-role="player"] .q-card h2 {
  font-size: 1.18rem;
  line-height: 1.35;
  font-weight: 900;
  margin: 0;
}

/* THE ANSWERS: full width pills with a light violet outline, exactly as drawn on the poster */
body[data-role="player"] .choice {
  width: 100%;
  min-height: 60px;
  padding: 14px 18px;
  border-radius: 18px;
  background: var(--qs-card);
  border: 2px solid var(--qs-outline);
  color: #fff;
  font-weight: 900;
  font-size: 1.05rem;
  letter-spacing: .01em;
  box-shadow: none;
}
body[data-role="player"] .choice[aria-pressed="true"] {
  background: #ff6a00;
  border-color: #ff8a2b;
  color: #fff;
  box-shadow: 0 0 0 3px rgba(255, 106, 0, .35), 0 10px 26px rgba(255, 106, 0, .45);
}
body[data-role="player"] .choice:disabled { opacity: .55; }
/* the reveal: the right answer glows green, the wrong pick stays outlined */
body[data-role="player"] .choice.right,
body[data-role="player"] .choice.correct {
  background: #12631f;
  border-color: var(--qs-green);
  color: #fff;
  box-shadow: 0 0 0 3px rgba(126, 227, 90, .30);
}

/* THE COUNTDOWN RING, as on the poster: a green arc on a dark ring, the seconds white in the middle */
body[data-role="player"] #clock {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  margin: 0;
  border-radius: 50%;
  font-weight: 900;
  font-size: 1.02rem;
  color: #fff;
  background:
    conic-gradient(var(--qs-green) calc(var(--pct, 1) * 360deg), rgba(255, 255, 255, .10) 0);
  box-shadow: inset 0 0 0 6px var(--qs-card), 0 6px 18px rgba(0, 0, 0, .45);
}

/* the quiet line that used to shout (his note: attention on questions and answers) */
body[data-role="player"] .q-waiting,
body[data-role="player"] .q-paused {
  color: rgba(255, 255, 255, .72);
  font-size: .86rem;
}

/* the small print at the bottom */
body[data-role="player"] .player-logout {
  color: rgba(255, 255, 255, .55);
  border-color: rgba(255, 255, 255, .22);
}

/* =====================================================================================
   HIS OWN BACKDROP (2026-11-01). The line-art quiz icons on near-black that he made for the app
   before we ever spoke: bulb, trophy, music note, dice, puzzle, clipboard, target. It is used as a
   proper background layer with a dark veil over it, because the question has to win the eye - the
   artwork sets the mood, it does not compete with the words.
   29 KB for the phone, 19 KB for the TV.
   ===================================================================================== */
body[data-role="player"]::before,
body[data-role="control"]::before,
body[data-role="host"]::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background: url('/images/bg-phone.webp') center / cover no-repeat;
  opacity: .9;
}
body[data-role="player"]::after,
body[data-role="control"]::after,
body[data-role="host"]::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  /* the veil: violet at the top, black at the bottom, so text always has something to sit on */
  background: linear-gradient(180deg, rgba(40, 12, 96, .55) 0%, rgba(8, 4, 22, .82) 60%, rgba(0, 0, 0, .92) 100%);
}

/* the television keeps the same art, darker still, because it is watched across a room */
body[data-role="screen"] {
  background: #050505 url('/images/bg-tv.webp') center / cover no-repeat fixed;
}
body[data-role="screen"] .screen-wrap::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  /* HE SAID THE TELEVISION WAS TOO DARK (2026-11-02) and the pictures were the casualty: the veil was
     killing contrast on the very thing the room looks at. Lighter, and never over a picture. */
  background: radial-gradient(ellipse at center, rgba(0,0,0,.18) 0%, rgba(0,0,0,.45) 80%);
  pointer-events: none;
}

/* the door sits at the top of the main column while the room arrives, above the scoreboard */
.screen-join-stage { order: -1; }
/* and it must not be dimmed: the vignette was washing the code out in his screenshot */
.screen-join-qr { box-shadow: 0 0 0 2vmin rgba(255, 255, 255, .06); }
.screen-join-stage, .screen-join-qr { opacity: 1; }

/* the picture gets its own brightness back: no veil, a clear border, and a touch of lift so it reads
   across a dark room */
.screen-pic, .screen-pic img.picture {
  filter: brightness(1.06) contrast(1.04);
}
.screen-pic { background: #000; border-radius: 1.2vmin; }

/* =====================================================================================
   THE STANDINGS WINDOW (/scoreboard). He sizes this window himself next to the question
   screen, so it fills whatever it is given and holds ten of each, top down.
   ===================================================================================== */
.sb-wrap { padding: 2vmin 2.4vmin; height: 100%; display: flex; flex-direction: column; gap: 1.6vmin; }
.sb-head { display: flex; align-items: baseline; justify-content: space-between; }
.sb-title { color: #ffd200; font-weight: 900; letter-spacing: .1em; font-size: clamp(1rem, 2.6vmin, 2.2rem); }
.sb-when { color: rgba(255,255,255,.5); font-size: clamp(.7rem, 1.5vmin, 1.1rem); letter-spacing: .08em; }
.sb-half { display: flex; flex-direction: column; gap: .5vmin; min-height: 0; }
.sb-label {
  margin: 0; font-size: clamp(.7rem, 1.6vmin, 1.2rem); letter-spacing: .16em;
  color: #ff6a00; font-weight: 900; text-transform: uppercase;
}
.sb-label.teams { color: #7fd6c8; }
.sb-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .4vmin; }
.sb-row {
  display: grid; grid-template-columns: 2.2em 1fr auto; align-items: baseline; gap: 1.2vmin;
  background: #141414; border: 1px solid #2a2a2a; border-radius: 1vmin;
  padding: .7vmin 1.2vmin; font-size: clamp(.9rem, 2.2vmin, 1.9rem);
}
.sb-rank { color: rgba(255,255,255,.45); font-weight: 900; }
.sb-who { color: #fff; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sb-pts { color: #ffd200; font-weight: 900; }
.sb-leader { border-color: #ff6a00; background: rgba(255,106,0,.12); }
.sb-leader .sb-pts { color: #fff; }
.sb-empty { color: rgba(255,255,255,.4); margin: 0 0 .6vmin; font-size: clamp(.75rem, 1.7vmin, 1.3rem); }

/* HIS PRACTICE SWITCH: unmistakable on or off, because the whole night scores or does not score by it */
.ctl-practice {
  width: 100%; min-height: 54px; border-radius: 14px; font-weight: 900; letter-spacing: .1em;
  border: 2px solid #ff6a00; background: transparent; color: #ff6a00; margin: 6px 0 10px;
}
.ctl-practice.on { background: #ff6a00; color: #000; border-color: #ff6a00; }

/* with no scoreboard on this screen, the question takes the whole glass: the join column is only needed
   while the room is arriving, and the big centred door already carries the code there */
.screen-wrap { grid-template-columns: minmax(14rem, 20%) 1fr; }
@media (min-aspect-ratio: 16/10) {
  .screen-wrap { grid-template-columns: minmax(14rem, 18%) 1fr; }
}

/* =====================================================================================
   THE TELEVISION IS ONE PAGE WITH THREE COLUMNS (his constraint, 2026-11-02: the venue TVs have
   browsers that will not run two windows side by side). Left: clock, badge, name. Middle: the door
   or the question. Right: the live standings. And his wallpaper underneath all of it.
   ===================================================================================== */
.screen-wrap {
  grid-template-columns: minmax(12rem, 17%) minmax(0, 1fr) minmax(14rem, 26%);
}
.screen-standings {
  display: flex; flex-direction: column; gap: 1vmin; min-height: 0; overflow: hidden;
  border-left: 1px solid rgba(255, 255, 255, .12); padding-left: 1.4vmin;
}
.screen-standings .sb-title { font-size: clamp(.7rem, 1.9vmin, 1.6rem); }
.screen-standings .sb-when { font-size: clamp(.55rem, 1.2vmin, .9rem); }
.screen-standings .sb-row { font-size: clamp(.7rem, 1.8vmin, 1.6rem); padding: .5vmin 1vmin; }
.screen-standings .sb-label, .screen-standings .sb-empty { font-size: clamp(.6rem, 1.35vmin, 1rem); }

/* THE WALLPAPER, on the room screen and on the standalone standings window: he made it and it belongs on
   the television. Kept dark behind the veil so the question still wins the eye. */
body[data-role="screen"],
body[data-role="scoreboard"] {
  background: #050505 url('/images/bg-tv.webp') center / cover no-repeat fixed;
}
body[data-role="scoreboard"] .sb-wrap {
  background: rgba(0, 0, 0, .55);
  border-radius: 2vmin;
  margin: 1.6vmin;
  height: calc(100% - 3.2vmin);
}

/* the where-am-I strip on his console: clock, round, question number, in one line that never scrolls away */
.ctl-where {
  position: sticky; top: 0; z-index: 6;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 8px 4px; margin: 0 0 8px;
  background: rgba(10, 6, 28, .92); border-bottom: 1px solid rgba(139, 123, 255, .35);
  backdrop-filter: blur(6px);
}
.ctl-where-clock { font-weight: 900; font-size: 1.05rem; color: #fff; letter-spacing: .04em; }
.ctl-where-round {
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: #ffd200; font-weight: 800; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ctl-where-pos { font-size: .78rem; font-weight: 900; color: #7fd6c8; letter-spacing: .06em; }

/* THE TV SPLIT HE ASKED FOR: 28% standings, the rest to the question */
.screen-wrap { grid-template-columns: minmax(11rem, 16%) minmax(0, 1fr) minmax(16rem, 28%) !important; }

/* everything fits the glass: no overflow, no scroll, on any TV shape */
html, body[data-role="screen"] { overflow: hidden; }
.screen-wrap { overflow: hidden; }
.screen-standings { overflow: hidden; }
.screen-standings .sb-list { overflow: hidden; }

/* his branded code fills the door: sharp at any television size, because it is an SVG */
.screen-join-qr-img { display: block; width: min(56vh, 46vw); height: auto; border-radius: 1.2vmin; }

/* =====================================================================================
   THE MEASURED SPLIT (Meta's read of his own 1080p screenshot, 2026-11-02): the standings take
   about 27% of the width, everything else is the quiz. Against 1920x1080 that is roughly
   16% sidebar (307px) + 56% question (1075px) + 27% standings (518px), with the gaps inside
   the 100%. Sizes are relative so the same split holds on 1280x720 and 4K.
   Overscan guard: 2.4vmin of padding all round, because those panels crop the edges.
   ===================================================================================== */
.screen-wrap {
  grid-template-columns: minmax(10rem, 16%) minmax(0, 1fr) minmax(15rem, 27%) !important;
  gap: 1.2vmin;
  padding: 2.4vmin;
}
/* the standings column must be able to shrink below its content, or a long name pushes the grid wide */
.screen-standings { min-width: 0; }
.screen-standings .sb-who { min-width: 0; }

/* the code must fit INSIDE its column, or it overflows its grid cell and gets clipped at the screen edge
   (his screenshot 2026-11-02 showed the QR cut off on the right) */
.screen-join-qr { max-width: 100%; }
.screen-join-qr-img { width: min(50vh, 100%); max-width: 100%; height: auto; }
.screen-join-qr canvas { max-width: 100%; }

/* =====================================================================================
   THE STANDINGS RAIL - done in CSS, not by rearranging the render function.
   His screenshot (2026-11-02) showed the standings landing in the MIDDLE column and the QR
   pushed off the right edge, because the block is appended to the page rather than to the grid.
   Rather than surgery inside renderScreen at midnight, the standings are pinned to the right
   as a rail and the grid is told to leave that width free. Deterministic, and it cannot
   reorder itself again.
   ===================================================================================== */
.screen-wrap { padding-right: calc(27% + 3vmin) !important; }
.screen-standings {
  position: fixed;
  top: 0;
  right: 0;
  width: 27%;
  height: 100%;
  padding: 2.4vmin 2vmin;
  box-sizing: border-box;
  background: rgba(0, 0, 0, .55);
  border-left: 2px solid rgba(255, 108, 0, .55);
  z-index: 3;
  overflow: hidden;
}
/* the layout inside the wrap is back to TWO columns: panel and question. The rail is the third. */
.screen-wrap { grid-template-columns: minmax(10rem, 18%) minmax(0, 1fr) !important; }
/* and the code must never overflow its cell */
.screen-join-qr-img { width: min(46vh, 100%); max-width: 100%; }
.screen-join-qr { max-width: 100%; }

/* =====================================================================================
   ONE LOOK, EVERY PAGE (his demand, 2026-11-02: "EVERY PAGE, WINDOW, APP MUST ALL HAVE THE
   SAME CSS... WHY ARE YOU USING 3 DIFFERENT CSS, ON THE SAME DOMAIN").
   He was right about the symptom. Every page already loads this one file, but each role had its
   own colour block, so they looked like three different products. Now every role shares the SAME
   violet field and the SAME wallpaper he painted. Only the layout differs.
   ===================================================================================== */
body[data-role="control"],
body[data-role="host"],
body[data-role="dashboard"],
body[data-role="league"],
body[data-role="generator"],
body[data-role="logs"],
body[data-role="player"],
body[data-role="v2r"] {
  background: linear-gradient(160deg, #4a1fa0 0%, #2c1269 55%, #1d0a4a 100%) fixed;
  color: #fff;
}
/* the artwork behind all of them, with the same veil, so no page looks like a different app */
body[data-role="control"]::before,
body[data-role="host"]::before,
body[data-role="dashboard"]::before,
body[data-role="logs"]::before,
body[data-role="player"]::before {
  content: "";
  position: fixed; inset: 0; z-index: -2;
  background: url('/images/bg-phone.webp') center / cover no-repeat;
  opacity: .9;
}
body[data-role="control"]::after,
body[data-role="host"]::after,
body[data-role="dashboard"]::after,
body[data-role="logs"]::after,
body[data-role="player"]::after {
  content: "";
  position: fixed; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(40, 12, 96, .5) 0%, rgba(8, 4, 22, .78) 60%, rgba(0, 0, 0, .9) 100%);
}
/* the television keeps the wide artwork, but the same violet mood under it */
body[data-role="screen"],
body[data-role="scoreboard"] {
  background-color: #1d0a4a;
}
/* one type scale, one accent, one button shape, on every role */
body[data-role] { font-family: 'OpenDyslexic', system-ui, -apple-system, 'Segoe UI', sans-serif; }
body[data-role] button, body[data-role] .btn {
  border-radius: 14px;
  font-weight: 900;
  letter-spacing: .04em;
}

/* THE FRAME MUST HUG THE CODE (his screenshot 2026-11-02: the white board was twice the width of the QR,
   so his orange code sat in the left half of an empty white box). The box takes the size of the code,
   the code fills the box, and both are square because a QR is square. */
.screen-join-qr {
  width: min(48vh, 100%) !important;
  max-width: 100%;
  padding: 1.4vmin !important;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
}
.screen-join-qr-img {
  display: block;
  width: 100% !important;
  height: 100% !important;
  object-fit: contain;
  border-radius: .8vmin;
}
.screen-join-qr canvas { width: 100% !important; height: auto !important; display: block; }

/* HIS OWN TV BACKGROUNDS (2026-11-02). pre_quiz_purple_orange while the room arrives, and the quieter
   in_quiz_purple behind the questions. Both 1920x1080, both under 65 KB, both drawn by him. */
body[data-role="screen"] {
  background: #12053a url('/images/tv-join.webp') center / cover no-repeat fixed;
}
/* and the step-by-step way in, on the left panel, readable from a few metres away */
.screen-steps { text-align: left; margin: .4vmin 0 0; }
.screen-steps-head {
  margin: 0 0 .6vmin; text-align: center; color: #ffd200; font-weight: 900;
  letter-spacing: .14em; font-size: clamp(.6rem, 1.5vmin, 1.15rem);
}
.screen-steps-list {
  margin: 0; padding-left: 1.5em; color: rgba(255, 255, 255, .86);
  font-size: clamp(.55rem, 1.3vmin, 1rem); line-height: 1.35;
}
.screen-steps-list li { margin: 0 0 .5vmin; }

/* BRIGHTNESS FOR A TELEVISION (his report 2026-11-02). Panels lose the dark end badly, so the veil that
   protected the text now sits at a fraction of what it was, and the artwork is lifted instead. */
body[data-role="screen"] .screen-wrap::before { background: rgba(0, 0, 0, .16); }
body[data-role="screen"] { filter: saturate(1.06) brightness(1.04); }
/* the code on the bright field: a white plate so it reads from the far side of a room */
.screen-join-stage { display: flex; align-items: center; justify-content: center; height: 100%; }
.screen-join-qr {
  width: min(62vh, 40vw) !important; aspect-ratio: 1 / 1; background: #fff;
  padding: 1.6vmin !important; border-radius: 2vmin; box-shadow: 0 0 6vmin rgba(255, 255, 255, .18);
}
.screen-join-qr-img { width: 100% !important; height: 100% !important; object-fit: contain; }

/* =====================================================================================
   THE DOOR, AS HE SKETCHED IT (2026-11-02): the name SPLIT around his code.
   DJ GRAHAM'S above it, QUIZ below it, both big, bold and centred - so the code sits inside the
   title instead of beside it. The left panel also earned width: his four scan steps were wrapping
   on every line and looked cramped.
   ===================================================================================== */
.screen-wrap { grid-template-columns: minmax(15rem, 22%) minmax(0, 1fr) !important; }
.screen-brand-top, .screen-brand-bottom {
  margin: 0; text-align: center; color: #fff; font-weight: 900; letter-spacing: .1em;
  text-shadow: 0 4px 18px rgba(0, 0, 0, .65);
  line-height: 1;
}
.screen-brand-top { font-size: clamp(1.1rem, 4.2vmin, 3.4rem); margin-bottom: 1.2vmin; }
.screen-brand-bottom { font-size: clamp(1.3rem, 5vmin, 4.2rem); margin-top: 1.2vmin; letter-spacing: .22em; }
/* the left panel: more air, bigger steps, nothing touching the edge */
body[data-role="screen"] aside { padding: 2.4vmin 1.6vmin; }
.screen-steps-list { font-size: clamp(.62rem, 1.5vmin, 1.15rem); line-height: 1.45; padding-left: 1.3em; }
.screen-steps-head { font-size: clamp(.68rem, 1.7vmin, 1.3rem); letter-spacing: .16em; }
.screen-presents, .screen-tagline, .screen-url { font-size: clamp(.58rem, 1.4vmin, 1.05rem); }
/* the code sits between the two halves of the name, so it needs a touch less room */
.screen-join-qr { width: min(54vh, 34vw) !important; }

/* =====================================================================================
   THE QUESTION MUST OWN THE TELEVISION (his report, 2026-11-02: "It is squashed in the left
   hand tiny column. cannot read, or see the pictures").
   MEASURED, not guessed: on a 1920x1080 screen the question box rendered 297px wide, the
   heading 161px wide with a 45px font, and the picture 78px. The cause was not the render
   function - it emitted `.screen-wrap no-join` correctly - it was eight competing
   `grid-template-columns` rules for `.screen-wrap`, four of them `!important`, with the LAST
   one winning at line 1296 and ignoring `no-join` completely.
   The fix is one rule that outranks them: two classes beat one class at equal !important, so
   `no-join` (a live question) always collapses to a single full-width column. The join screen
   keeps its own panel width untouched - this rule cannot affect it.
   ===================================================================================== */
.screen-wrap.no-join { grid-template-columns: minmax(0, 1fr) !important; }
/* and while a question is live the standings rail keeps its column, but the question may use
   every pixel left over - no nested percentage ceilings. */
.screen-wrap.no-join .screen-main { width: 100%; max-width: 100%; }
.screen-wrap.no-join .screen-question { min-width: 0; }
.screen-wrap.no-join .screen-top h2 { font-size: clamp(1.8rem, 4.2vmin, 4.6rem); }
.screen-wrap.no-join .screen-pic { max-width: 34%; }

/* AUTO ROUND: the button says what it is doing, and while it is on the console says so plainly. */
.ctl-auto { border-color: #ff6a00; color: #ffd200; font-weight: 800; letter-spacing: .06em; }
.ctl-auto.ctl-next { background: #3a1d00; }

/* THE SLIDE DOOR: top-left, quiet, remote-focusable. It must never fight the question for space, so it is
   fixed and outside the grid. Focus ring is loud on purpose - a TV remote user must see where they are. */
#slide-door {
  position: fixed; top: 1.4vmin; left: 1.6vmin; z-index: 40;
  font: 800 clamp(0.7rem, 1.5vmin, 1.3rem)/1 'OpenDyslexic', system-ui, sans-serif;
  letter-spacing: 0.14em; text-decoration: none;
  color: rgba(255, 255, 255, 0.55); background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 0.9vmin;
  padding: 1vmin 1.4vmin;
}
#slide-door:focus, #slide-door:focus-visible {
  color: #1d0a4a; background: #ffd200; border-color: #ffd200; outline: 3px solid #ff6a00;
}

/* =====================================================================================
   PLAYER PHONES COULD NOT SCROLL - LIVE REPORT, 2026-11-03, during a running quiz.
   "The pages do not scroll .. people cannot log in on some screens and some cannot lock in the answers."
   Whatever was holding the page to the viewport height is overruled here, hard, and the player sheet is
   tightened so the answers and the LOCK button fit on a small phone WITHOUT any scrolling at all.
   Scrolling is still allowed as the fallback - an unreachable button is the only unacceptable outcome.
   ===================================================================================== */
html { -webkit-text-size-adjust: 100%; }
body[data-role="player"], body[data-role="host"] {
  height: auto !important;
  min-height: 100dvh !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
}
body[data-role="player"] main#view, body[data-role="host"] main#view {
  overflow: visible !important;
  max-height: none !important;
  height: auto !important;
}
/* tighter so the question, the options and LOCK fit on one small screen */
body[data-role="player"] { padding: 8px 10px calc(10px + env(safe-area-inset-bottom, 0px)) !important; gap: 8px !important; }
/* CORRECTED 2026-11-03: the emergency tightener above stripped the 62px left padding that reserves
   room for the yellow "?" badge, so the badge landed on top of the question text. Space is kept - it is
   just smaller, and the badge shrinks with it. */
body[data-role="player"] .q-card { padding: 10px 12px 10px 46px !important; margin: 0 !important; }
body[data-role="player"] .q-card::before { font-size: 1.9rem !important; left: 11px !important; top: 8px !important; }
body[data-role="player"] .choices, body[data-role="player"] ul { gap: 6px !important; margin: 6px 0 !important; }
body[data-role="player"] .choice, body[data-role="player"] button {
  min-height: 44px !important;             /* still a real thumb target */
  padding-top: 8px !important; padding-bottom: 8px !important;
}
body[data-role="player"] h1, body[data-role="player"] .q-text { font-size: 1.02rem !important; line-height: 1.3 !important; }
/* on a short screen, shrink the chrome before shrinking the question */
@media (max-height: 700px) {
  body[data-role="player"] #who, body[data-role="player"] .name-line { font-size: .85rem !important; }
  body[data-role="player"] h1, body[data-role="player"] .q-text { font-size: .95rem !important; }
}

/* =====================================================================================
   THE INSTALLED APP MUST FIT THE PHONE (his report, 2026-11-03: "cheri installed the app, she is in
   mobile view ... make the screen fit a smart phone"). An installed PWA has no browser chrome to scroll
   against, so the page must own the viewport exactly: dvh where supported, safe-area insets respected top
   and bottom, and the sheet allowed to shrink rather than overflow.
   ===================================================================================== */
@supports (height: 100dvh) {
  body[data-role="player"], body[data-role="host"] { min-height: 100dvh !important; }
}
@media (display-mode: standalone), (display-mode: fullscreen) {
  html, body { height: 100% !important; }
  body[data-role="player"], body[data-role="host"] {
    padding-top: calc(8px + env(safe-area-inset-top, 0px)) !important;
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)) !important;
    padding-left: calc(10px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(10px + env(safe-area-inset-right, 0px)) !important;
  }
  /* the question card may shrink, the answers may not disappear */
  body[data-role="player"] .q-card { flex: 0 1 auto !important; }
  body[data-role="player"] .choice { min-height: 46px !important; }
}
/* very short screens: give the question the room, not the header */
@media (max-height: 620px) {
  body[data-role="player"] .q-card h2 { font-size: .92rem !important; line-height: 1.25 !important; }
  body[data-role="player"] .choice { min-height: 40px !important; font-size: .92rem !important; }
}
