/* ============================================================================
   Parsons (סידור קוד) on the PROJECTOR and the CONSOLE: ParsonsResults.vue.

   One sheet per surface, like the quick quiz's. parsons.css is the phone form
   plus `.cl-parsons-code`, the ONE class every surface puts on a line's text;
   this file is the block SlideRenderer mounts on the projector (and in both of
   the console's previews) and the presenter's card mounts with `live-tally`.

   THE COORDINATE SYSTEM IS SLIDES.CSS'S. On the projector the block sits on the
   1920x1080 canvas (`.cl-stage__canvas`, `container-type: inline-size`), so
   every `.cl-parsons--display` size is in `cqw` (1cqw = 19.2px) with a clamp
   floor, never `vw` and never behind a `@media` query. `cqh` does not resolve
   here (class-app/CLAUDE.md).

   THE FLOORS ARE THE CONSOLE CARD'S SIZES. On the canvas `cqw` is always
   19.2px and no floor below is ever reached. The presenter's control card is
   outside any canvas, so there `cqw` falls back to the viewport, and on the
   lecturer's phone (390px, 1cqw = 3.9px) every size IS its floor. So the floors
   are set for reading on that phone, the way slides.css sets the poll card's
   (`clamp(15px, ...)` on an option row): the code at 13px, the line numbers and
   the shares at 12px, nothing under 12px.

   THE WHITESPACE OF A LINE IS NOT THIS FILE'S. Indentation is leading spaces in
   the line's text, and `.cl-parsons-code` in parsons.css is what keeps them
   (`white-space: pre`). This file must never declare `white-space` as pre,
   pre-wrap, pre-line or break-spaces: tests/editorFormatSlideHtml.spec.ts reads
   every sheet class-app/index.html links and pins the classes that preserve
   whitespace, and that list names `cl-parsons-code` alone. `nowrap` below is
   not one of those.

   BARS ARE THIN AND SOLID. `--primary-color` on a 2-4px line, never the brand
   gradient: the ramp is a hairline mark, and a share bar is data. Every numeral
   is `--font-mono` in a solid colour, at weight 500 at most.
   ============================================================================ */

/* ── The block ─────────────────────────────────── */
.cl-parsons {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* THE CODE IS SIZED FOR THE BACK OF THE ROOM. The deck's own code
   (`.tpl-term__body`, slide-templates.css) is 1.6cqw, and so is a question
   here of up to eight lines, none longer than 52 characters. Any other takes
   the step the component names (`cl-parsons--fit-10`, `--fit-12`, `--fit-16`,
   SIZE_STEPS in ParsonsResults.vue: the first that holds both its number of
   lines and its longest line), and each step sets two sizes:

     --cl-parsons-lines-size    the shuffled lines, BEFORE the answer is out,
                                which the whole room has to read and arrange;
     --cl-parsons-program-size  the solution and the unused lines AFTER it,
                                which share the canvas with the verdict, two
                                headings and the wrong arrangement, so a long
                                program steps down further here.

   THE BUDGET, measured in Chromium on the 1920x1080 canvas with the real
   fonts (2026-10-29). The canvas less its 6cqw / 7cqw padding is 1651 x 850px;
   a one-line title and its gap leave 718px under it, and `.slide` clips
   silently. Every step fits that 718px with a one-line prompt in both states,
   the ballot included while the question is open. A slide BODY is not in that
   sum: it gives way to the block (the rules at the end of this file) but keeps
   its 2cqw gap, and what it still needs is taken back from the code by the
   measured fit, `--cl-parsons-fit` (`refit` in ParsonsResults.vue, "the
   slide's own text"). A second line of prompt runs at most 21px into the
   slide's padding, which is still on screen, and clear of the chevron (the
   corner rule below).

   THE WIDTH, measured the same way: the longest line each step shows whole,
   leading spaces included, before the reveal / after it, where a line shares
   its row with its share: 74 / 54 characters at the full sizes, 79 / 72 at
   `--fit-10`, 92 / 92 at `--fit-12` and 110 / 104 at `--fit-16`. The `chars`
   in SIZE_STEPS come from the second figure. Change a size here and those
   figures change with it. */
.cl-parsons--display {
  gap: 0.8cqw;
  --cl-parsons-lines-size: clamp(13px, 1.6cqw, 30.72px);
  --cl-parsons-program-size: clamp(13px, 1.6cqw, 30.72px);
}

.cl-parsons--display.cl-parsons--fit-10 {
  --cl-parsons-lines-size: clamp(13px, 1.5cqw, 28.8px);
  --cl-parsons-program-size: clamp(13px, 1.25cqw, 24px);
}

.cl-parsons--display.cl-parsons--fit-12 {
  gap: 0.65cqw;
  --cl-parsons-lines-size: clamp(13px, 1.3cqw, 24.96px);
  --cl-parsons-program-size: clamp(13px, 1.05cqw, 20.16px);
}

.cl-parsons--display.cl-parsons--fit-16 {
  gap: 0.5cqw;
  --cl-parsons-lines-size: clamp(13px, 1.1cqw, 21.12px);
  --cl-parsons-program-size: clamp(13px, 0.95cqw, 18.24px);
}

/* ABOVE THE CORNER MARKS, as the slide's title and body are (slides.css, the
   brandmark note): a positioned mark otherwise paints over a line of code or a
   share. Scoped to the slide: the console card has no marks to clear. */
.slide--display .cl-parsons {
  position: relative;
  z-index: 1;
}

/* THE CHEVRON'S CORNER IS LEFT TO THE CHEVRON. `.slide__brandmark--term`
   stands in the bottom RIGHT corner, which in this `dir="rtl"` deck is the
   inline-START side (and the inline-end of the `dir="ltr"` lists). It reaches
   2.528cqw into the content box, and a parsons slide fills that box to the
   foot: under a templated body (which grows, slide-templates.css) at every
   length, under any body once the program is long. Before this rule the ballot
   and its "התשובות נאספות", the shuffled lines' panel, the wrong arrangement
   and the unused lines' panel each printed into it.

   SIDEWAYS, NOT UPWARDS, for the reason slide-templates.css gives at "The
   closing block yields the chevron's corner": lifting the block off the
   bottom costs the 56px of height these slides are short of, while stepping
   back from the right costs width they have to spare. The width is the
   deck's own token, `--tpl-mark-reserve` (2.6cqw = 49.92px, declared on
   `.slide`, the overhang rounded up), so the block clears the mark by the
   same 1.4px every closing block in the deck does, and moves with it. The
   whole block steps back, not only its last row, so the panels, the headings
   and the prompt keep one right edge; that is also where a closing
   `.tpl-point` or `.tpl-note` in the body above already ends.

   THE BALLOT STEPS BACK WITH IT on a parsons slide, and on no other kind.
   It is SlideRenderer's, mounted under this block while the question is open,
   and it is the last thing on the slide then, so it is the box that reaches
   the corner. Narrowing it here keeps its edge on the block's. */
.slide--display .cl-parsons {
  padding-inline-start: var(--tpl-mark-reserve);
}

.slide--display.slide--kind-parsons > .cl-ballot {
  margin-inline-start: var(--tpl-mark-reserve);
}

.cl-parsons__prompt {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--text-color);
}

.cl-parsons--display .cl-parsons__prompt {
  font-size: clamp(16px, 2cqw, 38px);
}

/* ── The verdict, the headings, the empty lines ── */
.cl-parsons__header {
  font-size: 15px;
  line-height: 1.25;
  color: var(--text-secondary);
}

.cl-parsons--display .cl-parsons__header {
  font-size: clamp(14px, 1.6cqw, 31px);
}

/* Solid colour, never the brand gradient: numerals at weight 500. */
.cl-parsons__figure {
  font-family: var(--font-mono);
  font-size: 1.35em;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--primary-color);
}

/* The denominator is the context, not the reading. */
.cl-parsons__figure--total {
  color: var(--text-secondary);
}

/* A caption over a list of lines, in the ballot eyebrow's voice. */
.cl-parsons__heading {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.3;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
}

.cl-parsons--display .cl-parsons__heading {
  font-size: clamp(12px, 1.1cqw, 21px);
}

.cl-parsons__empty {
  font-size: 14px;
  line-height: 1.3;
  color: var(--text-tertiary);
}

.cl-parsons--display .cl-parsons__empty {
  font-size: clamp(14px, 1.6cqw, 31px);
}

/* ── The lines ─────────────────────────────────── */
/* ONE PANEL PER LIST, like a code editor, rather than a card per line: a line
   of code is read in the company of the lines around it, and a frame on every
   row would cost the budget a border and a gap ten times over. The lists are
   `dir="ltr"` in the markup, so the shown number is the gutter on the LEFT and
   the code reads from there, as it does in every editor the room has used. */
.cl-parsons__lines,
.cl-parsons__program,
.cl-parsons__distractors {
  list-style: none;
  display: flex;
  flex-direction: column;
  padding-block: 6px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
}

.cl-parsons--display .cl-parsons__lines,
.cl-parsons--display .cl-parsons__program,
.cl-parsons--display .cl-parsons__distractors {
  padding-block: 0.5cqw;
  border-radius: 0.8cqw;
}

/* The lines the solution does not use, told apart by the frame alone. */
.cl-parsons__distractors {
  border-style: dashed;
}

/* A row wraps only where it has to: on the console's narrow card the share
   drops under its line instead of squeezing the code, and a long line wraps
   inside its own box (parsons.css, "The presenter's card wraps too"). On the
   canvas every row is one line, and a line of code too long for it ends in an
   ellipsis. */
.cl-parsons__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 0.85em;
  row-gap: 2px;
  padding: 2px 12px;
  font-size: 14px;
  line-height: 1.3;
}

/* The row's font size IS the code's (`.cl-parsons-code` below is 1em), and
   the two sizes are the step's: the solution's by default, the shuffled
   lines' in their own list. Each is drawn at `--cl-parsons-fit` of itself,
   which ParsonsResults.vue sets on a slide whose body needs the room (never
   under 0.8) and nowhere else, so the card and any slide with room to spare
   take the step's size whole. The number and the share are em of the row and
   follow it. */
.cl-parsons--display .cl-parsons__row {
  row-gap: 0.1cqw;
  padding: 0.1cqw 1.2cqw;
  font-size: calc(var(--cl-parsons-program-size) * var(--cl-parsons-fit, 1));
}

.cl-parsons--display .cl-parsons__lines .cl-parsons__row {
  font-size: calc(var(--cl-parsons-lines-size) * var(--cl-parsons-fit, 1));
}

.cl-parsons--display.cl-parsons--fit-16 .cl-parsons__row {
  padding-block: 0;
}

/* ON THE CANVAS A ROW IS ALWAYS ONE LINE. The steps are budgeted row by row,
   and a share dropping under its line adds a row the budget never counted, on
   a slide that clips silently. The step a question takes keeps its longest
   line whole beside its share (`chars` in ParsonsResults.vue), so this only
   ever decides what a line past the last step does: it ends in an ellipsis.
   The console card keeps the wrap. */
.slide--display .cl-parsons__row {
  flex-wrap: nowrap;
}

/* THE NUMBER AND ITS LINE ARE ONE UNIT, which is what the wrap above may never
   split: a row too narrow for both moves the share under the line, and a line
   too long for the row ends in an ellipsis beside its number, never on a row of
   its own under a number standing alone. */
.cl-parsons__line {
  display: flex;
  align-items: baseline;
  flex: 1 1 auto;
  min-inline-size: 0;
  column-gap: 0.85em;
}

/* 0.85em of the code, never under 12px: the card on the phone. */
.cl-parsons__num {
  flex: none;
  inline-size: 2.6em;
  padding-inline-end: 0.7em;
  border-inline-end: 1px solid var(--border-light);
  font-family: var(--font-mono);
  font-size: max(12px, 0.85em);
  text-align: end;
  color: var(--text-tertiary);
}

/* THE LINE ITSELF. Its whitespace, direction and font come from
   `.cl-parsons-code` in parsons.css; this only fits it to the row. The row is
   the frame here, so the line draws none of its own, and a line too long for
   the row ends in an ellipsis rather than a scrollbar on a projector. On the
   presenter's card it wraps instead (parsons.css), so the ellipsis is never
   reached there: a lecturer reading a 390px phone must see the end of a line,
   which is what tells it from its distractor. */
.cl-parsons .cl-parsons-code {
  flex: 1 1 auto;
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: 1em;
  line-height: inherit;
  color: var(--text-color);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── The shares ────────────────────────────────── */
/* A FIXED WIDTH at the end of the row, so the bars start at one edge down the
   whole program and the distractors' figures end where the program's do.
   0.85em of the code, never under 12px. */
.cl-parsons__share {
  flex: none;
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6em;
  inline-size: 17em;
  max-inline-size: 100%;
  font-size: max(12px, 0.85em);
}

/* SMALLER THAN THE CODE ON THE CANVAS, and no larger than 1.1cqw (21px)
   however large the code is. The room reads the program; a share is the
   figure beside it, and every em it does not take is width the code keeps
   before it ends in an ellipsis. */
.cl-parsons--display .cl-parsons__share {
  font-size: max(12px, min(0.85em, 1.1cqw));
}

.cl-parsons__track {
  flex: 1 1 auto;
  min-inline-size: 0;
  block-size: 3px;
  border-radius: var(--radius-full);
  background: var(--primary-border);
  overflow: hidden;
}

.cl-parsons--display .cl-parsons__track {
  block-size: clamp(2px, 0.2cqw, 4px);
}

/* Grows from the start edge, the RIGHT one: the track is `dir="rtl"` in the
   markup, like every other bar in the room. */
.cl-parsons__fill {
  display: block;
  block-size: 100%;
  background: var(--primary-color);
  transition: inline-size 0.4s ease;
}

.cl-parsons__stat {
  flex: none;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* One width for every program row, so "5%" and "100%" do not move the bar. */
.cl-parsons__program .cl-parsons__stat {
  inline-size: 9.5em;
}

.cl-parsons__pct {
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--text-color);
}

/* ── The most common wrong arrangement ─────────── */
.cl-parsons__wrong {
  font-size: 14px;
  line-height: 1.3;
  color: var(--text-secondary);
}

.cl-parsons--display .cl-parsons__wrong {
  font-size: clamp(13px, 1.3cqw, 25px);
}

/* ONE BOX, so the arrangement moves under its label whole rather than breaking
   in the middle of an RTL line, where the half that wraps lands at the far
   (right) end of the next line and reads as a different order. Too long for a
   line of its own, it wraps inside the box, left to right. */
.cl-parsons__order {
  display: inline-block;
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--text-color);
}

/* ── The slide body gives way ──────────────────── */
/* The same three rules slides.css (the "interaction slide" block above "The
   break card") writes for poll, quiz, word cloud and numeric, for the same
   reasons, which that file spells out: a long body shrinks, and clips rather
   than painting over the lines under it. They live here rather than in
   slides.css because that file is mirrored to the main site's
   public/css/deck-slides.css, selector for selector
   (tests/deckSlidesCssMirror.spec.ts).

   THE FIRST ONE SKIPS A TEMPLATED BODY, and that is what keeps parsons
   identical to the four. Their `flex: 0 1 auto` is (0,3,0) in slides.css, a
   tie with slide-templates.css's `.slide--display .slide__body:has(.tpl)`
   `flex: 1 1 auto`, and slide-templates.css is linked later, so on a templated
   body THEIRS is what applies: the body grows into the free space and the
   question sits at the foot of the slide. This sheet is linked after both, so
   the same selector here would win that tie and lay a parsons slide out
   differently from every other question. The other two rules out-rank the
   template sheet by specificity, (0,4,0) and (0,5,0), exactly as the
   originals do. */
.slide--display.slide--kind-parsons .slide__body:not(:has(.tpl)) {
  flex: 0 1 auto;
  min-block-size: 0;
}

.slide--display.slide--kind-parsons .slide__body:has(.tpl) {
  overflow: hidden;
}

.slide--display.slide--kind-parsons .slide__body:has(.tpl) > .tpl {
  justify-content: flex-start;
}

/* ...AND IT IS NEVER CUT THROUGH ITS LETTERS, which is where the poll's net
   stops and this one goes further. ParsonsResults.vue shrinks its code (the
   rows' `--cl-parsons-fit` above) until the body's text fits the box the slide
   left it, and only a body still short with the code at its floor is longer
   than the slide can hold: the block then names itself `--hides-body` and the
   body is hidden whole. `visibility`, not `display`: the squeezed box keeps its
   place, so hiding it moves nothing else on the slide. */
.slide--display.slide--kind-parsons:has(> .cl-parsons--hides-body) > .slide__body {
  visibility: hidden;
}
