:root {
  /* Background color for every TOAM screen — the classic purple of the
     original TOAM terminal. Change this one value to retune the exact shade. */
  --screen-bg: #00005f;
  color-scheme: dark;
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  background: var(--screen-bg);
  color: #e7edf7;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  width: 100%;
  height: 100%;
  min-height: 100%;
  margin: 0;
  overflow: hidden;
}

body {
  display: grid;
  place-items: center;
  min-height: 100dvh;
  padding: 8px;
  background: var(--screen-bg);
}

/* Touch/tablet: remove margin and shrink frame so the terminal fills the screen */
@media (pointer: coarse) {
  body {
    padding: 0;
  }
  .terminal-frame {
    padding: 4px;
  }
  /* A tablet screen is far more square than the very wide browser terminal, so
     the big logo left no room and the green "קדימה" button fell below the frame
     and was clipped. Shrink the logo and tighten the copy so the whole opening
     screen - greeting, instruction, remember tick, both buttons - fits inside the
     frame. NOTE: the selectors are prefixed with .startup-screen on purpose. The
     base .startup-logo / .startup-copy rules appear LATER in this file, and media
     queries do not add specificity, so a bare ".startup-logo" here would lose to
     the later base rule on source order. The extra class makes these win. */
  .startup-screen .startup-logo { max-height: 60%; width: min(92%, 112ch); }
  .startup-screen .startup-copy { padding-top: 0.2em; }
  .startup-screen .startup-copy h1 { font-size: 1.55em; margin-bottom: 0.15em; }
  .startup-screen .startup-copy p { margin-bottom: 0.5em; }
}

.pilot-shell {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

.startup-screen {
  position: absolute;
  z-index: 10;
  inset: 0;
  direction: rtl;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  overflow: hidden;
  padding: 1.2em 3ch 1em;
  background: var(--screen-bg);
  color: #bfe7ff;
  font-family: "Cascadia Mono", "Consolas", "Courier New", monospace;
  line-height: 1.2;
  text-align: center;
  user-select: auto;
}

.startup-logo {
  display: block;
  width: min(72%, 64ch);
  max-height: 62%;
  object-fit: contain;
  object-position: center;
  filter: invert(1);
  mix-blend-mode: screen;
  /* The logo takes 62% of the screen whatever else is on it, and the words
     underneath got whatever was left - which was not enough: the second line of
     the button, "ראשונה", was cut off by the frame on every window, and on a
     tall narrow one the whole label went. A logo that can give up its room when
     the words need it keeps them both on the screen. `min-height: 0` is what
     lets a flex item shrink below its own content at all. */
  flex: 0 1 auto;
  min-height: 0;
}

.startup-copy {
  width: 100%;
  padding: 0.65em 2ch 0;
  /* The words are the part that must not be cut. */
  flex: 0 0 auto;
}

.startup-copy h1 {
  margin: 0 0 0.3em;
  color: #bfe7ff;
  font-size: 2em;
}

.startup-copy p {
  margin: 0 0 0.65em;
  font-size: 1em;
}

/* Quieter than the instruction above it: a child who already has a code should
   be able to skip straight past it. */
.startup-no-code {
  font-size: 0.82em;
  color: #9fb0e6;
}

.startup-form {
  display: grid;
  justify-items: center;
  gap: 7px;
}

.startup-password-field {
  display: grid;
  justify-items: center;
}

.startup-actions {
  display: flex;
  justify-content: center;
  align-items: end;
  gap: 2ch;
  width: 100%;
}

.startup-actions input {
  width: 14ch;
  padding: 0.15em 1ch 0.25em;
  border: 0;
  border-bottom: 2px solid #8cecff;
  border-radius: 0;
  background: transparent;
  color: #bfe7ff;
  caret-color: #bfe7ff;
  font: inherit;
  font-size: 1.2em;
  text-align: center;
  outline: none;
}

.startup-actions input:focus {
  border-color: #fff;
  box-shadow: 0 2px 0 rgb(255 255 255 / 28%);
}

.startup-actions button {
  padding: 0.35em 1.2ch;
  border: 1px solid #8cecff;
  border-radius: 0;
  background: transparent;
  color: #bfe7ff;
  font: inherit;
  font-size: 1em;
  font-weight: 700;
  cursor: pointer;
}

.startup-actions button:hover,
.startup-actions button:focus-visible {
  background: #bfe7ff;
  color: #00005f;
}

.startup-error {
  min-height: 1.3em;
  margin: 0.45em 0 0 !important;
  color: #fff;
  font-weight: 700;
}

/* "Remember this device" opt-in on the startup screen. */
.startup-remember {
  display: inline-flex;
  align-items: center;
  gap: 0.6ch;
  margin: 0.45em 0 0;
  color: #cfe6ff;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.startup-remember input {
  width: 1.15em;
  height: 1.15em;
  accent-color: #7fe0a8;
  cursor: pointer;
}

/* Small, unobtrusive "switch pupil" control, shown only on a remembered device.
   Two-tap confirm (see app.js) guards against an accidental child tap. */
.toam-switch-student {
  position: fixed;
  left: 10px;
  bottom: 8px;
  z-index: 60;
  padding: 6px 14px;
  border: 2px solid #ff8a8a;
  border-radius: 12px;
  background: rgba(0, 0, 40, 0.55);
  color: #ff8a8a;
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  opacity: 0.72;
  -webkit-tap-highlight-color: transparent;
}
.toam-switch-student:hover { opacity: 1; }
.toam-switch-student.is-armed {
  background: #ff8a8a;
  color: #00002a;
  opacity: 1;
}

.terminal-frame {
  position: relative;
  direction: ltr;
  overflow: hidden;
  padding: 12px;
  border: 1px solid #62708f;
  border-radius: 5px;
  background: var(--screen-bg);
  box-shadow:
    0 18px 70px rgb(0 0 0 / 45%),
    inset 0 0 0 2px #13184d;
  cursor: text;
}

.terminal-grid {
  position: relative;
  width: 80ch;
  height: 25em;
  overflow: hidden;
  transform-origin: top left;
  color: #bfe7ff;
  background: var(--screen-bg);
  font-family: "Cascadia Mono", "Consolas", "Courier New", monospace;
  font-size: 17px;
  font-weight: normal;
  line-height: 1;
  letter-spacing: 0;
  user-select: none;
}

.lesson-goodbye {
  position: absolute;
  z-index: 2;
  left: 1.5ch;
  top: 4.5em;
  width: 39ch;
  height: 16.5em;
  object-fit: contain;
  object-position: left center;
  pointer-events: none;
}

.kal-da-intro {
  position: absolute;
  z-index: 5;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3em;
  padding: 0.3em;
  background: var(--screen-bg);
  pointer-events: none;
}

.kal-da-intro-image {
  width: 100%;
  max-width: 100%;
  max-height: 91%;
  object-fit: contain;
}

.kal-da-intro-caption {
  margin: 0;
  width: 100%;
  color: #fff;
  font-size: 0.85em;
  line-height: 1.25;
  text-align: center;
  direction: rtl;
}

.terminal-grid.is-summary .screen-row {
  z-index: 1;
  /* Lesson segments are absolutely positioned inside 1em-tall rows, which is right
     for the fixed terminal grid but makes the enlarged finish message spill over
     the line below once it wraps. On finish screens only, the message flows
     normally so each row takes the height it actually needs. */
  height: auto;
  min-height: 1em;
  display: flex;
  justify-content: flex-end;
  padding-inline-end: 3ch;
}

.terminal-grid.is-summary .role-feedback {
  /* The finish message is the one thing a child actually reads here, so it is set
     much larger than lesson text. max-width shrinks in step with the font size
     (ch scales with it), keeping the text clear of the goodbye picture. */
  position: static;
  max-width: 26ch;
  font-size: 1.5em;
  font-weight: 600;
  white-space: normal;
  line-height: 1.4;
}

.english-summary {
  position: absolute;
  z-index: 6;
  inset: 0;
  direction: rtl;
  display: grid;
  /* Give the copy a little more room than the mascot so the closing text wraps
     less and fits above the centred "חזרה לתפריט" button. */
  grid-template-columns: 1.2fr 0.8fr;
  /* Top-align the two columns; the bottom is kept clear (padding-bottom) for the
     absolutely-positioned back button pinned to the bottom-centre in app.js. */
  align-items: start;
  gap: 2ch;
  padding: 1.1em 3ch 3.6em;
  background: var(--screen-bg);
  color: #bfe7ff;
  font-family: "Cascadia Mono", "Consolas", "Courier New", monospace;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.45;
}

.english-summary-copy h1 {
  margin: 0 0 0.35em;
  font-size: 1.85em;
  font-weight: 700;
}

.english-summary-copy p {
  margin: 0 0 0.5em;
  /* Honour the "\n" line breaks the server puts in the closing-screen copy so
     each skill sits on its own row and the screen is not crowded. */
  white-space: pre-line;
}

.english-summary img {
  display: block;
  width: 100%;
  max-height: 17em;
  object-fit: contain;
}

/* Post-diagnosis closing screen: keep the smiling "goodbye" mascot pinned to
   the visual left of the screen while the Hebrew copy stays right-aligned. The
   base .english-summary grid is RTL, so this switches the container to LTR to
   place the image column on the left and re-applies RTL to the copy. */
.diagnosis-complete {
  direction: ltr;
  /* Top-align so longer messages (e.g. the farewell screen) do not get their
     last lines clipped off the bottom. */
  align-items: start;
  gap: 2ch;
  /* Give the copy column more room so lines wrap less. */
  grid-template-columns: 0.85fr 1.15fr;
  padding-top: 1em;
}

.diagnosis-complete .diagnosis-complete-goodbye {
  grid-column: 1;
  align-self: center;
  width: 100%;
  max-height: 15em;
  object-fit: contain;
  object-position: center;
}

.diagnosis-complete .diagnosis-complete-copy {
  grid-column: 2;
  direction: rtl;
  text-align: right;
}

.diagnosis-complete-copy #diagnosis-complete-lines p {
  margin: 0 0 0.45em;
  line-height: 1.35;
}

.diagnosis-complete-hint {
  margin-top: 1.2em;
  color: #7fe0a8;
  font-weight: 700;
}

.screen-row {
  position: relative;
  width: 80ch;
  height: 1em;
  margin-bottom: -1px;
  overflow: visible;
  direction: ltr;
  white-space: pre;
}

/* Adjacent reverse-video rows (bar pairs, stacked highlighted buttons) can
   show a hairline seam where their backgrounds meet -- the terminal grid is
   CSS-scaled to fit the viewport (see app.js), and scaling by a fractional
   factor introduces sub-pixel rounding at each row boundary. Overlapping
   rows by 1px (via the negative margin above) makes adjacent same-color
   blocks bleed into each other instead of leaving a gap. `overflow: visible`
   lets that 1px of background show past the row's own box; segments are
   still clipped to 80ch by .screen-segment itself. */

.browser-illustration {
  position: absolute;
  z-index: 3;
  top: 5.1em;
  right: 3ch;
  width: 27ch;
  min-height: 7.5em;
  margin: 0;
  padding: 0.6em 1ch 0.5em;
  border: 1px solid #8cecff;
  background: rgb(122 78 150 / 84%);
  color: #bfe7ff;
  pointer-events: none;
}

.browser-illustration-art {
  margin: 0;
  color: #8cecff;
  font: inherit;
  line-height: 1;
  letter-spacing: 0;
  text-align: left;
  white-space: pre;
}

.browser-illustration-art.is-pixel-art {
  display: grid;
  width: max-content;
  margin: 0.15em auto 0;
  line-height: 1;
  white-space: normal;
}

.browser-pixel {
  width: 0.56em;
  height: 0.56em;
}

.browser-pixel.is-on {
  background: #8cecff;
  box-shadow: inset -1px -1px 0 rgb(45 185 208 / 42%);
}

.browser-illustration-image {
  display: block;
  width: 100%;
  height: auto;
  margin: 0.15em auto 0;
  image-rendering: pixelated;
}

.browser-illustration-caption {
  margin-top: 0.45em;
  overflow: hidden;
  color: #fff;
  font-size: 0.78em;
  line-height: 1.15;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A picture is the picture, not a picture in a box. The panel behind it put a
   second background under a drawing that already carries its own, and on the
   purple line art that read as an ugly slab: "האיורים בצבע רקע סגול כזה? זה
   נורא מכוער". The frame stays for ASCII and pixel art, which need an edge to
   be read against; a real image is left to stand on the screen. */
.browser-illustration.is-plain-image {
  border: 0;
  padding: 0;
  background: none;
}

.browser-illustration.is-plain-image .browser-illustration-image {
  margin: 0;
}

/* Illustrated multiple-choice: centered picture, numbers under each sub-image,
   and no surrounding frame. */
.browser-illustration.is-image-choice {
  position: absolute;
  z-index: 3;
  top: 6.5em;
  right: auto;
  left: 50%;
  width: 60ch;
  max-width: 90%;
  min-height: 0;
  padding: 0;
  border: none;
  background: transparent;
  transform: translateX(-50%);
}

/* Fixed height so short and tall pictures both put the numbers (and the
   "תשובתך:" line below them) in the same place — no big empty gap. */
.browser-illustration.is-image-choice .browser-illustration-image {
  width: 100%;
  height: 12.5em;
  margin: 0 auto;
  object-fit: contain;
  image-rendering: auto;
}

.browser-illustration-slots {
  position: relative;
  direction: ltr;
  width: 100%;
  height: 1.5em;
  margin-top: 0.15em;
}

.browser-illustration-slot {
  position: absolute;
  top: 0;
  left: var(--slot-position);
  min-width: 1.4em;
  padding: 0 0.15em;
  color: #bfe7ff;
  font-weight: 700;
  text-align: center;
  transform: translateX(-50%);
}

.browser-illustration-slot.is-correct {
  border-radius: 3px;
  background: #bfe7ff;
  color: #00005f;
}

.browser-illustration-slot.is-wrong {
  color: #ff9a9a;
  text-decoration: line-through;
}

/* Per-picture answer slots: active = blinking "?", filled = typed number,
   correct = highlighted, wrong = red. */
.browser-illustration-slot.state-active {
  color: #fff;
  animation: cursor-blink 1s steps(1, end) infinite;
}

.browser-illustration-slot.state-empty {
  color: #6f86c8;
}

.browser-illustration-slot.state-filled {
  color: #fff;
}

.browser-illustration-slot.state-correct {
  border-radius: 3px;
  background: #bfe7ff;
  color: #00005f;
}

.browser-illustration-slot.state-wrong {
  color: #ff9a9a;
}

.browser-illustration-slot-label {
  position: absolute;
  top: 0;
  right: 0.5ch;
  color: #bfe7ff;
  font-weight: 700;
}

/* The English prompt sentence in the illustrated demo, made bold + bright so it
   stays legible over the dark background. */
.role-demo-english {
  color: #fff;
  font-weight: 700;
}

/* Blinking answer cursor in the terminal lessons (the reading/illustrated pages
   already have their own). */
.pedagogical-cursor {
  background: #bfe7ff;
  color: #00005f;
  animation: cursor-blink 1s steps(1, end) infinite;
}

@keyframes cursor-blink {
  0%,
  49% {
    opacity: 1;
  }

  50%,
  100% {
    opacity: 0;
  }
}

.screen-segment {
  position: absolute;
  top: 0;
  display: inline-block;
  max-width: 80ch;
  overflow: hidden;
  white-space: pre;
}

.align-left {
  left: calc(var(--cell-margin) * 1ch);
}

.align-center {
  left: 50%;
  transform: translateX(-50%);
}

.align-right {
  right: calc(var(--cell-margin) * 1ch);
}

.direction-ltr {
  direction: ltr;
  unicode-bidi: isolate;
  text-align: left;
}

.direction-rtl {
  direction: rtl;
  unicode-bidi: isolate;
  text-align: right;
}

.role-title {
  font-weight: 700;
}

.role-diagnosis-title {
  font-weight: 700;
  font-size: 0.8em;
}

.role-diagnosis-star {
  color: #ffd700;
  font-weight: 700;
}

/* Diagnosis sitting-number pill: a small filled white capsule in the top-left of
   the header carrying just the current sitting number. Replaces the old yellow
   asterisk. The segment is absolutely positioned in the monospace grid, so the
   pill hugs the digits with a little padding and a rounded background. */
.role-lesson-pill {
  background: #ffffff;
  color: #001033;
  font-weight: 700;
  border-radius: 0.8em;
  padding: 0.04em 0.55ch;
  line-height: 1;
  box-shadow: 0 0.06em 0.12em rgba(0, 0, 0, 0.35);
}

/* Focus-session mark: a small gold dot on the header row, in the diagnosis
   star's spot. The pupil sees an ordinary lesson; the dot is the teacher's
   way of telling, at a glance, that this screen is a targeted-practice
   session. Deliberately unlabeled on the pupil's screen. */
.role-focus-dot {
  color: #ffd700;
  font-weight: 700;
}

/* Lesson progress meter on the header row: one dot per exercise (arithmetic) or
   per tenth of the session clock (English/Bagrut). Solved dots are green and
   remaining ones are dimmed, so "how much is left" reads at a glance without
   the pupil having to read anything. The server emits the two runs as separate
   segments and positions them by column, so nothing here may change the glyph
   width -- no letter-spacing, no bold, no font-size. */
.role-lesson-progress-done {
  color: #7fe0a8;
}

.role-lesson-progress-todo {
  color: #4a6fa5;
}

.role-rule {
  color: #8cecff;
}

.role-feedback {
  font-weight: 700;
}

.role-crossword-solved {
  color: #7c8aad;
}

.role-start-button {
  font-weight: 700;
  color: #071a3a;
  background: #8cecff;
  padding: 0 1.5ch;
  border-radius: 4px;
}

/* One-time welcome screens (first arithmetic / English lesson): the "how to
   start" line, shown as bold black text on a white highlight box. */
.role-start-prompt {
  color: #000;
  background: #fff;
  font-weight: 700;
  padding: 0 1ch;
}

/* A centred row of nav buttons on an orientation intro screen: green "קדימה"
   to start, red "אחורה" to step back. They match the on-screen keyboard keys —
   coloured outline and text on transparent, filling with navy text while
   pressed. The group is absolutely centred on its 1em row and allowed to
   overflow into the blank rows above and below it. */
.screen-button-row {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  direction: rtl;
  gap: 3ch;
  align-items: center;
  z-index: 3;
}

.screen-nav-button {
  padding: 0.5em 1.7em;
  border: 3px solid;
  border-radius: 6px;
  background: transparent;
  font-family: inherit;
  font-size: 1em;
  font-weight: 700;
  line-height: 1;
  white-space: pre;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 70ms, color 70ms;
}

.screen-nav-button.is-proceed {
  border-color: #7fe0a8;
  color: #7fe0a8;
}

.screen-nav-button.is-proceed:hover {
  background: rgba(127, 224, 168, 0.14);
}

.screen-nav-button.is-proceed:active,
.screen-nav-button.is-proceed.is-pressed {
  background: #7fe0a8;
  color: #00005f;
}

.screen-nav-button.is-back {
  border-color: #ff8a8a;
  color: #ff8a8a;
}

.screen-nav-button.is-back:hover {
  background: rgba(255, 138, 138, 0.14);
}

.screen-nav-button.is-back:active,
.screen-nav-button.is-back.is-pressed {
  background: #ff8a8a;
  color: #00005f;
}

/* First-run welcome: a big smiling greeting shown over the menu for a few
   seconds right after a brand-new pupil picks their avatar. The face pops in,
   then the two lines rise up under it; the whole card fades out afterwards. */
.toam-welcome-overlay {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1em;
  background: #00005f;
  color: #bfe7ff;
  text-align: center;
  padding: 4vw;
  box-sizing: border-box;
  opacity: 0;
  transition: opacity 450ms ease;
}

.toam-welcome-overlay.is-in {
  opacity: 1;
}

.toam-welcome-face {
  font-size: min(30vw, 34vh);
  line-height: 1.05;
  opacity: 0;
  transform: scale(0.55) translateY(0.08em);
  transition: transform 650ms cubic-bezier(0.2, 1.35, 0.35, 1), opacity 500ms ease;
}

/* When the face is the pupil's chosen avatar (an SVG badge) rather than an
   emoji, size it as a round box and ring it so it clearly reads as "their"
   avatar coming to greet them. */
.toam-welcome-face.is-avatar {
  width: min(40vw, 38vh);
  height: min(40vw, 38vh);
  border-radius: 50%;
  box-shadow: 0 0 0 0.14em rgba(140, 236, 255, 0.6),
    0 12px 34px rgba(0, 0, 0, 0.42);
}

.toam-welcome-face.is-avatar svg {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

.toam-welcome-title,
.toam-welcome-sub {
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
  opacity: 0;
  transform: translateY(0.45em);
  transition: transform 600ms ease, opacity 600ms ease;
}

.toam-welcome-title {
  font-size: min(10vw, 11vh);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: #8cecff;
  margin-top: 0.4em;
  transition-delay: 130ms;
}

.toam-welcome-sub {
  font-size: min(6.5vw, 7vh);
  font-weight: 500;
  letter-spacing: 0.005em;
  color: #7fe0a8;
  transition-delay: 250ms;
}

.toam-welcome-overlay.is-in .toam-welcome-face {
  opacity: 1;
  transform: scale(1) translateY(0);
}

/* The chosen avatar pops in with a friendly overshoot and then keeps a gentle,
   life-like bob so it feels like it is greeting the pupil for the whole time the
   screen is up. */
.toam-welcome-overlay.is-in .toam-welcome-face.is-avatar {
  animation: toam-welcome-pop 700ms cubic-bezier(0.2, 1.35, 0.35, 1) both,
    toam-welcome-bob 2.8s ease-in-out 700ms infinite;
}

@keyframes toam-welcome-pop {
  0% {
    opacity: 0;
    transform: scale(0.55) translateY(0.1em) rotate(-7deg);
  }
  65% {
    opacity: 1;
    transform: scale(1.07) translateY(-0.02em) rotate(4deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) translateY(0) rotate(0deg);
  }
}

@keyframes toam-welcome-bob {
  0%,
  100% {
    transform: translateY(0) rotate(0deg);
  }
  30% {
    transform: translateY(-0.06em) rotate(-3deg);
  }
  65% {
    transform: translateY(-0.015em) rotate(3deg);
  }
}

/* For the avatars given a greeting smile (the fox, the rabbit), the smile itself
   appears a beat after the avatar lands — a little "breaks into a smile" moment. */
.toam-welcome-overlay.is-in .toam-welcome-face.is-avatar .welcome-smile {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: toam-welcome-smile 480ms ease 900ms both;
}

@keyframes toam-welcome-smile {
  0% {
    opacity: 0;
    transform: scale(0.4) translateY(0.06em);
  }
  60% {
    opacity: 1;
    transform: scale(1.12);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Pupils who ask their device to reduce motion still get the avatar, its smile
   and the greeting — just the calm fade-in, no bobbing or growing. */
@media (prefers-reduced-motion: reduce) {
  .toam-welcome-overlay.is-in .toam-welcome-face.is-avatar {
    animation: toam-welcome-pop 500ms ease both;
  }
  .toam-welcome-overlay.is-in .toam-welcome-face.is-avatar .welcome-smile {
    opacity: 1;
    animation: none;
  }
}

.toam-welcome-overlay.is-in .toam-welcome-title,
.toam-welcome-overlay.is-in .toam-welcome-sub {
  opacity: 1;
  transform: translateY(0);
}

/* Handover notice: shown when this screen yields because the pupil signed in on
   another device. Calm, with one button to sign back in here. */
.toam-handover-overlay {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  background: #00005f;
  color: #bfe7ff;
  text-align: center;
  padding: 6vw;
  box-sizing: border-box;
}

.toam-handover-face {
  font-size: min(18vw, 22vh);
  line-height: 1.1;
}

.toam-handover-title {
  font-family: inherit;
  font-weight: 800;
  font-size: min(7vw, 8vh);
  color: #8cecff;
}

.toam-handover-sub {
  font-family: inherit;
  font-weight: 600;
  font-size: min(4vw, 4.5vh);
  color: #bfe7ff;
  max-width: 22ch;
}

.toam-handover-button {
  margin-top: 0.6em;
  padding: 0.55em 2em;
  border: 3px solid #7fe0a8;
  border-radius: 8px;
  background: transparent;
  color: #7fe0a8;
  font-family: inherit;
  font-weight: 800;
  font-size: min(4.5vw, 5vh);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 70ms, color 70ms;
}

.toam-handover-button:hover {
  background: rgba(127, 224, 168, 0.14);
}

.toam-handover-button:active {
  background: #7fe0a8;
  color: #00005f;
}

/* On touch devices (tablets/phones) the student starts with the on-screen
   "קדימה" button, so the decorative "מתחילים" button is hidden there. */
@media (pointer: coarse) {
  .role-start-button {
    display: none;
  }
}

/* Student-number prompt on the login screen: bigger than the surrounding
   text so it stands out as the field to type into. Scale from the right edge
   so enlarging it does not drift the text toward the center — it stays
   flush-right with the rest of the screen. */
.role-login-field {
  font-weight: 700;
  transform: scale(1.5);
  transform-origin: right center;
}

/* Login notices (e.g. "already signed in on another screen"): a highlighted
   white box with black text so the message is easy to read. */
.role-login-notice {
  color: #000;
  background: #fff;
  font-weight: 700;
  padding: 0 1ch;
}

.crossword-board {
  position: absolute;
  z-index: 4;
  top: 5.05em;
  left: 1ch;
  display: flex;
  flex-direction: column;
  gap: 1px;
  pointer-events: none;
}

.crossword-board-labels,
.crossword-board-row {
  display: flex;
  flex-direction: row;
}

.crossword-board-label,
.crossword-cell,
.crossword-board-rownum {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 2.2ch;
  height: 1.1em;
  font-family: inherit;
  font-size: 0.95em;
  line-height: 1;
}

.crossword-board-label {
  color: #8cecff;
  font-weight: 700;
}

.crossword-board-rownum {
  width: 2.8ch;
  color: #8cecff;
  font-size: 0.78em;
}

.crossword-cell {
  border: 1px solid rgb(191 231 255 / 25%);
  color: #bfe7ff;
  background: transparent;
}

.crossword-cell.is-closed {
  border-color: transparent;
  background: transparent;
}

.crossword-cell.is-open {
  background: rgb(191 231 255 / 14%);
}

.crossword-cell.is-current {
  border-color: #8cecff;
  background: #8cecff;
  color: #00005f;
  font-weight: 700;
}

.pedagogical-cursor {
  display: inline-block;
  min-width: 1ch;
  color: #00005f;
  background: #bfe7ff;
  animation: pedagogical-blink 900ms steps(1, end) infinite;
}

/* Clean block caret for the writing composition: a solid filled block (a space with a
   full background), so it never depends on a font having the "█" glyph. */
.pedagogical-cursor.cursor-plain {
  background: #bfe7ff;
  color: #bfe7ff;
}

.pedagogical-answer-highlight {
  display: inline-block;
  color: #00005f;
  background: #bfe7ff;
  font-weight: 700;
  padding: 0 0.15ch;
}

/* Selection highlight for the composition editor: must NOT change the cell width
   (no inline-block / no padding), otherwise the highlighted run widens the row and
   pushes the frame's right border off to the side. */
.pedagogical-answer-highlight.selection-plain {
  display: inline;
  padding: 0;
  font-weight: normal;
}

/* Blocked-paste notice: a bright bar so it clearly stands out from the key help. */
.role-notice {
  color: #00005f;
  background: #ffffff;
  font-weight: 700;
}

@keyframes pedagogical-blink {
  0%,
  44% {
    color: #00005f;
    background: #bfe7ff;
  }

  45%,
  100% {
    color: #bfe7ff;
    background: transparent;
  }
}

.keyboard-capture {
  position: absolute;
  width: 1px;
  height: 1px;
  inset: 50% auto auto 50%;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .pedagogical-cursor {
    animation-duration: 1400ms;
  }
}

@media (max-width: 600px) {
  body {
    padding: 4px;
  }

  .startup-copy {
    padding-inline: 1ch;
  }

  .startup-copy p {
    font-size: 0.9em;
  }
}

/* ─── Touch numpad ────────────────────────────────────────────────────────── */
/* Shown only on touch-primary devices (injected by app.js when pointer:coarse). */

.touch-numpad {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  /* Two rows: digits on top, symbols + exit on bottom */
  flex-direction: column;
  align-items: stretch;
  /* LTR so digit keys run left→right and the exit button sits on the far right */
  direction: ltr;
  gap: 5px;
  padding: 8px 10px;
  /* honour iOS home-indicator safe area */
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  background: #000044;
  border-top: 1px solid #62708f;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

/* Each horizontal strip inside the two-row numpad */
.touch-numpad-row {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: 5px;
}

.touch-numpad-key {
  flex: 1;
  min-width: 0;
  padding: 18px 4px;
  border: 3px solid #8cecff;
  border-radius: 4px;
  background: transparent;
  color: #bfe7ff;
  font-family: "Cascadia Mono", "Consolas", "Courier New", monospace;
  /* fluid size: readable on small phone, comfortable on large tablet */
  font-size: clamp(1em, 3.2vw, 1.35em);
  font-weight: 700;
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 70ms, color 70ms;
}

.touch-numpad-key:active,
.touch-numpad-key.is-pressed {
  background: #8cecff;
  color: #00005f;
}

/* Inactive keys: still visible but not pressable */
.touch-numpad-key[disabled] {
  opacity: 0.18;
  pointer-events: none;
}

/* Action button (יציאה / הסבר) — slightly wider, red tint */
.touch-numpad-key.is-action {
  flex: 1.6;
  border-color: #ff9a9a;
  color: #ff9a9a;
  font-size: clamp(0.75em, 2.4vw, 1em);
}

.touch-numpad-key.is-action:active,
.touch-numpad-key.is-action.is-pressed {
  background: #ff9a9a;
  color: #00005f;
}

/* "Armed" state: first tap of the exit button asks for a confirming second tap,
   so an accidental single tap can't drop the student out of practice. */
.touch-numpad-key.is-action.is-armed {
  background: #ff9a9a;
  color: #00005f;
  animation: toam-arm-pulse 0.7s ease-in-out infinite alternate;
}
@keyframes toam-arm-pulse { from { opacity: 1; } to { opacity: 0.6; } }

/* Enter / קדימה button — slightly wider, green tint */
.touch-numpad-key.is-enter {
  flex: 1.6;
  border-color: #7fe0a8;
  color: #7fe0a8;
  font-size: clamp(0.75em, 2.4vw, 1em);
}

.touch-numpad-key.is-enter:active,
.touch-numpad-key.is-enter.is-pressed {
  background: #7fe0a8;
  color: #00005f;
}

/* Touch-only "כניסה" button on the startup screen */
.startup-touch-enter {
  margin-top: 1em;
  padding: 0.55em 2.5ch;
  border: 1px solid #8cecff;
  border-radius: 0;
  background: transparent;
  color: #bfe7ff;
  font: inherit;
  font-size: 1.15em;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.startup-touch-enter:active {
  background: #bfe7ff;
  color: #00005f;
}

/* ─── Fullscreen toggle button (touch/tablet only, injected by app.js) ──── */
/* Sits in the top-right corner; semi-transparent so it doesn't distract      */
/* from lesson content, but clearly tappable.                                 */
.touch-fs-btn {
  position: fixed;
  top: 10px;
  right: 10px;
  z-index: 50;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgb(140 236 255 / 40%);
  border-radius: 5px;
  background: rgb(0 0 80 / 55%);
  color: rgb(191 231 255 / 55%);
  font-family: "Cascadia Mono", "Consolas", "Courier New", monospace;
  font-size: 1.15em;
  line-height: 40px;
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 100ms, background 100ms;
  user-select: none;
  -webkit-user-select: none;
}

.touch-fs-btn:active {
  background: rgb(140 236 255 / 22%);
  color: #bfe7ff;
}

/* Icon: "⛶" = expand to full screen, "✕" = exit full screen */
.touch-fs-btn[data-fs="0"]::before {
  content: "⛶";
}

.touch-fs-btn[data-fs="1"]::before {
  content: "✕";
}

/* Farewell screen (high-school, no modules): goodbye image on the left, no box. */
.browser-illustration.is-farewell {
  left: 4ch;
  right: auto;
  top: 7.5em;
  width: 30ch;
  min-height: 0;
  border: none;
  background: transparent;
  padding: 0;
}
.browser-illustration.is-farewell .browser-illustration-image {
  image-rendering: auto;
}
.browser-illustration.is-farewell .browser-illustration-caption {
  display: none;
}


/* TOAM-BADGE : TOAM identity badge in the bottom-right corner of every screen (browser + tablet), so any screen — including the video/explanation screens — is recognizable as TOAM. */
body::after{content:"";position:fixed;bottom:8px;right:10px;z-index:2147483000;width:52px;height:28px;background-color:rgba(255,255,255,.9);background-image:url("data:image/png;base64,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");background-repeat:no-repeat;background-position:center;background-size:auto 17px;border-radius:6px;box-shadow:0 1px 4px rgba(0,0,0,.28);pointer-events:none}
/* Hide the badge only while the on-screen numpad is up so it never overlaps the keys. */
body:has(.touch-numpad:not([hidden]))::after{opacity:0}

/* ---------------------------------------------------------------------------
   "להמשיך לשיעור הבא" — round green button on arithmetic finish screens
   (practice and diagnosis), starting the next lesson without a trip through
   the main menu. Sits clear of the "חזרה לתפריט" button beside it.
   --------------------------------------------------------------------------- */
.next-lesson-button {
  position: fixed;
  bottom: 16px;
  right: 24px;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 132px;
  height: 132px;
  padding: 0;
  border: 3px solid #7bffb0;
  border-radius: 50%;
  background: #1f9d5a;
  color: #f2fff7;
  font-family: inherit;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
  transition: transform 90ms, background 90ms;
}

.next-lesson-button .next-lesson-arrow { font-size: 20px; line-height: 1; }

.next-lesson-button:active { transform: scale(0.94); background: #17804a; }
.next-lesson-button[disabled] { opacity: 0.55; cursor: default; }

@media (pointer: coarse) {
  .next-lesson-button { width: 148px; height: 148px; font-size: 17px; }
}

/* ---------------------------------------------------------------------------
   Graphic main menu.
   Replaces the numbered terminal list with a grid of large icon tiles a child
   can simply touch. Each subject gets its own colour and icon so it is
   recognisable before the label is even read. The number stays in the corner of
   each tile, so keyboard users lose nothing.
   --------------------------------------------------------------------------- */
.menu-screen {
  position: fixed;
  inset: 0;
  z-index: 30;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 20px 20px;
  box-sizing: border-box;
  direction: rtl;
  background: var(--screen-bg, #00005f);
  /* Rounded, friendly Hebrew face for the whole menu (loaded in index.html). */
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
}

.menu-screen-brand {
  font-family: inherit;
  font-size: clamp(30px, 5.4vw, 74px);
  font-weight: 700;
  color: #8cecff;
  line-height: 1.05;
  letter-spacing: 0.02em;
  text-shadow: 0 2px 10px rgba(140, 236, 255, 0.35);
}

/* The terminal underneath is hidden while the graphic menu is up, so the two
   never show at once. */
body.has-graphic-menu .terminal-frame,
body.has-graphic-menu .touch-numpad { display: none; }

.menu-screen-head {
  font-family: inherit;
  font-size: clamp(17px, 2.6vw, 34px);
  font-weight: 500;
  color: #bfe7ff;
  letter-spacing: -0.01em;
  text-align: center;
}

.menu-screen-sub {
  margin-bottom: 8px;
  font-family: inherit;
  font-size: clamp(16px, 2.2vw, 30px);
  font-weight: 600;
  color: #ffd479;
  opacity: 0.95;
  text-align: center;
}

.menu-section {
  width: 100%;
  /* Three tiles per row: six subjects land as two tidy rows on a tablet. */
  max-width: clamp(560px, 72vw, 1020px);
}

.menu-section-heading {
  margin: 6px 0 8px;
  font-family: inherit;
  font-size: clamp(13px, 1.7vw, 16px);
  font-weight: 700;
  color: #bfe7ff;
  text-align: center;
  opacity: 0.85;
}

.menu-grid {
  display: grid;
  /* Fixed-width tiles, centred: a section with one item must not stretch into a
     full-width bar. Every tile is the same size no matter how many there are. */
  /* The tile grows with the screen: on a tablet held at arm's length the old
     fixed 172px read like a phone menu lost on a big display. */
  --menu-tile: clamp(172px, 21vw, 300px);
  grid-template-columns: repeat(auto-fit, minmax(var(--menu-tile), var(--menu-tile)));
  gap: clamp(14px, 2vw, 26px);
  justify-content: center;
}

.menu-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: clamp(148px, 18vw, 250px);
  padding: clamp(14px, 1.6vw, 22px) clamp(12px, 1.4vw, 20px);
  border: 3px solid var(--tile-color, #8cecff);
  border-radius: 24px;
  background: var(--tile-tint, rgba(140, 236, 255, 0.14));
  color: #eaf7ff;
  font-family: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
  transition: transform 110ms ease, background 110ms ease, box-shadow 110ms ease;
}

.menu-tile-icon {
  font-size: clamp(34px, 6vw, 78px);
  line-height: 1;
}

.menu-tile-label {
  font-size: clamp(15px, 2.6vw, 30px);
  font-weight: 700;
  text-align: center;
  line-height: 1.25;
}

/* The keyboard shortcut, tucked into the corner so it informs without shouting. */
.menu-tile-key {
  position: absolute;
  top: 10px;
  inset-inline-start: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(28px, 3vw, 42px);
  height: clamp(28px, 3vw, 42px);
  border: 2px solid var(--tile-color, #8cecff);
  border-radius: 50%;
  color: var(--tile-color, #8cecff);
  font-size: clamp(14px, 1.8vw, 22px);
  font-weight: 700;
  opacity: 0.75;
}

.menu-tile:hover { background: color-mix(in srgb, var(--tile-color) 22%, transparent); }

.menu-tile.is-pressed,
.menu-tile:active {
  transform: scale(0.96);
  background: var(--tile-color, #8cecff);
  color: #04123a;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.menu-tile.is-pressed .menu-tile-key,
.menu-tile:active .menu-tile-key { color: #04123a; border-color: #04123a; }

/* "יציאה" is deliberately smaller and set apart from the learning tiles. */
.menu-footer { width: 100%; max-width: 1000px; display: flex; justify-content: center; }

.menu-tile.is-back {
  min-height: clamp(66px, 8vw, 104px);
  width: min(clamp(220px, 26vw, 380px), 60vw);
  flex-direction: row;
  gap: 12px;
  border-radius: 18px;
}

.menu-tile.is-back .menu-tile-icon { font-size: clamp(28px, 3.4vw, 44px); }
.menu-tile.is-back .menu-tile-key { display: none; }

.menu-note {
  margin: 0;
  color: #ffd479;
  font-family: inherit;
  font-size: 16px;
  font-weight: 700;
  text-align: center;
}

/* Phones: two per row, a little tighter. */
@media (max-width: 560px) {
  .menu-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .menu-tile { min-height: 140px; border-radius: 20px; }
}

/* ---------------------------------------------------------------------------
   Finish-screen actions.
   Two large buttons in the middle of the screen: carry on practising, or stop
   for today. They replace the small corner buttons, which a child could neither
   find nor read, and each says plainly what it does.
   --------------------------------------------------------------------------- */
.finish-actions {
  display: flex;
  flex-direction: row-reverse;
  align-items: stretch;
  justify-content: center;
  gap: 22px;
  direction: rtl;
}

.lesson-action {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 250px;
  min-height: 104px;
  padding: 16px 30px;
  border: 4px solid;
  border-radius: 20px;
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.38);
  transition: transform 100ms ease, filter 100ms ease;
}

.lesson-action-main { font-size: 30px; font-weight: 700; line-height: 1.1; }
.lesson-action-sub { font-size: 21px; font-weight: 600; opacity: 0.95; }

.lesson-action.is-continue {
  border-color: #7bffb0;
  background: #1f9d5a;
  color: #f2fff7;
}

.lesson-action.is-finish {
  border-color: #9db8ff;
  background: #2f3f8f;
  color: #eef3ff;
}

.lesson-action.is-pressed,
.lesson-action:active { transform: scale(0.96); filter: brightness(1.15); }

@media (max-width: 700px) {
  .finish-actions { flex-direction: column; gap: 14px; }
  .lesson-action { min-width: 260px; min-height: 84px; padding: 12px 24px; }
  .lesson-action-main { font-size: 24px; }
}

/* ---------------------------------------------------------------------------
   Finish screen.
   A screen of its own rather than terminal rows: the goodbye picture, the message
   in TOAM's friendly rounded face at a size a child reads across the room, and
   both actions — all inside one frame. Hides the monospace terminal, whose fixed
   one-line rows cannot hold text this large without overlapping.
   --------------------------------------------------------------------------- */
.finish-screen {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  box-sizing: border-box;
  direction: rtl;
  background: var(--screen-bg, #00005f);
}

body.has-finish-screen .terminal-frame,
body.has-finish-screen .touch-numpad { display: none; }

.finish-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  width: min(1000px, 96vw);
  max-height: 96vh;
  padding: 26px 30px 30px;
  box-sizing: border-box;
  border: 3px solid #4a6bd0;
  border-radius: 22px;
  background: rgba(10, 20, 90, 0.35);
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
}

.finish-art {
  width: min(300px, 42vw);
  max-height: 26vh;
  object-fit: contain;
}

.finish-text { text-align: center; }

.finish-line {
  margin: 6px 0;
  color: #eaf7ff;
  font-size: clamp(20px, 2.9vw, 30px);
  font-weight: 500;
  line-height: 1.35;
}

.finish-line.is-title {
  color: #8cecff;
  font-size: clamp(28px, 4.2vw, 44px);
  font-weight: 700;
}

.finish-actions { margin-top: 4px; }

/* =====================================================================
   Per-pupil skins (data-theme)
   ---------------------------------------------------------------------
   A pupil picks a look once; the server stamps it on every frame and
   app.js reflects it as <html data-theme="...">. "classic" is the
   default and defines NO --skin-* variables, so every rule below falls
   back to the original TOAM value and classic renders byte-for-byte as
   before. A skin only re-tints: layout, the blinking "?" cursor, the
   header, the feedback strings and the tablet keyboard are unchanged,
   and no skin adds motion.
   ===================================================================== */

/* --- consumers: apply to any skinned screen; classic hits the fallback --- */
:root[data-theme] .terminal-grid { color: var(--skin-ink, #bfe7ff); }
:root[data-theme] .english-summary { color: var(--skin-ink, #bfe7ff); }
:root[data-theme] .role-rule { color: var(--skin-accent, #8cecff); }
:root[data-theme] .role-lesson-progress-done { color: var(--skin-done, #7fe0a8); }
:root[data-theme] .role-lesson-progress-todo { color: var(--skin-todo, #4a6fa5); }
:root[data-theme] .role-diagnosis-star,
:root[data-theme] .role-focus-dot { color: var(--skin-mark, #ffd700); }
:root[data-theme] .pedagogical-cursor {
  background: var(--skin-cursor-bg, #bfe7ff);
  color: var(--skin-cursor-ink, #00005f);
  animation-name: var(--skin-cursor-anim, pedagogical-blink);
}
:root[data-theme] .pedagogical-answer-highlight {
  background: var(--skin-cursor-bg, #bfe7ff);
  color: var(--skin-cursor-ink, #00005f);
}
:root[data-theme] .finish-card {
  background: var(--skin-panel, rgba(10, 20, 90, 0.35));
  border-color: var(--skin-panel-bd, #4a6bd0);
}
:root[data-theme] .finish-line { color: var(--skin-finish-ink, #eaf7ff); }
:root[data-theme] .finish-line.is-title { color: var(--skin-finish-title, #8cecff); }

/* --- dark skins --- */
:root[data-theme="space"],
.skin-card[data-theme="space"] {
  --screen-bg:
    radial-gradient(1px 1px at 15% 22%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 62% 32%, #ffe9b0 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 82% 16%, #fff 50%, transparent 51%),
    radial-gradient(1px 1px at 38% 68%, #ffffffaa 50%, transparent 51%),
    radial-gradient(1px 1px at 90% 60%, #fff 50%, transparent 51%),
    radial-gradient(900px 500px at 50% -10%, #3a1c74, #1a0b40 60%, #0d0526 100%);
  --skin-ink: #efe6ff;
  --skin-accent: #ffd166;
  --skin-done: #8ef0c0;
  --skin-todo: #6a5a9a;
  --skin-mark: #ffd166;
  --skin-cursor-bg: #ffd166;
  --skin-cursor-ink: #241150;
  --skin-cursor-anim: cursor-blink;
  --skin-panel: rgba(22, 8, 54, 0.55);
  --skin-panel-bd: #4a2c8a;
  --skin-finish-ink: #efe6ff;
  --skin-finish-title: #ffd166;
  color-scheme: dark;
}
:root[data-theme="arcade"],
.skin-card[data-theme="arcade"] {
  --screen-bg: #12003a;
  --skin-ink: #f3e9ff;
  --skin-accent: #ff5db1;
  --skin-done: #37e0b8;
  --skin-todo: #6a4a8a;
  --skin-mark: #ffd166;
  --skin-cursor-bg: #ff5db1;
  --skin-cursor-ink: #12003a;
  --skin-cursor-anim: cursor-blink;
  --skin-panel: rgba(20, 5, 60, 0.6);
  --skin-panel-bd: #4a2a7a;
  --skin-finish-ink: #f3e9ff;
  --skin-finish-title: #ff5db1;
  color-scheme: dark;
}

/* --- light skins --- */
:root[data-theme="nature"],
.skin-card[data-theme="nature"] {
  --screen-bg: linear-gradient(180deg, #eaf7ef, #d8efdc);
  --skin-ink: #2f4f3e;
  --skin-accent: #e8833a;
  --skin-done: #1b7a46;   /* was #3f9d63 - 3.0:1 on this ground */
  --skin-todo: #5f8570;   /* was #9db8a6 - 2.0:1, effectively invisible */
  --skin-mark: #b7791f;
  --skin-cursor-bg: #e8833a;
  --skin-cursor-ink: #ffffff;
  --skin-cursor-anim: cursor-blink;
  --skin-panel: #ffffff;
  --skin-panel-bd: #cfe3d4;
  --skin-finish-ink: #2f4f3e;
  --skin-finish-title: #3f9d63;
  color-scheme: light;
}
:root[data-theme="sun"],
.skin-card[data-theme="sun"] {
  --screen-bg: linear-gradient(180deg, #fff6e6, #ffe6cc);
  --skin-ink: #5a3a1a;
  --skin-accent: #f2792f;
  --skin-done: #1a7a46;   /* was #2f9e5e - 3.0:1 */
  --skin-todo: #8a6a45;   /* was #c9a98a - 1.9:1 */
  --skin-mark: #b7791f;
  --skin-cursor-bg: #f2792f;
  --skin-cursor-ink: #ffffff;
  --skin-cursor-anim: cursor-blink;
  --skin-panel: #ffffff;
  --skin-panel-bd: #f3d9b8;
  --skin-finish-ink: #5a3a1a;
  --skin-finish-title: #f2792f;
  color-scheme: light;
}
:root[data-theme="clean"],
.skin-card[data-theme="clean"] {
  --screen-bg: linear-gradient(160deg, #eef4fb, #e4ecf7);
  --skin-ink: #22314a;
  --skin-accent: #3f78e0;
  --skin-done: #0a6b43;   /* was #1e9e6a - 3.0:1 */
  --skin-todo: #657b99;   /* was #9fb0c8 - 1.9:1, white on white */
  --skin-mark: #b7791f;
  --skin-cursor-bg: #3f78e0;
  --skin-cursor-ink: #ffffff;
  --skin-cursor-anim: cursor-blink;
  --skin-panel: #ffffff;
  --skin-panel-bd: #dbe4ef;
  --skin-finish-ink: #22314a;
  --skin-finish-title: #3f78e0;
  color-scheme: light;
}

/* The lesson meter is the only thing on screen that tells a child how much is
   left, so both of its colours have a contrast floor against their own skin's
   ground: 4.5:1 for the solved dots, 3:1 for the remaining ones. The dark skins
   always cleared it; all three light ones failed, the remaining dots at 1.9:1.
   Re-measure after any change to --screen-bg. */
/* Light skins: the classic frame's dark inner ring + navy border read as a
   defect on a pale screen, so soften them (classic keeps its exact shadow). */
:root[data-theme="nature"] .terminal-frame,
:root[data-theme="sun"] .terminal-frame,
:root[data-theme="clean"] .terminal-frame {
  border-color: rgba(0, 0, 0, 0.14);
  box-shadow: 0 18px 70px rgb(0 0 0 / 15%), inset 0 0 0 2px rgb(255 255 255 / 60%);
}

/* =====================================================================
   One-time skin picker overlay (mode: theme_picker)
   Shown once after identity-confirmation to a pupil who has not chosen a
   look. Neutral TOAM navy backdrop (the pupil has not picked yet); each
   card previews a real skin via its own data-theme. No motion.
   ===================================================================== */
.theme-picker {
  position: fixed;
  inset: 0;
  /* Use the VISIBLE viewport height on tablets (not the larger layout
     viewport), so the centred content lands in the middle of what the pupil
     actually sees. Falls back to the inset:0 height on old engines. */
  height: 100dvh;
  z-index: 45;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
  padding: 20px;
  box-sizing: border-box;
  direction: rtl;
  background: var(--screen-bg, #00005f);
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
  overflow: auto;
}
body.has-theme-picker .terminal-frame,
body.has-theme-picker .touch-numpad { display: none; }

.theme-picker-title {
  margin: 0;
  color: #eaf7ff;
  font-size: clamp(22px, 3.4vw, 34px);
  font-weight: 700;
  text-align: center;
}
.theme-picker-hint {
  margin: 0;
  color: #8cecff;
  font-size: clamp(14px, 1.9vw, 18px);
  text-align: center;
}
.theme-picker-grid {
  display: grid;
  /* Two skins now, so two columns - a 3-column track left an empty column that
     pushed the pair to one side in RTL. */
  grid-template-columns: repeat(2, 1fr);
  gap: 22px;
  width: min(640px, 94vw);
  justify-content: center;
  margin-top: 6px;
}
@media (max-width: 560px) {
  .theme-picker-grid { grid-template-columns: repeat(2, 1fr); }
}

.skin-card {
  padding: 0;
  border: 3px solid transparent;
  border-radius: 16px;
  overflow: hidden;
  background: #0d1a55;
  cursor: pointer;
  box-shadow: 0 8px 22px rgb(0 0 0 / 35%);
}
.skin-card.is-selected { border-color: #8cecff; }
.skin-card-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 96px;
  background: var(--screen-bg, #00005f);
  color: var(--skin-ink, #bfe7ff);
  font-family: "Cascadia Mono", "Consolas", "Courier New", monospace;
  font-size: 20px;
  font-weight: 700;
  direction: ltr;
}
.skin-card-screen .s-accent { color: var(--skin-accent, #8cecff); }
.skin-card-screen .s-rule {
  width: 46px;
  height: 3px;
  border-radius: 2px;
  background: var(--skin-accent, #8cecff);
}
.skin-card-name {
  display: block;
  padding: 9px 8px;
  background: rgb(0 0 0 / 28%);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
}
.theme-picker-go {
  margin-top: 10px;
  min-width: 180px;
  padding: 14px 26px;
  border: 0;
  border-radius: 12px;
  background: #7fe0a8;
  color: #04351f;
  font: inherit;
  font-size: 20px;
  font-weight: 700;
  cursor: pointer;
}
.theme-picker-go:disabled { opacity: 0.4; cursor: default; }

/* The graphic main menu is shared "home base" chrome, built for the classic
   navy backdrop (light text, translucent tiles). A light skin would turn the
   backdrop pale and wash the tiles and text out, so the menu keeps the classic
   background under every skin - the skin shows on the lessons themselves, not on
   the menu. Classic is already navy, so this changes nothing for it. */
:root[data-theme] .menu-screen { background: #00005f; }

/* =====================================================================
   One-time avatar picker (mode: avatar_picker) + the avatar badge
   Shown once after the skin picker. Neutral TOAM navy backdrop. No motion.
   ===================================================================== */
.avatar-picker {
  position: fixed;
  inset: 0;
  /* Use the VISIBLE viewport height on tablets (not the larger layout
     viewport), so the centred content lands in the middle of what the pupil
     actually sees. Falls back to the inset:0 height on old engines. */
  height: 100dvh;
  z-index: 46;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 20px;
  box-sizing: border-box;
  direction: rtl;
  background: var(--screen-bg, #00005f);
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
  overflow: auto;
}
body.has-avatar-picker .terminal-frame,
body.has-avatar-picker .touch-numpad { display: none; }

.avatar-picker-title {
  margin: 0;
  color: #eaf7ff;
  font-size: clamp(22px, 3.4vw, 34px);
  font-weight: 700;
  text-align: center;
}
.avatar-picker-hint {
  margin: 0;
  color: #8cecff;
  font-size: clamp(14px, 1.9vw, 18px);
  text-align: center;
  max-width: 40ch;
}
.avatar-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 12px;
  width: min(920px, 96vw);
}
.avatar-card {
  padding: 10px 6px 8px;
  border: 3px solid transparent;
  border-radius: 16px;
  background: #0d1a55;
  cursor: pointer;
  box-shadow: 0 6px 16px rgb(0 0 0 / 30%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.avatar-card.is-selected { border-color: #8cecff; }
.avatar-card-face { width: 62px; height: 62px; display: block; }
.avatar-card-face svg { width: 100%; height: 100%; display: block; }
.avatar-card-name { color: #cfe0ff; font-size: 12.5px; font-weight: 600; text-align: center; }
.avatar-picker-go {
  min-width: 180px;
  padding: 14px 26px;
  border: 0;
  border-radius: 12px;
  background: #7fe0a8;
  color: #04351f;
  font: inherit;
  font-size: 20px;
  font-weight: 700;
  cursor: pointer;
}
.avatar-picker-go:disabled { opacity: 0.4; cursor: default; }

/* Corner badge: the pupil's avatar by the name, top-right of the terminal
   frame. Sits above the grid; purely identity, no motion. */
.toam-avatar-badge {
  /* Inside the terminal grid so it scales with the text. The server clears the
     grid's top-right corner for it (see _reserve_avatar_corner): the pupil name
     is nudged left and the header rule line is trimmed on the right, so the
     badge sits over blank cells and never touches the name or a line. A thin
     ring ("moat") in the screen-background colour is kept as insurance for the
     few screens that have no header rule to trim. */
  position: absolute;
  z-index: 6;
  top: 0.1em;
  right: 0.5em;
  width: 1.5em;
  height: 1.5em;
  border-radius: 50%;
  overflow: hidden;
  pointer-events: none;
  box-shadow:
    0 0 0 0.12em var(--screen-bg, #00005f),
    0 0.08em 0.25em rgb(0 0 0 / 40%);
}
.toam-avatar-badge svg { width: 100%; height: 100%; display: block; }

/* Finish screen: a larger, gentle presence of the avatar above the message. */
.finish-avatar {
  width: min(120px, 26vw);
  height: min(120px, 26vw);
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 6px 18px rgb(0 0 0 / 35%);
}
.finish-avatar svg { width: 100%; height: 100%; display: block; }

/* ── Opening-screen profiles + 4-digit code screen ──────────────────────────
   The tablet's opening screen shows one face per saved pupil (plus an "add"
   chip); tapping a face opens a code screen with four boxes and an on-screen
   keypad. Navy TOAM world, cyan ring on each face, green accents. */
.startup-profiles {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.1em;
  margin-top: 0.9em;
}
.toam-profile-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4em;
  width: 5.2em;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
  -webkit-tap-highlight-color: transparent;
}
.toam-profile-face {
  width: 4.2em;
  height: 4.2em;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 0.16em rgba(140, 236, 255, 0.55), 0 6px 16px rgba(0, 0, 0, 0.34);
  transition: transform 140ms ease, box-shadow 140ms ease;
  background: #0a0f52;
  display: grid;
  place-items: center;
}
.toam-profile-face svg { width: 100%; height: 100%; display: block; }
.toam-profile-chip:hover .toam-profile-face,
.toam-profile-chip:focus-visible .toam-profile-face {
  transform: translateY(-2px) scale(1.04);
  box-shadow: 0 0 0 0.16em rgba(140, 236, 255, 0.9), 0 10px 22px rgba(0, 0, 0, 0.42);
}
.toam-profile-chip:active .toam-profile-face { transform: scale(0.97); }
.toam-profile-name {
  font-size: 0.95em;
  font-weight: 600;
  color: #d6e2ff;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.toam-profile-chip.is-add .toam-profile-face {
  /* Same box size as an avatar face — do NOT set font-size here, or the em-based
     width above would scale with it and blow the circle up. */
  color: #8cecff;
  box-shadow: 0 0 0 2px #3a52c8;
  background: #101a5e;
}
.toam-profile-chip.is-add .add-plus {
  font-size: 1.9em;
  font-weight: 300;
  line-height: 1;
}
.toam-profile-chip.is-add .toam-profile-name {
  color: #9fb0e6;
  /* Show the whole label ("תלמיד/ה נוספת") — wrap instead of truncating. */
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.15;
}

.toam-code-overlay {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4vmin;
  box-sizing: border-box;
  background: rgba(0, 0, 40, 0.82);
  backdrop-filter: blur(3px);
  font-family: "Rubik", "Fredoka", "Varela Round", "Segoe UI", Arial, sans-serif;
}
.toam-code-overlay[hidden] { display: none; }
.toam-code-card {
  position: relative;
  /* Sized off the viewport so the whole card scales up comfortably on a tablet
     instead of sitting tiny in the middle of a big screen; everything inside is
     em-based, so this one font-size grows the avatar, boxes and keypad together. */
  font-size: clamp(15px, 2.4vmin, 23px);
  width: min(94vw, 25em);
  max-height: 96vh;
  overflow: auto;
  background: linear-gradient(180deg, #0c1264, #0a0d45);
  border: 1px solid #2b3690;
  border-radius: 1.1em;
  padding: 1.3em 1.2em 1.2em;
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55em;
  text-align: center;
}
.toam-code-back {
  position: absolute;
  inset-inline-start: 0.6em;
  inset-block-start: 0.6em;
  border: 0;
  background: transparent;
  color: #9fb0e6;
  font: 600 0.95em "Rubik", sans-serif;
  cursor: pointer;
  padding: 0.2em 0.4em;
}
.toam-code-face {
  width: 5em;
  height: 5em;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 0.16em rgba(140, 236, 255, 0.6);
  display: grid;
  place-items: center;
  background: #0a0f52;
}
.toam-code-face svg { width: 100%; height: 100%; display: block; }
.toam-code-name { font-size: 1.35em; font-weight: 700; color: #8cecff; }
.toam-code-hint { font-size: 0.85em; color: #9fb0e6; margin-top: -0.2em; }
.toam-code-boxes {
  display: flex;
  gap: 0.5em;
  direction: ltr;
  margin: 0.3em 0 0.1em;
}
.toam-code-boxes span {
  width: 2.1em;
  height: 2.6em;
  border-radius: 0.4em;
  border: 2px solid #4a58c8;
  background: #0a0f52;
  display: grid;
  place-items: center;
  font-size: 1.4em;
  color: #fff;
}
.toam-code-boxes span.is-filled { border-color: #8cecff; box-shadow: 0 0 10px rgba(140, 236, 255, 0.4); }
.toam-code-boxes.is-shake { animation: toam-code-shake 360ms ease; }
@keyframes toam-code-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(7px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(3px); }
}
.toam-code-msg { min-height: 1.3em; font-size: 0.92em; font-weight: 600; color: #ff9d9d; }
.toam-code-keys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5em;
  width: 100%;
  max-width: 15em;
  direction: ltr;
}
.toam-code-key {
  padding: 0.55em 0;
  border: 1px solid #33409a;
  border-radius: 0.55em;
  background: #12185f;
  color: #eaf0ff;
  font: 700 1.3em "Rubik", sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.toam-code-key:active { background: #1b247a; transform: scale(0.97); }
.toam-code-key.is-back { color: #9fb0e6; }
/* The last digit (0) sits in the middle column, backspace to its right. */
.toam-code-keys .toam-code-key:last-child { grid-column: 2; }

/* ==========================================================================
   The boxed display for vertical exercises.

   The screen itself is unchanged: a fixed grid of characters. When a pupil has
   this display turned on, the character rows holding the exercise are hidden
   and this panel is drawn over the band they leave free, giving every digit
   the pupil has to fill a box of its own. Colours come from the pupil's chosen
   skin where it defines them, and from the classic TOAM screen where it does
   not - so a pupil who never picked a look sees TOAM's own blue, cyan and gold.
   ========================================================================== */
.board-layer {
  position: absolute;
  left: 0;
  right: 0;
  display: grid;
  place-items: center;
  z-index: 2;
  pointer-events: none;
  --bd: 24px;
  /* Digits of one number sit close, the way they do on paper. Wide gutters
     between the columns were part of what made a sum read as loose rows of
     separate digits instead of as two numbers - and on a seven-digit answer
     they turned the number into a string of separate characters. */
  --bd-cell: calc(var(--bd) * 0.62);
  --bd-op: var(--bd-cell);
  --board-ink: var(--skin-ink, #eaf4ff);
  --board-accent: var(--skin-accent, #8cecff);
  --board-done: var(--skin-done, #7fe0a8);
  --board-mark: var(--skin-mark, #ffd700);
  --board-line: var(--skin-panel-bd, #2f4a95);
  --board-panel-bg: var(--skin-panel, rgba(8, 14, 80, 0.55));
}
/* A vertical exercise has no frame at all: it stands on the screen the way it
   stands on a page. Only the English board, which is a sentence and a row of
   words rather than a column of figures, keeps a panel around it. */
.board-stack {
  display: grid;
  justify-items: center;
}

.board-panel {
  border: max(1px, calc(var(--bd) * 0.04)) solid var(--board-line);
  border-radius: calc(var(--bd) * 0.5);
  background: var(--board-panel-bg);
  padding: calc(var(--bd) * 0.62) calc(var(--bd) * 1.05);
  display: grid;
  justify-items: center;
}
.board-grid {
  display: grid;
  direction: ltr;
  justify-items: center;
  align-items: center;
  column-gap: calc(var(--bd) * 0.02);
}
.board-digit,
.board-op,
.board-carry {
  display: grid;
  place-items: center;
  line-height: 1;
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  font-variant-numeric: tabular-nums;
}
.board-digit {
  width: var(--bd-cell);
  height: calc(var(--bd) * 1.02);
  font-size: calc(var(--bd) * 0.88);
  font-weight: 500;
  color: var(--board-ink);
}
/* One sign for the whole sum, centred across the numbers it joins - and set a
   little away from them. Once the digit columns were tightened so a number
   reads as a number, a sign sitting in the middle of its own column ended up
   almost touching the first digit. */
.board-op {
  width: var(--bd-op);
  height: 100%;
  align-self: stretch;
  margin-inline-end: calc(var(--bd) * 0.16);
  font-size: calc(var(--bd) * 0.86);
  font-weight: 500;
  color: var(--board-accent);
}
/* The numbers being added are one block, so their rows sit close together -
   far closer than the gap down to the answer, which the line already marks.
   With the old even spacing the sum read as two unrelated rows of digits. */
.board-digit.is-operand {
  height: calc(var(--bd) * 1.04);
}
/* Long division has no operand rows of its own; its digits keep the same
   height as the rest so the frame stays square. */
.board-frame .board-digit {
  height: calc(var(--bd) * 1.02);
}
.board-carry {
  width: var(--bd-cell);
  height: calc(var(--bd) * 0.72);
  font-size: calc(var(--bd) * 0.5);
  font-weight: 700;
  color: var(--board-mark);
}
.board-carry.is-now {
  border: max(1px, calc(var(--bd) * 0.04)) solid var(--board-mark);
  border-radius: calc(var(--bd) * 0.16);
}
.board-rule {
  grid-column: 1 / -1;
  width: 100%;
  height: 0;
  border-top: max(1px, calc(var(--bd) * 0.045)) solid var(--board-accent);
  margin: calc(var(--bd) * 0.14) 0;
}
/* A box appears only where something is still missing. A digit already written
   is part of the exercise now and needs nothing around it - which is what keeps
   a fifteen-row long division from turning into a wall of boxes. The lines are
   the thinnest that still read, and gold is the only accent on the screen. */
.board-cell {
  border: max(1px, calc(var(--bd) * 0.04)) solid var(--board-line);
  border-radius: calc(var(--bd) * 0.2);
  background: transparent;
}
.board-cell.is-done {
  border-color: transparent;
}
.board-cell.is-now {
  border-color: var(--board-mark);
  background: transparent;
  /* A hair narrower than its column, so the box never touches the digit
     standing next to it now that the digits sit close. */
  width: calc(var(--bd) * 0.58);
}
/* The blinking "?" - TOAM's own mark for "this is your turn". It has said that
   on every screen since the first one, so the boxed display says it too, in the
   same character and at the same rhythm. */
.board-caret {
  color: var(--board-mark);
  font-weight: 700;
  animation: board-caret-blink 1.05s steps(1, end) infinite;
}
/* It dims rather than disappears. The classic screen's cursor inverts its
   colours and so is never absent; a "?" that blinks all the way out leaves the
   child looking at an empty box for half of every second. */
@keyframes board-caret-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0.3; }
}
.board-carry.is-now .board-caret {
  font-size: inherit;
}
@media (prefers-reduced-motion: reduce) {
  .board-caret {
    animation: none;
  }
}

/* ==========================================================================
   The resting screen.

   Painted over the whole character grid when TOAM is in maintenance. The
   picture carries the message; the words underneath are short enough to be
   taken in at a glance. Colours follow the pupil's chosen skin where it
   defines them, and TOAM's own blue where it does not.

   The screen is far wider than it is tall, so everything here is sized against
   the screen's HEIGHT. Sizing against the width overflowed the bottom of the
   screen and cut off the return time - the one line a waiting child most
   wants.
   ========================================================================== */
.rest-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  container-type: size;
  display: grid;
  place-items: center;
  overflow: hidden;
  background:
    radial-gradient(120% 100% at 50% 0%, #0a1080 0%, var(--screen-bg, #00005f) 62%, #00003c 100%);
  --rest-ink: var(--skin-ink, #eaf4ff);
  --rest-accent: var(--skin-accent, #8cecff);
  --rest-done: var(--skin-done, #7fe0a8);
  --rest-screen: #0a1070;
  --rest-inner: #00003c;
  --rest-muted: #a9bdea;
  color: var(--rest-ink);
  font-family: "Rubik", "Heebo", "Segoe UI", Arial, sans-serif;
  direction: rtl;
}
.rest-stage {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 2.6cqh;
  padding: 2cqh 3cqw;
  text-align: center;
  max-height: 100%;
}
.rest-art {
  position: relative;
  height: 38cqh;
  display: grid;
  place-items: center;
}
.rest-art svg { height: 100%; width: auto; display: block; }
.rest-z {
  position: absolute;
  font-weight: 900;
  color: var(--rest-accent);
  opacity: 0;
  animation: rest-z-float 3.2s ease-out infinite;
}
.rest-z1 { inset-inline-start: -14cqh; top: 22%; font-size: 9cqh; }
.rest-z2 { inset-inline-start: -22cqh; top: 12%; font-size: 6.4cqh; animation-delay: .9s; }
.rest-z3 { inset-inline-start: -28cqh; top: 4%; font-size: 4.8cqh; animation-delay: 1.8s; }
@keyframes rest-z-float {
  0%   { transform: translateY(0) scale(.7); opacity: 0; }
  25%  { opacity: .95; }
  100% { transform: translateY(-10cqh) scale(1.1); opacity: 0; }
}
.rest-headline {
  font-family: "Heebo", "Rubik", Arial, sans-serif;
  font-weight: 900;
  font-size: 11cqh;
  line-height: 1.1;
}
/* Why TOAM is asleep. This is the line that stops a child wondering whether
   they broke something, so it sits directly under the headline. */
.rest-reason {
  font-size: 5.4cqh;
  line-height: 1.45;
  color: var(--rest-muted);
  max-width: 64cqw;
}
.rest-note {
  font-size: 4.3cqh;
  color: var(--rest-done);
  max-width: 74cqw;
  line-height: 1.45;
}
@media (prefers-reduced-motion: reduce) {
  .rest-z { animation: none; opacity: .55; }
}

/* ==========================================================================
   Long division.

   A different picture from the columns board: a frame instead of columns over
   a rule. The rules it shares are the ones that matter - one box on the screen,
   the one the pupil is on; the thinnest line that still reads; and a help table
   of five anchors rather than a list of every multiple, so it lifts the
   multiplication load without answering the division step.
   ========================================================================== */
/* A fraction drawn inside a line of text: numerator over a bar over the
   denominator, sized to sit on the line without pushing the rows apart. The
   line around it keeps its own direction; the fraction is always read left to
   right, like every number. */
.screen-fraction {
  display: inline-grid;
  justify-items: center;
  direction: ltr;
  vertical-align: middle;
  line-height: 1;
  font-size: 0.82em;
  margin: 0 0.18em;
  transform: translateY(-0.02em);
}
.screen-fraction-bar {
  width: 100%;
  height: 0;
  border-top: max(1px, 0.06em) solid currentColor;
  margin: 0.1em 0;
}

/* --------------------------------------------------------------------------
   English. The sentence is the exercise, so it is what the screen is mostly
   made of; the four words sit under it as one quiet row, and the only accent
   is the hole the pupil is filling.
   -------------------------------------------------------------------------- */
.board-english {
  direction: ltr;
  display: grid;
  justify-items: center;
  row-gap: calc(var(--bd) * 0.72);
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  max-width: var(--board-width-share, 90%);
}
.board-en-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 calc(var(--bd) * 0.34);
  color: var(--board-ink);
  font-size: var(--bd);
  font-weight: 500;
  line-height: 1.25;
}
/* A word never breaks in the middle, so a prefix exercise - the hole and the
   word it belongs to - stays one thing. */
.board-en-word {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.board-en-blank {
  display: inline-grid;
  place-items: center;
  height: calc(var(--bd) * 1.5);
  margin: 0 calc(var(--bd) * 0.06);
  border: max(1px, calc(var(--bd) * 0.05)) solid var(--board-mark);
  border-radius: calc(var(--bd) * 0.2);
}
/* The same rule the columns board follows: a box marks a place still to be
   filled, so once the word is in it the box is gone and only the word is left.
   The width it reserved stays, so nothing on the line moves. */
.board-en-blank.is-done {
  border-color: transparent;
}
/* The Hebrew meaning of the word, when the exercise gives one: present, but
   clearly not part of the English sentence. */
.board-en-gloss {
  direction: rtl;
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.64);
}
.board-en-options {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(var(--bd) * 0.3) calc(var(--bd) * 1.45);
}
.board-en-option {
  display: inline-flex;
  align-items: baseline;
  gap: calc(var(--bd) * 0.4);
  color: var(--board-ink);
  font-size: calc(var(--bd) * 0.86);
  font-weight: 500;
  white-space: nowrap;
}
/* The number is the key the pupil presses, not part of the word, so it is
   quieter than the word and always the same width. */
.board-en-number {
  color: var(--board-ink);
  opacity: 0.5;
  font-size: calc(var(--bd) * 0.62);
  font-variant-numeric: tabular-nums;
  min-width: 1ch;
  text-align: center;
}
/* Items with no hole in the sentence answer with the number itself. */
/* --------------------------------------------------------------------------
   An expression board: one bare exercise on a card, the answer in a box where
   the '?' stood. Same materials as the vertical board - thin lines, one accent
   on the screen, the instruction above the panel and nothing the exercise does
   not need.
   -------------------------------------------------------------------------- */
.board-expression {
  direction: ltr;
  display: grid;
  justify-items: center;
  /* The instruction belongs to the exercise, not above it at a distance. */
  row-gap: calc(var(--bd) * 0.42);
  padding: calc(var(--bd) * 0.1) calc(var(--bd) * 0.35);
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  max-width: var(--board-width-share, 90%);
}

.board-ex-prompt {
  direction: rtl;
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.62);
  text-align: center;
}

.board-ex-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  /* Digits of one number sit close, the way they do on paper; the gap is
     between the parts of the sum, which is where a reader needs the break.
     Wider than this and "4 : 2 = ?" reads as four separate things. */
  gap: calc(var(--bd) * 0.18) calc(var(--bd) * 0.34);
  /* The line keeps the height of an answer box whether or not one is drawn.
     Without this the card lost the box's height the moment the answer was
     typed, the fit loop found the spare room and scaled everything up, and the
     frame appeared to jump size under the pupil's fingers. */
  min-height: calc(var(--bd) * 1.5);
}

/* TRACK10 measures in Hebrew units, so its equations read right to left. Only
   the order of the parts flips; each number inside its own token is still
   written the way numbers are written. */
.board-ex-line.is-rtl {
  direction: rtl;
}

.board-ex-token {
  color: var(--board-ink);
  font-size: calc(var(--bd) * 1.15);
  font-variant-numeric: tabular-nums;
  white-space: pre;
}

.board-ex-sup {
  font-size: 0.6em;
  line-height: 1;
  vertical-align: super;
}

.board-ex-slot,
.board-ex-answer {
  /* One row, always. A grid here made the caret a second grid row and hung the
     "?" under the box.

     The answered token keeps the box's footprint even though no box is drawn
     around it, so the card is the same size before the first digit, between
     digits and after the last one. It used to shrink under the pupil's fingers:
     every keystroke made the line wider and the fit loop scaled the whole card
     down to match. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: pre;
  /* Room for a three-digit answer, which is where the arithmetic tracks live. */
  min-width: calc(var(--bd) * 2.7);
  height: calc(var(--bd) * 1.5);
  padding: 0 calc(var(--bd) * 0.2);
  color: var(--board-ink);
  font-size: calc(var(--bd) * 1.15);
  font-variant-numeric: tabular-nums;
}

/* Only the open slot is drawn. A box means something is still missing here. */
.board-ex-slot {
  border: max(1px, calc(var(--bd) * 0.05)) solid var(--board-mark);
  border-radius: calc(var(--bd) * 0.2);
  font-weight: 600;
}

/* A fraction the way it is written in a book: numerator over a bar over
   denominator. Tracks 11 and 12 write them on one line ("2/6 + 3/6 = 5/?"), so
   without this the pupil met the whole fractions track as flat slashed text
   while every other exercise was drawn properly. */
.board-ex-frac {
  display: inline-flex;
  align-items: center;
  color: var(--board-ink);
  font-variant-numeric: tabular-nums;
}

.board-ex-fracside {
  font-size: calc(var(--bd) * 1.15);
}

.board-ex-fracstack {
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
  /* Centred on the line of the sum, so "2/6 + 3/6" sits level with its plus. */
  justify-content: center;
  padding: 0 calc(var(--bd) * 0.12);
}

.board-ex-frachalf {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: calc(var(--bd) * 1.1);
  height: calc(var(--bd) * 0.95);
  font-size: calc(var(--bd) * 0.9);
  white-space: pre;
}

/* Only the missing half is boxed. A box means something is still missing. */
.board-ex-fracslot {
  border: max(1px, calc(var(--bd) * 0.05)) solid var(--board-mark);
  border-radius: calc(var(--bd) * 0.18);
  min-width: calc(var(--bd) * 1.6);
  font-weight: 600;
}

/* The answered fraction keeps the boxed half's footprint, so the card is the
   same size before the answer and after it - the same reason the plain answered
   token keeps the box's width. It must also undo the shared .board-ex-answer
   height, which is sized for a single line and would squash the stack. */
.board-ex-frac.board-ex-answer {
  min-width: 0;
  height: auto;
  padding: 0;
}

.board-ex-frac.board-ex-answer .board-ex-frachalf {
  min-width: calc(var(--bd) * 1.6);
}

.board-ex-fracbar {
  height: max(1px, calc(var(--bd) * 0.07));
  margin: calc(var(--bd) * 0.09) 0;
  background: var(--board-ink);
  border-radius: 999px;
}

.board-en-slot {
  display: grid;
  place-items: center;
  min-width: calc(var(--bd) * 1.7);
  height: calc(var(--bd) * 1.7);
  border: max(1px, calc(var(--bd) * 0.05)) solid var(--board-line);
  border-radius: calc(var(--bd) * 0.2);
  color: var(--board-ink);
  font-size: calc(var(--bd) * 0.9);
  font-weight: 600;
}
.board-en-slot.is-now {
  border-color: var(--board-mark);
}
.board-division {
  display: flex;
  direction: rtl;
  /* Top-aligned, like the exercise itself: the help table must not slide down
     the screen every time the division grows another step. */
  align-items: flex-start;
  justify-content: center;
  gap: calc(var(--bd) * 1.6);
}
.board-frame {
  display: grid;
  direction: ltr;
  justify-items: center;
  align-items: center;
  column-gap: calc(var(--bd) * 0.07);
  row-gap: calc(var(--bd) * 0.05);
}
/* One element with two borders, so the two lines meet at a real corner
   instead of being two bars that nearly touch. */
.board-div-frame {
  width: 100%;
  height: 100%;
  pointer-events: none;
  border-top: max(1px, calc(var(--bd) * 0.045)) solid var(--board-accent);
  border-right: max(1px, calc(var(--bd) * 0.045)) solid var(--board-accent);
}
.board-div-rule {
  width: 100%;
  height: 0;
  border-top: max(1px, calc(var(--bd) * 0.04)) solid var(--board-line);
}
/* The help table is reference, not part of the answer: one colour, no frame,
   nothing competing with the box the pupil is on. */
.board-help {
  display: grid;
  gap: calc(var(--bd) * 0.09);
  padding: calc(var(--bd) * 0.3) calc(var(--bd) * 0.42);
  border-inline-start: max(1px, calc(var(--bd) * 0.05)) solid var(--board-line);
  font-family: "Rubik", "Segoe UI", Arial, sans-serif;
  color: var(--board-help-ink, #8fa6d8);
  direction: rtl;
}
/* Reference, and it has to LOOK like reference. Set at the size of the digits
   it stands beside, five lines of multiplication table are the biggest thing on
   the screen and the exercise is the small print next to them - so the table is
   set at about half the size of a digit, near enough to read from where the
   child sits and clearly not the thing they are meant to be looking at. */
.board-help-title {
  font-size: calc(var(--bd) * 0.38);
  font-weight: 500;
  text-align: center;
  opacity: 0.85;
  margin-bottom: calc(var(--bd) * 0.08);
}
.board-help-row {
  display: grid;
  grid-template-columns: auto auto;
  gap: calc(var(--bd) * 0.34);
  justify-content: space-between;
  direction: ltr;
  font-size: calc(var(--bd) * 0.48);
  font-variant-numeric: tabular-nums;
}

/* A worded question. There is no arithmetic here to re-typeset, so the card
   holds the whole question in one frame and turns "תשובה: ?" into a box - the
   same box the pupil already knows from every other board. TRACK14 is 448
   exercises of exactly this and had no board at all. */
.board-word {
  direction: rtl;
  display: grid;
  justify-items: center;
  row-gap: calc(var(--bd) * 0.42);
  padding: calc(var(--bd) * 0.1) calc(var(--bd) * 0.35);
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  max-width: var(--board-width-share, 90%);
}

/* "פתור את השאלה הבאה:" is the teacher speaking, not the question. Same weight
   the expression board gives its own instruction, so the two cards read alike. */
.board-wd-prompt {
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.62);
  text-align: center;
}

.board-wd-body {
  display: grid;
  justify-items: center;
  row-gap: calc(var(--bd) * 0.12);
}

/* The server sends the question already broken into the lines the pupil sees on
   the classic screen, so the board keeps those breaks rather than re-wrapping
   and showing a different shape of the same sentence. */
.board-wd-line {
  color: var(--board-ink);
  font-size: calc(var(--bd) * 0.92);
  line-height: 1.35;
  text-align: center;
  white-space: pre-wrap;
}

.board-wd-line.is-ltr {
  direction: ltr;
  font-variant-numeric: tabular-nums;
}

.board-wd-answer {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--bd) * 0.35);
}

.board-wd-label {
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.72);
}

/* Same footprint whether the box is drawn or the answer stands in its place, so
   the question above does not shift as the pupil types. */
.board-wd-slot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: pre;
  min-width: calc(var(--bd) * 2.7);
  height: calc(var(--bd) * 1.5);
  padding: 0 calc(var(--bd) * 0.2);
  color: var(--board-ink);
  font-size: calc(var(--bd) * 1.15);
  font-variant-numeric: tabular-nums;
}

/* Only the open slot is drawn. A box means something is still missing here. */
.board-wd-slot.is-now {
  border: max(1px, calc(var(--bd) * 0.05)) solid var(--board-mark);
  border-radius: calc(var(--bd) * 0.2);
  font-weight: 600;
}

/* A screen built out of stacked fractions. Tracks 11 and 12 write them as three
   rows of characters lined up by column; the card reads those rows back into
   one line, so a worked example ("אם: ... אז: ...") keeps its own order. */
.board-stack {
  direction: rtl;
  display: grid;
  justify-items: center;
  row-gap: calc(var(--bd) * 0.3);
  padding: calc(var(--bd) * 0.1) calc(var(--bd) * 0.35);
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  max-width: var(--board-width-share, 90%);
}

/* "אם:" and "אז:" belong to the exercise, in the same quiet weight the other
   cards give their instruction. */
.board-st-text {
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.62);
  text-align: center;
}

.board-stack .board-ex-line {
  direction: ltr;
}

/* --------------------------------------------------------------------------
   A choice board: the question on a card and the numbered answers under it,
   each in its own box. Tracks 09, 10, 11 and 12 ask this way in Hebrew, and
   the English board would not take them because its options run left to right.
   The number is the key the pupil presses, so it is quieter than the answer
   itself and always the same width.
   -------------------------------------------------------------------------- */
.board-choice {
  direction: rtl;
  display: grid;
  justify-items: center;
  row-gap: calc(var(--bd) * 0.4);
  padding: calc(var(--bd) * 0.1) calc(var(--bd) * 0.35);
  font-family: "Rubik", "Segoe UI", "Heebo", Arial, sans-serif;
  max-width: var(--board-width-share, 90%);
}

.board-ch-prompt {
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.62);
  text-align: center;
}

.board-ch-question {
  display: grid;
  justify-items: center;
  row-gap: calc(var(--bd) * 0.12);
}

/* The server sends the question already broken into the lines the pupil sees
   on the classic screen, so the board keeps those breaks. */
.board-ch-line {
  color: var(--board-ink);
  font-size: calc(var(--bd) * 0.9);
  line-height: 1.35;
  text-align: center;
  white-space: pre-wrap;
}

.board-ch-line.is-ltr {
  direction: ltr;
  font-variant-numeric: tabular-nums;
}

.board-ch-options {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(var(--bd) * 0.3) calc(var(--bd) * 0.55);
}

/* When the answers are one set of units repeated at several sizes, they are
   laid out as the grid they are: a row per size, a column per unit. The eye
   then runs down a single unit instead of hunting through a wrapped row. */
.board-ch-options.is-grid {
  display: grid;
  justify-content: center;
  justify-items: stretch;
}

.board-ch-options.is-grid .board-ch-option {
  justify-content: center;
}

/* One box per answer, so a long list reads as a list and not as a paragraph. */
.board-ch-option {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--bd) * 0.35);
  padding: calc(var(--bd) * 0.14) calc(var(--bd) * 0.42);
  border: max(1px, calc(var(--bd) * 0.035)) solid var(--board-line);
  border-radius: calc(var(--bd) * 0.28);
  background: var(--board-panel-bg);
  color: var(--board-ink);
  font-size: calc(var(--bd) * 0.84);
  font-weight: 500;
}

.board-ch-option.is-ltr {
  direction: ltr;
}

.board-ch-number {
  color: var(--board-ink);
  opacity: 0.5;
  font-size: calc(var(--bd) * 0.6);
  font-variant-numeric: tabular-nums;
  min-width: 1ch;
  text-align: center;
}

.board-ch-value {
  white-space: pre-wrap;
  font-variant-numeric: tabular-nums;
}

/* A fraction option arrives as the three character rows the terminal drew -
   numerator, bar, denominator - and is kept in a monospaced block so it lands
   in the same columns it had on the classic screen. */
.board-ch-stack {
  direction: ltr;
  white-space: pre;
  text-align: center;
  line-height: 1.05;
  font-family: "Consolas", "DejaVu Sans Mono", "Courier New", monospace;
  font-variant-numeric: tabular-nums;
}

.board-ch-answer {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--bd) * 0.35);
}

.board-ch-label {
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.72);
}

/* Same footprint whether the box is drawn or the number stands in its place. */
.board-ch-slot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: pre;
  min-width: calc(var(--bd) * 2.7);
  height: calc(var(--bd) * 1.5);
  padding: 0 calc(var(--bd) * 0.2);
  color: var(--board-ink);
  font-size: calc(var(--bd) * 1.15);
  font-variant-numeric: tabular-nums;
}

/* Only the open slot is drawn. A box means something is still missing here. */
.board-ch-slot.is-now {
  border: max(1px, calc(var(--bd) * 0.05)) solid var(--board-mark);
  border-radius: calc(var(--bd) * 0.2);
  font-weight: 600;
}

/* A hole the pupil has not reached yet: the box is there, so the shape of the
   answer is visible, but nothing blinks in it. Only the hole being typed into
   carries the caret. */
.board-ex-fracslot.is-waiting,
.board-ex-slot.is-waiting {
  opacity: 0.55;
}

/* An exercise written over several lines keeps them stacked and centred, the
   way the classic screen writes them one under the other. */
.board-chain {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--bd) * 0.2);
}

/* A sentence the screen writes under the exercise. Quieter than the exercise
   itself, and the same size as the instruction above it. */
.board-ex-note {
  direction: rtl;
  color: var(--board-ink);
  opacity: 0.62;
  font-size: calc(var(--bd) * 0.62);
  text-align: center;
}

/* A number line, read off the row the classic screen draws with dashes: the
   two ends beside it, the marks along it, and the arrow under the point the
   question is about. */
.board-st-scale {
  display: flex;
  align-items: center;
  gap: calc(var(--bd) * 0.4);
  color: var(--board-ink);
  font-size: calc(var(--bd) * 1.15);
  font-variant-numeric: tabular-nums;
  width: 100%;
  padding: calc(var(--bd) * 0.5) 0 calc(var(--bd) * 0.9);
}

.board-st-track {
  position: relative;
  flex: 1 1 auto;
  min-width: calc(var(--bd) * 8);
  height: calc(var(--bd) * 0.9);
}

.board-st-axis {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: max(1px, calc(var(--bd) * 0.07));
  background: var(--board-line);
}

.board-st-tick {
  position: absolute;
  top: 15%;
  height: 70%;
  width: max(1px, calc(var(--bd) * 0.07));
  background: var(--board-line);
  transform: translateX(-50%);
}

/* The arrow the screen draws as "^", under the line rather than on it, so it
   cannot be mistaken for one of the marks. */
.board-st-arrow {
  position: absolute;
  top: 78%;
  transform: translateX(-50%);
  color: var(--board-mark);
  font-size: calc(var(--bd) * 0.7);
  line-height: 1;
}

/* Answers that are whole sentences stand one under the other, aligned on their
   numbers, the way a printed list of choices does. Four of them side by side
   need four sentences' width, and the card is then scaled down until none of
   them can be read. */
.board-en-options.is-stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--bd) * 0.34);
}

.board-en-options.is-stacked .board-en-option {
  white-space: normal;
  align-items: baseline;
}

/* The number keeps its own column so the sentences start on one line. */
.board-en-options.is-stacked .board-en-number {
  flex: 0 0 auto;
  min-width: calc(var(--bd) * 0.9);
  text-align: right;
}
