/* PARSONS (סידור קוד): the student surface, plus the one code-line class every
   surface shares. Prefix .cl-parsons-. ParsonsAnswerForm.vue and
   ParsonsAnswerEcho.vue on the phone; the projector and the console card have
   their own sheet beside this one, parsons-results.css, so no two hands write
   one file (the quick quiz's rule, see the comment above quiz.css in
   index.html).

   A LINE OF CODE IS LTR INSIDE AN RTL PAGE. Every row holding one is
   `dir="ltr"` in the template: the line's shown number first, as the gutter on
   the left the projector draws too, then the line itself in `.cl-parsons-code`,
   then whatever acts on the row, at the right edge: the start of the RTL page,
   under the thumb.

   ONE PRESERVING CLASS. `.cl-parsons-code` is the only subject here, and the
   only one in parsons-results.css, that declares a preserving `white-space`
   (the `pre-wrap` below, for the phone and the presenter's card, is a rule
   ABOUT that same class).
   tests/editorFormatSlideHtml.spec.ts derives the slide formatter's table
   (`SHEET_PRESERVING_CLASSES` in src/components/editor/deck/formatSlideHtml.ts)
   from every sheet class-app/index.html links, and fails until a second such
   class is named there too.

   RIGHT AND WRONG ARE NEVER A COLOUR ALONE (quiz-student.css says why): blue
   and red, the icon's shape, and a hidden word. No brand gradient on this
   sheet: nothing here is a thin rule, and a filled or bold shape must not wear
   it.

   PHONE FIRST, and every tap target is at least 44px tall: a line in the pool
   and a line in the program by their minimum height, the controls under the
   program by their size, the send by `min-block-size`. The grip is the one
   narrower target (32px across, the full height of its row), because the arrows
   do everything it does. */

/* ── The line of code, on every surface ────────── */
/* `white-space: pre` keeps the leading spaces that carry the indentation, and
   keeps a line on one line. `unicode-bidi: isolate` stops a Hebrew neighbour
   reordering it. A line wider than its box scrolls inside the box rather than
   pushing the page sideways. Sizes belong to each surface, in its own sheet;
   the phone and the presenter's card wrap instead (`.cl-parsons-form
   .cl-parsons-code` below). */
.cl-parsons-code {
  display: block;
  min-inline-size: 0;
  max-inline-size: 100%;
  margin: 0;
  font-family: var(--font-mono);
  line-height: 1.5;
  direction: ltr;
  unicode-bidi: isolate;
  text-align: left;
  white-space: pre;
  overflow-x: auto;
  overflow-y: hidden;
}

/* Read by a screen reader, drawn nowhere: the prefix that names what a pool
   line does, the word before a shown number and the indentation after it, the
   live line, and the word beside a place mark. */
.cl-parsons-sr {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
}

/* ── A line on the phone: its number, then its code ── */
/* THE NUMBER AND THE CODE ARE ONE UNIT, on their first baselines, so a wrapped
   line keeps its number beside its first row and never on a row of its own. */
.cl-parsons-line {
  display: flex;
  flex: 1 1 auto;
  align-items: baseline;
  gap: 6px;
  min-inline-size: 0;
}

/* The shown number, the projector's gutter in small: one width for every row
   (two digits, since a question has at most sixteen lines), so the code starts
   at one edge all the way down. */
.cl-parsons-line__num {
  flex: none;
  inline-size: calc(2ch + 7px);
  padding-inline-end: 6px;
  border-inline-end: 1px solid var(--border-light);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  text-align: end;
  color: var(--text-tertiary);
}

/* A LONG LINE WRAPS ON THE PHONE, and never runs out of its row unseen: the end
   of a line is often exactly what tells it from its distractor, and a row a
   phone cuts short hid it. `pre-wrap` still keeps every leading space.

   THE HANGING INDENT. A wrapped continuation starts two columns further in than
   the line's own text, so it can never be mistaken for a line of its own:
   `--cl-parsons-lead` is the line's leading columns (bound per line in the
   template, the one computed value it needs), the padding puts every row of the
   line that far in plus two, and the negative indent brings the FIRST row back
   to the edge, where its own leading spaces indent it exactly as written.
   `1ch` is one column, because the face is monospaced.

   THE PRESENTER'S CARD WRAPS TOO (`cl-parsons--console`, which PresenterView
   puts on its own mount and on nothing else). On the lecturer's phone the card
   gives a line about 34 columns at 13px, and an ellipsis there left a key line
   and its distractor reading as the same "const users = await response.…".
   This sheet says so rather than parsons-results.css, which may declare no
   preserving `white-space` (its header says why); its sizes and its frame stay
   there. Two classes on the block, because its `.cl-parsons .cl-parsons-code`
   zeroes the padding and is linked after this sheet. The projector's lines and
   both of the console's previews are on a slide and keep to one line. */
.cl-parsons-form .cl-parsons-code,
.cl-parsons-echo .cl-parsons-code,
.cl-parsons.cl-parsons--console .cl-parsons-code {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding-inline-start: calc((var(--cl-parsons-lead, 0) + 2) * 1ch);
  text-indent: calc((var(--cl-parsons-lead, 0) + 2) * -1ch);
}

/* The phone's size, colour and share of its row. */
.cl-parsons-form .cl-parsons-code,
.cl-parsons-echo .cl-parsons-code {
  flex: 1 1 auto;
  min-inline-size: 0;
  font-size: 14px;
  color: var(--text-color);
}

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

.cl-parsons-form__zone {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* "השורות" and "התוכנית שלכם". The body font: Departure Mono has no Hebrew. */
.cl-parsons-form__title {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-tertiary);
}

.cl-parsons-form__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A line in the pool: the whole row is the button, and one tap adds it. */
.cl-parsons-form__add {
  appearance: none;
  position: relative;
  display: flex;
  align-items: center;
  inline-size: 100%;
  min-block-size: 44px;
  margin: 0;
  padding: 6px var(--space-sm);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  color: var(--text-color);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* A line in the program. OPAQUE, because a row being dragged slides over its
   neighbours. The solid bar on its start edge (the left, in this LTR row) is
   what tells a chosen line from one still in the pool at a glance.

   THE ROW IS THE LINE: a button across the whole row but for the grip, so the
   code has the card's width to itself and an eight-line program of phone-width
   lines stands one row of text to a line, two where a line is long, all of it
   on one screen. */
.cl-parsons-form__row {
  position: relative;
  display: flex;
  align-items: stretch;
  border: 1px solid var(--primary-border);
  border-inline-start: 3px solid var(--primary-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
}

/* SELECTED: the line the controls under the program act on. A solid ground
   and a full outline, so it reads at a glance among rows that all carry the
   start bar. */
.cl-parsons-form__row.is-selected {
  border-color: var(--primary-color);
  background: var(--bg-secondary);
  box-shadow: 0 0 0 1px var(--primary-color);
}

.cl-parsons-form__pick {
  appearance: none;
  position: relative;
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  min-inline-size: 0;
  min-block-size: 44px;
  margin: 0;
  padding-block: 6px;
  padding-inline: var(--space-sm) 0;
  border: 0;
  border-start-start-radius: var(--radius-sm);
  border-end-start-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-color);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* The row in the finger: lifted over its neighbours and moved by the computed
   `transform` the form sets while it is held. */
.cl-parsons-form__row.is-dragging {
  z-index: 2;
  border-color: var(--primary-color);
  box-shadow: var(--shadow-lg);
}

/* THE ONLY ELEMENT THAT OWNS THE TOUCH. `touch-action: none` here and on
   nothing else is what lets a finger on the grip drag while a finger on a line
   still scrolls the page. 32px across and the full height of its row: the
   arrows under the program do everything it does, so it may be the one target
   narrower than 44px, and every pixel it gives back goes to the code. No
   selection and no iOS long-press sheet. */
.cl-parsons-form__handle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 32px;
  color: var(--text-tertiary);
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.cl-parsons-form__row.is-selected .cl-parsons-form__handle,
.cl-parsons-form__row.is-dragging .cl-parsons-form__handle {
  color: var(--primary-color);
}

.cl-parsons-form__row.is-dragging .cl-parsons-form__handle {
  cursor: grabbing;
}

/* THE CONTROLS FOR THE SELECTED LINE, one set for the whole program. In the
   flow right under the list, and STICKY at the foot of the screen while the
   program runs on below it, so a line near the top is moved without scrolling
   away from it. Opaque, with a hairline on top, because while it is held it
   sits over the rows; the row in the finger (z-index 2) still passes over it.
   The safe-area inset keeps the buttons off an iPhone's home bar when the room
   is installed to the home screen. */
.cl-parsons-form__dock {
  position: sticky;
  inset-block-end: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-block: var(--space-sm) max(var(--space-sm), env(safe-area-inset-bottom));
  border-block-start: 1px solid var(--border-light);
  background: var(--bg-surface);
}

.cl-parsons-form__note {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* In the RTL page: the two arrows at the start (the right, under the thumb),
   the way back to the pool alone at the far end. */
.cl-parsons-form__tools {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.cl-parsons-form__tool {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 44px;
  block-size: 44px;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  color: var(--text-secondary);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}

.cl-parsons-form__tool--back {
  margin-inline-start: auto;
  padding-inline: var(--space-md);
}

.cl-parsons-form__tool:disabled {
  opacity: 0.35;
  cursor: default;
}

.cl-parsons-form__add:focus-visible,
.cl-parsons-form__tool:focus-visible {
  outline: 2px solid var(--primary-color);
  outline-offset: 1px;
}

/* Inside the row, which draws its own edge: a ring over the row's border
   would hide which of the two is the focus. */
.cl-parsons-form__pick:focus-visible {
  outline: 2px solid var(--primary-color);
  outline-offset: -3px;
}

/* Where the program will be, while it is empty: a place, not an error. */
.cl-parsons-form__hint {
  margin: 0;
  padding: var(--space-md);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-md);
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-secondary);
  text-align: center;
}

.cl-parsons-form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin: 0;
}

.cl-parsons-form__button {
  min-block-size: 44px;
}

/* "שינוי הסדר" under the echo (StudentView.vue): a full 44px target, which its
   small word-cloud and numeric twins in app.css are not. */
.cl-parsons-change {
  min-block-size: 44px;
}

/* ── The echo: the order sent, the solution, or the lines ── */
.cl-parsons-echo {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.cl-parsons-echo__title {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-tertiary);
}

.cl-parsons-echo__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Read, not pressed, so smaller than a form row. */
.cl-parsons-echo__row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  min-block-size: 36px;
  padding: 4px var(--space-sm);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
}

.cl-parsons-echo__row--right {
  border-color: var(--primary-border);
}

.cl-parsons-echo__row--wrong {
  border-color: var(--alert-border);
}

/* The mark sits last in the LTR row: at the right edge, where the eye of an
   RTL reader starts the line. */
.cl-parsons-echo__mark {
  display: inline-flex;
  flex: none;
  justify-content: center;
  inline-size: 24px;
}

.cl-parsons-echo__mark--right {
  color: var(--primary-color);
}

.cl-parsons-echo__mark--wrong {
  color: var(--alert-color);
}

/* Hover only where a pointer hovers: on a phone a tapped line would keep its
   hover tint until the next tap somewhere else. */
@media (hover: hover) {
  .cl-parsons-form__add:hover,
  .cl-parsons-form__tool:not(:disabled):hover {
    border-color: var(--primary-border);
    background: var(--fsp-hover-bg);
  }

  .cl-parsons-form__pick:hover {
    background: var(--fsp-hover-bg);
  }
}
