/* The one child the practice screen hands to .screen (base.css), which is a
   flex row shared by every tab: the wrapper turns the direction back to a
   column, so the filter bar is a strip across the top and the terminal with
   the task card get all the height that is left. Without it the filter bar
   was a sibling column 467 px wide — 24% of a 1920 screen, 57% of a narrow
   one — with only its top 30 px ever in use. Local on purpose: the other
   screens each stack their own way and must not be touched by this. */
.practice-shell {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
}

.section-filter { padding: 10px 12px 0; font-size: 0.75rem; color: var(--muted); }
.level-filter-label { margin-left: 16px; }

/* flex: none — the strip keeps its own height and never steals any from the
   work area below it, nor gets squeezed by it. */
.practice-shell > .section-filter {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
}

/* Each label already wraps its own <select>; making that pair one nowrap
   flex item is what stops "Уровень:" from breaking onto a line of its own,
   leaving its dropdown stranded next to the previous filter's label. */
.practice-shell .section-filter-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

/* The row's own gap now does the separating; the historic margin would add
   to it. */
.practice-shell .level-filter-label { margin-left: 0; }
.section-filter-select {
  background: var(--panel);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  font-size: 0.75rem;
  padding: 3px 6px;
  /* Списки были 26 px — самая мелкая цель в приложении, а промахнуться по
     выбору раздела обиднее всего: это отбрасывает на другое задание. В rem,
     а не в пикселях: на крупной ступени сама подпись выше 30 px, и жёсткая
     цифра обрезала бы название раздела. */
  min-height: 1.875rem;
}

.empty-note {
  padding: 14px;
  color: var(--muted);
  line-height: 1.55;
  font-size: 0.8125rem;
}

.split { display: flex; gap: 0; flex: 1; min-height: 0; padding: 12px; }
/* Хозяин терминала как элемент флекс-строки .split: разделитель панелей
   задаёт долю ширины инлайном (flex-basis), а min-width: 0 — то, без чего
   терминал отказывается сжиматься уже ниже своего содержимого, когда
   разделитель тянут влево.

   display: flex отсюда убран намеренно. Он остался от разметки, где внутри
   хоста лежал отдельный .term; сейчас LT.Terminal превращает в .term сам
   хост, и его детьми оказываются вывод и строка приглашения — при флексе они
   встают рядом, а не друг под другом. До правки правило вообще не
   действовало: build() затирал класс присваиванием className. */
.split-term { flex-grow: 0; flex-shrink: 1; min-width: 0; }
.split-card {
  flex-grow: 0;
  flex-shrink: 1;
  min-width: 10rem;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 12px 14px;
  font-size: 0.8125rem;
}

.splitter {
  flex: none;
  width: 6px;
  margin: 0 6px;
  position: relative;
  cursor: col-resize;
  touch-action: none;
  user-select: none;
}
.splitter::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  transform: translateX(-50%);
  background: var(--line);
  border-radius: 1px;
}
.splitter:hover::before,
.splitter:focus::before {
  background: var(--green);
}
.splitter:focus {
  outline: none;
}

.card-head { display: flex; justify-content: space-between; font-size: 0.6875rem; color: var(--muted); }
.card-title { margin: 8px 0 6px; font-size: 0.9375rem; }
/* Условие задания — самый читаемый текст в приложении: его перечитывают по
   несколько раз, пока решают. Без предела оно растягивалось на 143 символа в
   строке, когда карточке доставалась широкая доля разделителя. */
.card-brief { margin: 0 0 12px; line-height: 1.55; max-width: 68ch; }

.checklist { list-style: none; margin: 0 0 10px; padding: 0; }
.step { display: flex; gap: 8px; padding: 3px 0; line-height: 1.45; }
.step-mark { color: var(--muted); width: 0.875rem; flex: none; }
.step-ok .step-mark { color: var(--green); }
.step-ok .step-label { color: var(--fg); }
.step-label { color: var(--muted); }
.step-broken { color: var(--red); font-size: 0.6875rem; }

.card-note { min-height: 1.125rem; font-size: 0.75rem; margin-bottom: 8px; }
.card-note-done { color: var(--green); font-weight: 600; }

.card-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.btn {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--fg);
  font: inherit;
  font-size: 0.75rem;
  padding: 5px 10px;
  /* Кнопка была 28 px в высоту при общепринятом минимуме цели в 32. Высота
     задана минимумом, а не жёстко, чтобы при увеличенном масштабе интерфейса
     кнопка росла вместе с надписью, а не обрезала её. inline-flex нужен
     потому, что min-height на инлайновом элементе не действует. */
  min-height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
  cursor: pointer;
}
.btn:hover { background: rgba(128, 140, 160, 0.15); }
.btn:disabled { opacity: 0.4; cursor: default; }

.hint {
  border-left: 2px solid var(--green);
  padding: 6px 10px;
  margin-bottom: 6px;
  background: rgba(94, 194, 126, 0.08);
  line-height: 1.5;
}

.solution, .selfmode, .explain {
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 10px;
  margin-top: 8px;
}
.solution-title { font-size: 0.6875rem; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.solution-line {
  margin: 0 0 4px;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 0.75rem;
  background: var(--bg);
  padding: 5px 8px;
  border-radius: 4px;
  white-space: pre-wrap;
  word-break: break-all;
}

/* "Разбор команд": composition of a solution — token left, meaning right —
   never the solution's own line (that stays inside .solution above). */
.explain-list { list-style: none; margin: 0; padding: 0; }
.explain-row {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 3px 0;
  line-height: 1.45;
}
.explain-token {
  flex: none;
  min-width: 4.5rem;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 0.75rem;
  background: var(--bg);
  padding: 2px 6px;
  border-radius: 4px;
  text-align: center;
}
.explain-text { color: var(--muted); }
.explain-empty { color: var(--muted); margin: 0; }
.selfmode-hint { margin: 0 0 8px; line-height: 1.5; color: var(--muted); }
.selfmode-input {
  width: 100%;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 4px;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 0.75rem;
  padding: 6px 8px;
  margin-bottom: 8px;
  resize: vertical;
}
.selfmode-result { margin-top: 8px; line-height: 1.5; }
.selfmode-good { color: var(--green); }
.selfmode-bad { color: var(--red); }

@media (max-width: 900px) {
  .split { flex-direction: column; }
}

.stats { padding: 20px 24px; overflow-y: auto; flex: 1; font-size: 0.8125rem; }
.stats-head { margin-bottom: 20px; }
.stats-xp { font-size: 1.875rem; font-weight: 600; }
.stats-level { font-size: 0.9375rem; color: var(--green); margin-top: 2px; }
.stats-streak, .stats-next { color: var(--muted); margin-top: 4px; }
.stats-h { margin: 0 0 10px; font-size: 0.875rem; }

.sections { display: flex; flex-direction: column; gap: 8px; max-width: 38.75rem; }
/* Колонки в rem, а не в пикселях: в левой стоит название раздела («Работа с
   архивами»), и на крупной ступени масштаба жёсткие 190 px обрезали бы его. */
.section-row { display: grid; grid-template-columns: 11.875rem 1fr 13.75rem; gap: 10px; align-items: center; }
.section-name { color: var(--fg); }
.section-num { color: var(--muted); font-size: 0.75rem; text-align: right; }
.bar { height: 7px; background: rgba(128, 140, 160, 0.2); border-radius: 4px; overflow: hidden; }
.bar-fill { height: 100%; background: var(--green); }

.stats-note { color: var(--muted); margin-top: 22px; max-width: 38.75rem; line-height: 1.55; }

/* The rank ladder (LT.ranks.ladderFor) — every rung, current one picked out,
   locked ones dimmed but still readable. Being able to see "Умница" and the
   two rungs after it is the point (plan: видеть, что впереди ещё ступени,
   важнее, чем не расстраиваться из-за недоступной), so locked rows are
   dimmed, never hidden. */
.rank-ladder {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 26.25rem;
  margin-bottom: 22px;
}

.rank-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 5px;
}

.rank-name { flex: 1; }
.rank-at { color: var(--muted); font-size: 0.75rem; }

.rank-current {
  border-color: var(--green);
  background: rgba(94, 194, 126, 0.1);
}
.rank-current .rank-name { color: var(--green); font-weight: 600; }

.rank-locked { opacity: 0.5; }
.rank-locked-note { color: var(--muted); font-size: 0.6875rem; }

@media (max-width: 700px) {
  .section-row { grid-template-columns: 1fr; gap: 3px; }
  .section-num { text-align: left; }
}
