/* The quiz's own styling, loaded by the plugin's three bodies. Two audiences with opposite
   needs, kept apart below: the projector (read from the back of a room, on the dark DISPLAY
   shell, so it inherits that shell's variables) and the phone (tapped in a hurry, standing,
   one-handed, on Bootstrap's light ground). CONTROL borrows one class from each. */

/* --- the projector ------------------------------------------------------------------- */

/* The stage splits the panel: the question takes the room's attention, the board keeps its
   own column so it is on the wall at all times — never a screen the host has to switch to. */
.quiz-stage {
  /* Fills the panel and is bounded by it. This used to be `min-height: 82vh`, because the
     shell sized the panel to its content and the stage otherwise huddled in the top third
     of a 1080p screen — but a MINIMUM cannot stop content growing past the bottom, and a
     question with a video pushed the "Atsakė" line off the wall. `.display-body` now fills
     the panel itself, so the stage inherits a real height and everything inside can shrink. */
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  /* 3.1fr: the question column was 710px of 1920 and hyphenating while 45% of the panel sat
     empty. The board keeps a readable column; the question takes the rest. */
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1rem, 2vw, 2rem);
}
/* The options grow into the space instead of leaving a third of the wall black, and the
   "answered" line stays with the answers it counts rather than orphaned at the bottom. */
.quiz-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* The grid takes the leftover height but CENTRES its rows in it rather than stretching them.
   Stretching made each option a ~240px box for one line of text, and — with flex-wrap on —
   a wrapped letter/text pair was then pushed to opposite ends of that box: the room saw a
   stranded "B" at the top and its answer at the bottom. */
.quiz-main .quiz-options { flex: 1 1 auto; align-content: center; }
.quiz-main .quiz-note { margin-top: clamp(.75rem, 1.6vh, 1.5rem); }
.quiz-side {
  display: flex; flex-direction: column; min-width: 0; min-height: 0;
  border-left: 1px solid var(--line); padding-left: clamp(.75rem, 1.5vw, 1.75rem);
}
/* The shell drops to one column at 1100px; the stage follows it instead of squeezing the
   question into a third of a laptop screen. */
@media (max-width: 1100px) {
  .quiz-stage { grid-template-columns: minmax(0, 1fr); }
  .quiz-side {
    border-left: 0; border-top: 1px solid var(--line);
    padding: 1rem 0 0; margin-top: 1rem;
  }
}

.quiz-meta {
  margin: 0; color: var(--muted); letter-spacing: .1em; text-transform: uppercase;
  font-size: clamp(.85rem, 1.15vw, 1.2rem);
}
/* The one thing the back row must read. It wraps rather than shrinks — a 90-character
   Lithuanian question is normal — and breaks long words instead of overflowing the panel. */
.quiz-question {
  margin: .35em 0 .7em; font-weight: 700; line-height: 1.12;
  font-size: clamp(1.8rem, 3.4vw, 3.75rem);
  /* NO hyphens. Automatic hyphenation split "Nepriklausomybės" as "Nepri-klausomybės" across
     a line break, which is genuinely hard to parse from the back of a room. Long words wrap
     whole; break-word stays only as the last resort against an overflowing panel. */
  hyphens: none;
  overflow-wrap: break-word;
  text-wrap: balance;
}

/* 2x2: four options read as one block at a glance, where a column of four reads as a list
   to work through. Below 800px there is no room for two, so they stack. */
.quiz-options {
  list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(.5rem, 1.4vh, 1rem);
}
@media (max-width: 800px) { .quiz-options { grid-template-columns: minmax(0, 1fr); } }
.quiz-option {
  display: flex; align-items: center; gap: clamp(.5rem, 1vw, 1rem); min-width: 0;
  /* Wrapping, because the reveal adds a count and a label to a row that was sized for an
     option: without it flex shrinks the text below its longest word and the room reads
     "Ka / un / as". The label drops to its own line instead. */
  flex-wrap: wrap;
  /* If the reveal's label does wrap onto a second line, the lines stay together instead of
     spreading to the box's top and bottom edges. */
  align-content: center;
  background: rgba(255, 255, 255, .05); border: 2px solid var(--line); border-radius: 1rem;
  padding: clamp(.5rem, 1.3vh, 1rem) clamp(.6rem, 1.1vw, 1.1rem);
  /* Chunky on a wall, still honest on a laptop: the grid centres these in the leftover
     height, so a taller tile closes the gap under the question without stretching. */
  min-height: clamp(3.5rem, 13vh, 10rem);
  font-size: clamp(1rem, 1.6vw, 1.9rem); line-height: 1.2;
}
.quiz-letter {
  flex: 0 0 auto; width: 1.9em; height: 1.9em; border-radius: .55em; font-size: .8em;
  display: grid; place-items: center; font-weight: 700;
  background: #1d2434; color: var(--ink);
}
/* flex-basis 0 + min-width 0, so a long option wraps INSIDE its own column instead of
   shoving itself onto a line below the letter. With min-content the item refused to shrink
   past its longest word, the whole row wrapped, and the room saw a stranded "B" above its
   answer. The letter now always sits beside the text. */
.quiz-text { flex: 1 1 0; min-width: 0; overflow-wrap: break-word; }
.quiz-count { flex: 0 0 auto; color: var(--muted); font-variant-numeric: tabular-nums; }

/* The reveal, and the only thing on this screen that was a secret one click ago. Colour
   AND a word AND the losers dimmed — three signals, because one of them is invisible to
   part of every room. */
/* Named ONCE, because true/false paints the same signal and two reveals that drift apart
   read as two different products on one wall. */
.quiz-stage {
  --reveal-tint: rgba(64, 200, 120, .2);
  --reveal-edge: #40c878;
  --reveal-ink: #06210f;
}
.quiz-correct { background: var(--reveal-tint); border-color: var(--reveal-edge); }
.quiz-correct .quiz-letter { background: var(--reveal-edge); color: var(--reveal-ink); }
.quiz-mark {
  flex: 0 0 auto; margin-left: auto; color: #7ee2a8; font-weight: 700; font-size: .62em;
  letter-spacing: .08em; white-space: nowrap;
}
.quiz-dim { opacity: .45; }

/* Pushed to the bottom of the column: the options stay with the question, the running
   status sits where the eye returns to it. */
.quiz-note {
  margin: auto 0 0; padding-top: .8rem; color: var(--muted);
  font-size: clamp(1rem, 1.5vw, 1.5rem);
}
.quiz-answered { color: var(--ink); font-variant-numeric: tabular-nums; }
.quiz-winners { color: var(--ink); }
.quiz-wait {
  /* A thin grey line in an empty black panel reads as a crashed feed from across a room, so
     the idle state fills its space and states plainly that nothing is wrong. */
  margin: 0;
  flex: 1 1 auto;
  display: grid;
  place-content: center;
  text-align: center;
  color: var(--ink);
  opacity: .9;
  font-size: clamp(1.75rem, 3.2vw, 3.25rem);
  font-weight: 600;
}

/* --- the phone ----------------------------------------------------------------------- */

/* Four targets tapped in a hurry, standing, one hand: the full width of the card and far
   above the 44px minimum, with the text left-aligned so a long option reads as a sentence.
   Bootstrap's .btn keeps the colours, so contrast comes from the theme (participant.css
   darkens the outline variant to 6.11:1). */
.quiz-choice {
  display: flex; align-items: center; gap: .75rem; min-height: 4.5rem;
  text-align: left; white-space: normal; overflow-wrap: break-word;
  font-size: 1.05rem; line-height: 1.3;
}
.quiz-key {
  flex: 0 0 auto; width: 2.5rem; height: 2.5rem; border-radius: .5rem;
  display: grid; place-items: center; font-weight: 700; font-size: 1.1rem;
  background: rgba(0, 0, 0, .07);   /* neutral: the same badge sits on white, on the
                                       filled button and on a tinted result row */
}
/* The chosen one is a filled button, so its badge needs the light-on-dark version. */
.btn-primary .quiz-key { background: rgba(255, 255, 255, .25); }
.quiz-pick { flex: 1 1 auto; min-width: 0; }
.quiz-flag { flex: 0 0 auto; font-size: .8rem; font-weight: 700; white-space: nowrap; }
/* Two flags can sit on the same row ("this is the key" and "this is what you picked"), so
   each has to read as its own label rather than as the next word of the other. */
.quiz-flag--key { color: #0f5132; }
.quiz-flag--you {
  padding: .2rem .45rem;
  border-radius: .3rem;
  background: var(--fest-primary-700, #5346c9);
  color: #fff;
  font-size: .7rem;
}

/* The verdict, first thing read after the reveal. It sits in a Bootstrap alert, so the
   colour pair is the framework's (#0f5132 on #d1e7dd — 7.4:1) and never a dimmed one. */
.quiz-verdict { font-size: 1.35rem; font-weight: 700; }

/* Between questions. A blank screen reads as broken; this reads as "nothing to do yet". */
.quiz-idle {
  border: 1px dashed #adb5bd; border-radius: .75rem; padding: 2rem 1rem; text-align: center;
}

/* --- the host's own device ------------------------------------------------------------ */

/* He is standing in front of people and glancing down: the press he is about to make is the
   biggest thing on the screen, and the other one is deliberately quiet. */
.quiz-act { min-height: 5rem; font-size: 1.35rem; font-weight: 600; }

/* --- shared question media (true_false, buzzer) -------------------------------------- */
/* Sized for a projector read from the back of a room: the media takes the space the text
   does not need, and never pushes the statement off screen. */
.qmedia { display: block; margin: 0 auto; max-width: 100%; }

/* ON THE WALL, THE MEDIA MUST NOT EAT THE ANSWERS.
   The projector never scrolls (`overflow: hidden` on the stage), so anything pushed past
   the bottom is not scrolled to — it is silently gone. A question's picture kept its full
   52vh and shoved the four options off the screen: the room could read the question and
   the picture and could not see A-D at all, which is unusable and looks like nothing is
   wrong. So inside the projector's question column the media gets a bounded band and is
   allowed to shrink (`flex: 0 1 auto` + `min-height: 0`, which a replaced element needs
   before flexbox may shrink it), and `object-fit: contain` keeps it from distorting when
   it does. A picture AND a link on one question — a combination games/media.py explicitly
   supports — therefore share the band instead of stacking to twice the height. */
.quiz-media {
  flex: 0 1 auto; min-height: 0;
  /* A ROW, so "a picture with a link under it" — a combination games/media.py explicitly
     supports — sits side by side on a 16:9 wall instead of stacking to twice the height.
     With one item this centres it and behaves exactly as before. */
  display: flex; flex-direction: row; align-items: center; justify-content: center;
  gap: clamp(.5rem, 1.5vw, 1.5rem);
  max-height: 32vh;
  margin: clamp(.5rem, 1.4vh, 1rem) 0;
}
.quiz-media .qmedia { margin: 0; min-height: 0; max-height: 32vh; object-fit: contain; }
.quiz-media .qmedia-image { width: auto; }
/* A VIDEO IS SIZED BY HEIGHT HERE, and `max-height` alone is not enough — this is the same
   trap as in the split band below, which was fixed there and left standing here. An <img>
   reports the picture's own dimensions, so a max-height scales it UP to fill the band; a
   <video> reports its POSTER's, which is a 400px thumbnail, and a MAXIMUM never grows
   anything. Measured on the buzzer's 1920x1080 projector: the clip sat at 400x225 while an
   image in the same band got 519x346 and a YouTube embed 614x346 — the smallest thing on the
   wall was the one media kind games/media.py tells organisers to prefer over YouTube. */
.quiz-media .qmedia-video { height: 32vh; width: auto; }
.quiz-media .qmedia-youtube { height: 32vh; width: auto; aspect-ratio: 16 / 9; }
.quiz-media .qmedia-audio { flex: 0 0 auto; width: min(100%, 32rem); }

.qmedia-image, .qmedia-video { max-height: 52vh; width: auto; border-radius: .5rem; }
.qmedia-youtube { position: relative; width: min(100%, 92vw); aspect-ratio: 16 / 9;
                  max-height: 52vh; border-radius: .5rem; overflow: hidden; }
.qmedia-youtube iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.qmedia-note { text-align: center; opacity: .6; font-size: clamp(1rem, 2vw, 1.5rem); }

/* --- true/false: two options, not four ---------------------------------------------- */
.tf-options { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tf-true  { border-color: rgba(40,167,69,.55); }
.tf-false { border-color: rgba(214,41,62,.55); }
/* The winning side after the reveal — a ring, not a move, so the room does not lose it. */
/* THE REVEAL STAYS INSIDE THE BOX. This was `outline: .35vw solid` with an offset, and an
   outline is painted OUTSIDE the border box and takes part in no layout — so where the
   winning option met the stage's edge it fell outside `overflow: hidden` (quirk 40) and the
   room saw a green frame with one side sliced clean off. Widening it or adding padding only
   moves that edge; the shape itself was wrong.
   The quiz's own reveal had the answer all along — tint the box, recolour the glyph, dim the
   loser — so true/false now paints the SAME three signals from the SAME values. Nothing is
   drawn outside anything, so there is nothing left to clip. */
.tf-won { background: var(--reveal-tint); border-color: var(--reveal-edge); }
.tf-won .quiz-letter { background: var(--reveal-edge); color: var(--reveal-ink); }
/* `margin: 0` put this line flush against the options it describes, so from the back of the
   room the answer and the boxes read as one block of noise. It is a separate statement and
   needs to look like one. */
.quiz-reveal {
  text-align: center; font-size: clamp(1.2rem, 3vw, 2.4rem);
  margin: clamp(.85rem, 2.4vh, 1.75rem) 0 0;
}

/* A bare answer pad: the letter fills the button because there is no option text beside it
   any more — the options are on the projector. */
.quiz-choice-bare { font-size: 1.5rem; font-weight: 700; padding: 1.1rem; }
.quiz-listen { font-style: italic; }
/* An audio question has nothing to look at by design — the control is just proof it plays. */
.qmedia-audio { display: flex; justify-content: center; padding: 2vh 0; }
.qmedia-audio audio { width: min(100%, 40rem); }

/* --- An audio question on the PROJECTOR ------------------------------------------------
 * There is nothing to look at, and that is the format's whole point: the room should be
 * listening rather than reading a progress bar. So the wall gets a symbol and the fact that
 * something is playing — never the transport, which lives on the host's own screen because
 * that is where the speakers and the clicks are (games/_media.html).
 */
.qmedia-sound {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(.75rem, 2vh, 1.5rem);
  padding: clamp(1rem, 3vh, 2.5rem) 0;
}
.qmedia-sound-icon svg {
  width: clamp(3.5rem, 9vh, 7rem); height: clamp(3.5rem, 9vh, 7rem);
  color: var(--fest-primary, #7367f0);
}
/* Five bars, out of phase, so a silent room can still tell it is running. */
.qmedia-sound-bars { display: flex; align-items: flex-end; gap: .45rem; height: 2.5rem; }
.qmedia-sound-bars i {
  display: block; width: .55rem; border-radius: .3rem; background: currentColor;
  height: 40%; animation: qmedia-sound-bar 1.05s ease-in-out infinite;
}
.qmedia-sound-bars i:nth-child(2) { animation-delay: .14s; }
.qmedia-sound-bars i:nth-child(3) { animation-delay: .28s; }
.qmedia-sound-bars i:nth-child(4) { animation-delay: .42s; }
.qmedia-sound-bars i:nth-child(5) { animation-delay: .56s; }
@keyframes qmedia-sound-bar { 0%, 100% { height: 28%; } 50% { height: 100%; } }
/* Anti-flake for the visual suite, and kinder on a projector nobody is watching closely. */
@media (prefers-reduced-motion: reduce) {
  .qmedia-sound-bars i { animation: none; height: 60%; }
}
.qmedia-sound-label {
  margin: 0; letter-spacing: .12em; text-transform: uppercase;
  font-size: clamp(.85rem, 1.6vh, 1.15rem); opacity: .7;
}
/* The host's still of a clip that is playing on the wall. */
.qmedia-poster { max-height: 12rem; width: auto; border-radius: .5rem; }

/* --- The projector's question: media as big as the wall allows -------------------------
 * WITHOUT media the four options keep their 2x2 block and the whole panel — that is the
 * right shape for a question that is only words.
 *
 * WITH media the picture is the thing the room is looking at, so it takes the width and the
 * options stand beside it in ONE column. Stacking a 2x2 grid under a picture squeezed both:
 * the picture got a third of the height it could have had, and the options got a third of
 * the width they did not need. Measured on a 1920x1080 wall, this roughly doubles the
 * picture's area.
 */
.quiz-body { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }

.quiz-body--media {
  display: grid;
  /* The picture takes what it can; the options need a readable column and no more. */
  grid-template-columns: minmax(0, 1fr) minmax(13rem, 20rem);
  gap: clamp(1rem, 2vw, 2.25rem);
  align-items: center;
}
@media (max-width: 1100px) {
  .quiz-body--media { grid-template-columns: minmax(0, 1fr); }
}

/* One column beside the picture: four rows, each free to be short. */
.quiz-body--media .quiz-options {
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
}
.quiz-body--media .quiz-option { padding: clamp(.45rem, 1.1vh, .9rem) clamp(.6rem, 1vw, 1rem); }

/* The band is gone here: the media column IS the band, and it is as tall as the row. */
.quiz-body--media .quiz-media { max-height: none; height: 100%; margin: 0; }
.quiz-body--media .quiz-media .qmedia { max-height: 100%; }
.quiz-body--media .quiz-media .qmedia-image { max-height: 100%; width: auto; }
/* A VIDEO CANNOT USE `width: auto` HERE. An <img> reports the picture's own size, so
   auto-width plus a height cap scales it up to fill the band; a <video> reports its
   POSTER's size, which is the 400px thumbnail — so the clip sat at 400x225 in a 1026x608
   band, 7.6x smaller than an image on the same wall, for the very media kind
   games/media.py tells people to prefer over YouTube. Fill the cell and letterbox
   instead: `object-fit: contain` keeps the aspect ratio and never crops. */
.quiz-body--media .quiz-media .qmedia-video {
  width: 100%; height: 100%; max-height: 100%; object-fit: contain;
}
.quiz-body--media .quiz-media .qmedia-youtube { height: auto; width: 100%; max-height: 100%; }

/* TWO ITEMS IN THE BAND GET A COLUMN EACH — they must never be left to negotiate the width
   between themselves. "A picture with a link under it" is a combination games/media.py
   explicitly supports, and on the projector it was unusable: an <img> reports its own width
   and took the whole row, while the YouTube wrapper had no intrinsic size to push back with
   and collapsed into the gap. MEASURED on a 1920x1080 wall: picture 912x608, player 88x50 —
   a postage stamp beside a poster. Sizing them both by HEIGHT instead only moved the damage
   (player 543x608, picture 459x306), because two replaced elements with different aspect
   ratios still divide the row by whatever they each happen to claim.
   So the two-item case stops being a negotiation: one column each, and each item fits
   itself inside its own column. Scoped with :has() so the SINGLE-item band — the common
   case, and the one every rule above was measured for — keeps its behaviour exactly. */
.quiz-body--media .quiz-media:has(> * + *) {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  align-items: center; justify-items: center;
}
.quiz-body--media .quiz-media:has(> * + *) > * { max-width: 100%; max-height: 100%; }
.quiz-body--media .quiz-media:has(> * + *) .qmedia-image {
  width: 100%; height: 100%; object-fit: contain;
}
.quiz-body--media .quiz-media:has(> * + *) .qmedia-youtube { width: 100%; height: auto; }
/* A GLYPH IS NOT A PICTURE. An audio question keeps the ordinary stacked layout, so the
   loudspeaker sits in a band of its own height above options that still get the full
   panel — rather than eating the row a photograph would have earned. */
.quiz-media--symbol { max-height: 26vh; }

/* TIESA/MELAS beside a picture: one under the other, like the quiz's four. */
.quiz-body--media .tf-options { grid-template-columns: minmax(0, 1fr); }
