/* .screen (shared by every tab) is a row flex box, so this screen hands it
   exactly one child that stacks vertically itself — the same rule
   css/memory.css documents for .memory-screen. */
.dojo-screen {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px 20px;
  gap: 10px;
}

.dojo-select {
  padding: 22px 24px;
  max-width: 47.5rem;
  overflow-y: auto;
}

.dojo-title { margin: 0 0 10px; font-size: 1.1875rem; }
.dojo-intro { color: var(--muted); line-height: 1.55; margin: 0 0 16px; }

/* ---- Три блока в списке заданий ---- */

/* Заголовок блока отделён сверху воздухом, а не линией: линий на экране и так
   хватает (у каждой карточки задания своя рамка), и ещё одна читалась бы как
   рамка вокруг блока целиком. */
.dojo-block { margin-top: 22px; }
.dojo-block:first-of-type { margin-top: 0; }

.dojo-block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.dojo-block-title { margin: 0; font-size: 1rem; }

.dojo-block-count {
  flex: none;
  color: var(--muted);
  font-size: 0.75rem;
}

.dojo-level-item {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 10px 14px;
  margin-bottom: 10px;
  background: var(--panel);
}

.dojo-level-title { font-weight: 600; margin-bottom: 4px; }
/* Capped in characters, not pixels: on a FullHD screen the card is wide
   enough for a 100-character line, which is roughly twice the length the eye
   can track back to the start of comfortably. */
.dojo-level-task {
  color: var(--muted);
  line-height: 1.5;
  font-size: 0.8125rem;
  margin-bottom: 8px;
  max-width: 72ch;
}

.dojo-head { display: flex; align-items: center; justify-content: space-between; }
.dojo-level-heading { margin: 0; font-size: 1rem; }
.dojo-task-text { color: var(--muted); line-height: 1.55; margin: 0; max-width: 56.25rem; }

/* ---- Оптимальное число строк ---- */

/* Не предупреждение и не ошибка: цвет рамки — обычный, как у справки, потому
   что премия — это приглашение, а не требование. Тем же зелёным, что у
   .dojo-status-done, коробка кричала бы «получилось!» ещё до того, как
   человек начал решать. */
.dojo-par {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel);
  padding: 8px 12px;
  max-width: 56.25rem;
}

.dojo-par-head { font-weight: 600; font-size: 0.8125rem; margin-bottom: 3px; }
.dojo-par-text { color: var(--muted); font-size: 0.8125rem; line-height: 1.5; margin: 0; }

/* Правило подсчёта — мельче объяснения, но не серее: это единственное место,
   где написано, что именно считается строкой, и выцветшая строка внизу
   коробки читается как сноска, которую можно не читать. */
.dojo-par-rule { font-size: 0.75rem; line-height: 1.45; margin: 5px 0 0; }

.dojo-par-result {
  padding: 6px 12px;
  border-left: 2px solid var(--green);
  background: rgba(94, 194, 126, 0.08);
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* Строка из двух панелей с разделителем между ними, как .split на практике:
   gap: 0, потому что зазор задают поля самой ручки (.splitter в
   css/practice.css).

   flex-wrap отсюда убран намеренно. Разделитель задаёт панелям доли инлайном
   (flex-basis в процентах), их сумма — те же 100 %, и с переносом строки
   ручка со своими полями уже не влезала бы: панель кода уезжала бы под доску
   при любом положении разделителя. Вместо переноса панели сжимаются
   (flex-shrink: 1 и min-width: 0 ниже), а на узком окне их разводит по
   вертикали медиа-запрос в конце файла — как это сделано у .split.

   align-items остаётся flex-start, и это не мелочь. При stretch колонка со
   сценой получает высоту всей строки, то есть высоту панели кода, и всё, что
   в этой колонке лежит, начинает сжиматься, чтобы в неё уложиться: квадратная
   доска шириной 737 px превращалась в полоску высотой 75 px. Высота нужна
   одной только ручке разделителя, и её даёт правило ниже — ей одной. */
.dojo-main {
  display: flex;
  gap: 0;
  flex: 1;
  min-height: 0;
  align-items: flex-start;
}

/* Ручка без высоты — ручка, за которую не ухватиться: при flex-start она была
   бы ростом со своё содержимое, а содержимого у неё нет вовсе. */
.dojo-main > .splitter { align-self: stretch; }

/* The board column: both the 3D canvas and the fallback grid live inside
   .dojo-stage and simply fill it, which is why the size lives here and not on
   either of them. Ширину колонке задаёт разделитель (flex-basis инлайном), а
   не эти правила: min-width: 0 — то, без чего колонка отказывается сжиматься
   ниже своего содержимого, когда разделитель тянут влево. */
.dojo-world {
  flex-grow: 0;
  flex-shrink: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Квадрат — пока помещается по высоте. Разделитель позволяет отдать сцене хоть
   семь десятых окна, а квадрат в семь десятых ширины FullHD — это доска выше
   экрана, за которой пришлось бы прокручивать страницу, чтобы увидеть
   собачку. max-height обрезает именно высоту: сцена становится широкой и
   низкой, камера сама считает расстояние по соотношению сторон
   (js/ui/dojo-3d-camera.js), а плоская сетка просто заполняет то, что есть. */
.dojo-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  max-height: 70vh;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  background: #0e1016;
}

/* Sized by its container, not by attributes: the canvas backing store is set
   in js/ui/dojo-3d.js from clientWidth/clientHeight and devicePixelRatio.
   touch-action keeps a drag from scrolling the page out from under it. */
.dojo-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: grab;
}

.dojo-canvas:active { cursor: grabbing; }

.dojo-view-hint {
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1.4;
  min-height: 1rem;
}

.dojo-grid {
  display: grid;
  gap: 2px;
  width: 100%;
  height: 100%;
  background: var(--line);
  border-radius: 4px;
  padding: 2px;
  flex: none;
}

/* Ни одного цвета клетки здесь больше нет — ни фона, ни косточки, ни пса.
   Их ставит js/ui/dojo-ui.js из js/ui/dojo-palette.js, той же палитры, что
   красит трёхмерную сцену и образцы в легенде под полем. Пока цвета жили
   отдельно в CSS, плоская сетка и сцена показывали разный зелёный, и легенда
   не могла совпасть с обеими сразу. Классы остаются: по ним видно разметку,
   и по ним же ищут клетки в отладке. */
.dojo-cell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
}

/* Цвет рамки выхода тоже из палитры (--exitFrame): здесь только её наличие. */
.dojo-cell-exit { border: 1px solid transparent; }

.dojo-bone {
  position: absolute;
  font-size: 0.625rem;
  top: 4px;
  right: 4px;
}

.dojo-dog {
  font-size: min(4vw, 26px);
  line-height: 1;
  transition: transform 0.15s ease;
}

/* ---- Легенда поля ---- */

/* Стоит в колонке .dojo-world, сразу под доской: подпись нужна там, куда
   смотрят, а место под квадратной сценой всё равно пустует рядом с высокой
   панелью кода. Складывается своей кнопкой — на крупной ступени масштаба семь
   строк с пояснениями заметно выше самой доски. */
.dojo-legend {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel);
}

.dojo-legend-body { padding: 0 12px 10px; }
.dojo-legend-closed .dojo-legend-body { display: none; }

.dojo-legend-note { color: var(--muted); font-size: 0.75rem; line-height: 1.45; margin: 0 0 6px; }

.dojo-legend-list { list-style: none; margin: 0; padding: 0; }

.dojo-legend-item {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding: 4px 0;
}

/* Образец цвета — не иконка со своим смыслом, а тот же квадрат, что на поле,
   поэтому и форма у него квадратная. Размер в rem: на крупной ступени он
   растёт вместе со строкой, рядом с которой стоит. */
.dojo-legend-swatch {
  flex: none;
  position: relative;
  display: block;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.125rem;
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, 0.35);
}

/* Второй цвет образца: светлая шапка стены, рамка выхода, косточка на плитке,
   тёмный низ собачки. Полоска, а не вторая рамка, — она одинаково читается во
   всех четырёх случаях. */
.dojo-legend-accent {
  position: absolute;
  left: 20%;
  right: 20%;
  top: 38%;
  height: 24%;
  border-radius: 1px;
}

/* Название, вызовы и пояснение идут одним абзацем: строка под названием
   стоила бы семь лишних строк, и легенда стала бы выше самой доски. */
.dojo-legend-lines { min-width: 0; font-size: 0.75rem; line-height: 1.5; }

.dojo-legend-name { font-weight: 600; color: var(--fg); margin-right: 5px; }

.dojo-legend-call {
  display: inline-block;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.6875rem;
  color: var(--green);
  background: var(--bg);
  padding: 0 5px;
  border-radius: 4px;
  margin-right: 5px;
}

.dojo-legend-text { color: var(--muted); }

/* Долю ширины задаёт разделитель, поэтому ни flex: 1, ни нижнего предела
   ширины здесь нет: min-width: 20rem не давал бы панели сжаться, и вместо
   сжатия строка уезжала бы за правый край окна. Насколько узкой панель может
   стать, решает не CSS, а границы хода разделителя (SPLIT_MIN/SPLIT_MAX в
   js/ui/dojo-ui.js) — там это одно число, а не правило вёрстки. */
.dojo-code-panel {
  flex-grow: 0;
  flex-shrink: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ---- Редактор кода: номера строк, подсветка, поле ввода ---- */

/* Гнездо кода — колонка (см. .dojo-code-slot ниже), и редактор в ней не
   сжимается: иначе на невысоком окне поле ввода отдало бы свою высоту тому,
   что под ним, и от программы осталась бы полоска в две строки. */
.dojo-editor-box { flex: none; }

/* Высота в rem: на крупной ступени строки кода выше, и жёсткие 260 px
   показывали бы вдвое меньше программы, чем на мелкой. */
.dojo-editor-wrap {
  display: flex;
  height: 16.25rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  resize: vertical;
}

/* Кольцо фокуса рисует рамка, а не само поле: поле лежит внутри и его
   собственное кольцо оказалось бы под краем рамки. */
.dojo-editor-wrap:focus-within { outline: 2px solid var(--green); outline-offset: 2px; }

/* Номера не выделяются мышью: протаскивание по коду иначе захватывало бы их,
   и скопированный фрагмент приезжал бы с номерами вперемешку с кодом. Цвет и
   выключка вправо — те же, что у .dojo-code-lineno в режиме исполнения, чтобы
   номер не менял вид при переходе от правки к запуску. Шрифт, размер и
   межстрочный интервал обязаны совпадать с полем ввода, иначе номера уедут
   относительно строк; за этим следит tests/dojo-editor.test.js. */
.dojo-gutter {
  flex: none;
  min-width: 1.75rem;
  overflow: hidden;
  padding: 10px 8px 10px 10px;
  border-right: 1px solid var(--line);
  color: var(--muted);
  text-align: right;
  white-space: pre;
  user-select: none;
  -webkit-user-select: none;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.8125rem;
  line-height: 1.5;
}

.dojo-editor-area { position: relative; flex: 1; min-width: 0; }

/* Единственное объявление метрик на оба слоя сразу — и это не про краткость.
   Раскрашенный текст лежит ровно под прозрачным полем ввода, и стоит шрифту,
   размеру, межстрочному интервалу, отступам или переносу строк разойтись
   хоть на пиксель, курсор перестанет стоять на своей букве. Разнести эти
   свойства по двум правилам — значит однажды поправить одно и забыть другое;
   tests/dojo-editor.test.js проверяет, что ниже никто не переопределил их
   для одного слоя из двух. */
.dojo-editor-hl,
.dojo-editor {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
  padding: 10px 12px;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.8125rem;
  line-height: 1.5;
  letter-spacing: normal;
  white-space: pre;
  tab-size: 4;
  -moz-tab-size: 4;
}

/* Прокруткой обоих нижних слоёв управляет поле ввода (js/ui/dojo-editor.js):
   своя полоса прокрутки у подложки дала бы вторую полосу поверх первой.
   Сдвигается при этом содержимое, а не сама подложка — почему именно так,
   написано у Editor.prototype.syncScroll. */
.dojo-editor-hl { overflow: hidden; color: var(--fg); pointer-events: none; }
.dojo-editor-hl code { display: block; position: relative; font: inherit; }
.dojo-gutter-inner { position: relative; }

/* Текст поля прозрачен — виден раскрашенный слой под ним, — а курсор нет.
   -webkit-text-fill-color нужен отдельно: Safari иначе возвращает выделенному
   тексту непрозрачный цвет и рисует его вторым слоем поверх раскрашенного. */
.dojo-editor {
  overflow: auto;
  background: transparent;
  color: transparent;
  -webkit-text-fill-color: transparent;
  caret-color: var(--fg);
  resize: none;
  outline: none;
}

/* Выделение полупрозрачно: сплошная заливка закрыла бы раскрашенный текст,
   который лежит под полем, и выделенный фрагмент стал бы нечитаем. */
.dojo-editor::selection { background: rgba(94, 194, 126, 0.3); color: transparent; }
.dojo-editor::-moz-selection { background: rgba(94, 194, 126, 0.3); color: transparent; }

.dojo-editor-hint { color: var(--muted); font-size: 0.75rem; line-height: 1.4; margin: 4px 0 0; }

/* Палитра — та же, что во всём приложении. Из переменных css/base.css сюда
   подходят двe: --green для семи функций собачки (этим же цветом отмечен
   выход с поля и значения переменных) и --muted для комментариев — того
   единственного, что не исполняется вовсе. Оставшимся трём разрядам
   переменных не хватает, и вместо новых цветов взяты значения из той же
   палитры терминала в css/base.css: .c-magenta, .c-yellow и .c-cyan. Красный
   не занят ничем намеренно: в этом приложении он значит ошибку
   (.dojo-status-error, .term-err), и правильная строка в кавычках, набранная
   цветом ошибки, читалась бы как поломка. */
.dojo-hl-kw { color: #c98bdb; }
.dojo-hl-world { color: var(--green); }
.dojo-hl-num { color: #d9b06a; }
.dojo-hl-str { color: #5fc7d4; }
.dojo-hl-comment { color: var(--muted); }

.dojo-code-view {
  height: 16.25rem;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 0;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.8125rem;
  line-height: 1.6;
}

.dojo-code-line { display: flex; padding: 0 12px; white-space: pre; }
.dojo-code-line-active { background: rgba(217, 176, 106, 0.22); }
.dojo-code-lineno { flex: none; width: 1.75rem; color: var(--muted); text-align: right; margin-right: 10px; }
.dojo-code-text { color: var(--fg); }

.dojo-buttons { display: flex; gap: 8px; flex-wrap: wrap; }

.dojo-status {
  padding: 8px 12px;
  border-radius: 5px;
  font-size: 0.8125rem;
  line-height: 1.5;
}

.dojo-status-done { background: rgba(94, 194, 126, 0.16); border: 1px solid var(--green); color: var(--fg); }
.dojo-status-error { background: rgba(226, 104, 109, 0.16); border: 1px solid var(--red); color: var(--fg); }

/* Панель кода собрана из постоянных гнёзд: js/ui/dojo-ui.js перерисовывает
   только верхние три, а кнопки, справка и подсказки под ними живут дольше
   одного тика. Пустое гнездо обязано исчезать целиком — иначе зазор колонки
   (gap) отсчитывался бы и от него, и кнопки съезжали бы вниз на пустом
   месте во время правки кода. */
.dojo-code-slot { display: flex; flex-direction: column; }
.dojo-vars:empty, .dojo-status-slot:empty { display: none; }

/* ---- Значения переменных во время исполнения ---- */

.dojo-vars {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 10px;
  background: var(--panel);
}

.dojo-vars-title {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 4px;
}

.dojo-vars-empty { color: var(--muted); font-size: 0.8125rem; line-height: 1.5; margin: 0; }

.dojo-var-group {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  margin-top: 4px;
}

.dojo-var-func {
  flex: none;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.75rem;
  color: var(--muted);
}

.dojo-var-cell {
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.8125rem;
  background: var(--bg);
  border-radius: 4px;
  padding: 2px 8px;
}

.dojo-var-name { color: var(--fg); }
.dojo-var-eq { color: var(--muted); margin: 0 4px; }
.dojo-var-value { color: var(--green); }
.dojo-var-none { color: var(--muted); font-size: 0.75rem; }

/* ---- Справка ---- */

.dojo-help {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel);
}

/* font: inherit сбрасывает браузерный шрифт кнопки, и только потом ставится
   свой размер — иначе бы он потерялся вместе с остальным сокращением. */
.dojo-help-toggle {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  background: none;
  border: none;
  color: var(--fg);
  font: inherit;
  font-size: 0.8125rem;
  text-align: left;
  padding: 9px 12px;
  cursor: pointer;
}

.dojo-help-toggle:hover { background: rgba(128, 140, 160, 0.1); border-radius: 6px; }
.dojo-help-mark { flex: none; color: var(--muted); }
.dojo-help-body { padding: 0 12px 10px; }
.dojo-help-closed .dojo-help-body { display: none; }

.dojo-help-group { margin-top: 10px; }
.dojo-help-group:first-child { margin-top: 0; }

.dojo-help-group-title {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 2px;
}

.dojo-help-note { color: var(--muted); font-size: 0.75rem; line-height: 1.45; margin: 0 0 6px; }

/* Перенос обязателен: панель кода бывает шириной в 20rem, и колонка вызова
   рядом с длинным пояснением иначе вылезала бы за её край. */
.dojo-help-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  align-items: baseline;
  padding: 3px 0;
  line-height: 1.45;
}

.dojo-help-call {
  flex: none;
  min-width: 7.5rem;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.75rem;
  background: var(--bg);
  padding: 2px 6px;
  border-radius: 4px;
}

.dojo-help-text { flex: 1 1 12rem; font-size: 0.8125rem; line-height: 1.5; color: var(--fg); margin: 0; }

.dojo-help-warn {
  margin: 10px 0 0;
  border-left: 2px solid #d9b06a;
  background: rgba(217, 176, 106, 0.12);
  padding: 6px 10px;
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* Столько колонок, сколько влезает: на FullHD семь заметок ложатся в три-
   четыре ряда вместо метра прокрутки, а на узкой панели auto-fill сам
   сводит их в одну колонку. minmax(...,1fr) не даёт колонке стать шире
   доступного места, поэтому горизонтальной прокрутки не появляется. */
.dojo-help-langs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 6px 16px;
  margin-top: 4px;
}

.dojo-help-lang { min-width: 0; margin-top: 4px; }
.dojo-help-lang-title { font-size: 0.8125rem; margin-bottom: 4px; }

/* Код примера не переносится по словам — перенос разрушил бы отступы, — но
   и не растягивает панель: длинная строка прокручивается внутри себя. */
.dojo-help-code {
  margin: 0 0 4px;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.75rem;
  line-height: 1.5;
  background: var(--bg);
  padding: 6px 9px;
  border-radius: 4px;
  white-space: pre;
  overflow-x: auto;
}

/* ---- Подсказки и решение ---- */

.dojo-aid { display: flex; flex-direction: column; gap: 6px; }
.dojo-aid-note { color: var(--muted); font-size: 0.75rem; line-height: 1.5; margin: 0; }
.dojo-aid-out { display: flex; flex-direction: column; gap: 8px; }
.dojo-aid-out:empty { display: none; }

.dojo-hint {
  border-left: 2px solid var(--green);
  background: rgba(94, 194, 126, 0.08);
  padding: 6px 10px;
}

.dojo-hint-num {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 2px;
}

.dojo-hint-text { margin: 0; font-size: 0.8125rem; line-height: 1.55; }

.dojo-solution {
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 10px;
}

.dojo-solution-title {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 6px;
}

.dojo-solution-code {
  margin: 0;
  font-family: ui-monospace, Consolas, "Courier New", monospace;
  font-size: 0.75rem;
  line-height: 1.55;
  background: var(--bg);
  padding: 8px 10px;
  border-radius: 4px;
  white-space: pre;
  overflow-x: auto;
}

.dojo-solution-note { color: var(--muted); font-size: 0.75rem; line-height: 1.5; margin: 6px 0 0; }

/* На узком окне панели встают друг под друга — тот же отход, что у .split в
   css/practice.css. Доли, выставленные разделителем, при этом относятся к
   высоте, а высота у колонки не задана, и проценты в flex-basis снова
   становятся «по содержимому»: разметка не ломается, просто перестаёт
   слушаться разделителя — на такой ширине двум панелям рядом всё равно не
   поместиться. */
@media (max-width: 900px) {
  .dojo-main { flex-direction: column; }
  .dojo-stage { max-height: none; }
}
