/* =====================================================================
   PONG Terminal — стили
   Чёрно-белая консоль, как tty / xterm по умолчанию: чёрный фон,
   светло-серый текст, только оттенки серого. Без CRT-эффектов, теней
   и скруглений. Только системные шрифты (работает через file://).
   Разделы:
     1. Токены
     2. База и [hidden]
     3. Раскладка и строка заголовка (в инверсии, как статус-строка tmux)
     4. Вывод: типы строк (раздел 3 SPEC)
     5. Инлайн-классы: cmd-link, hl, muted, tag--*
     6. Строка ввода и курсор-блок
     7. Игра
     8. Анимации, адаптивность, prefers-reduced-motion, prefers-contrast
   ===================================================================== */

/* ---------- 1. Токены ---------- */
:root {
  --font-mono: Consolas, "Cascadia Mono", "DejaVu Sans Mono", Menlo, "Courier New", monospace;
  --fs: clamp(13px, 0.45vw + 11px, 16px);
  --lh: 1.45;

  --bg:        #000;
  --fg:        #ccc;   /* обычный текст */
  --fg-bright: #fff;   /* заголовки, акценты, ссылки */
  --fg-dim:    #8c8c8c; /* hint, muted, ключи kv (контраст ≈ 6:1 на чёрном) */
  --line:      #555;   /* рамки и разделители */
  --code-bg:   #0d0d0d;
  --inv-bg:    #ccc;   /* инверсия: светлый фон */
  --inv-fg:    #000;   /*           тёмный текст */

  --gutter: 16px;
}

/* ---------- 2. База ---------- */
[hidden] { display: none !important; }

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
}

/* Без голубой вспышки при касании (Chrome Android) */
html { -webkit-tap-highlight-color: transparent; }

body {
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: var(--fs);
  line-height: var(--lh);
  overflow: hidden;                 /* прокручивается только #output */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

::selection {
  background: var(--fg);
  color: var(--bg);
}

pre, code, kbd, input, button { font-family: inherit; }

/* ---------- 3. Раскладка ---------- */
#app {
  height: 100vh;
  height: 100dvh;
}

#terminal,
#game {
  width: 100%;
  height: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  overflow: hidden;
}

/* Строка заголовка: инверсия на всю ширину, как статус-строка tmux/screen */
#terminal-header,
.win-bar {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 2ch;
  padding: 0 1ch;
  background: var(--inv-bg);
  color: var(--inv-fg);
  line-height: var(--lh);
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
}

.win-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Экскурсия: путь в заголовке меняется на ~/tour */
body[data-tour="1"] .win-path::after { content: "/tour"; }

/* Состояние справа: ЗАГРУЗКА… / ЭКСКУРСИЯ, в обычном режиме пусто */
.win-status { flex: none; }
body[data-booting="1"] .win-status::after { content: "ЗАГРУЗКА…"; }
body[data-tour="1"] .win-status::after { content: "ЭКСКУРСИЯ"; }

/* ---------- 4. Вывод ---------- */
#output {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 8px var(--gutter) 4px;
  overscroll-behavior: contain;
  overflow-wrap: anywhere;
  scrollbar-width: thin;
  scrollbar-color: var(--line) var(--bg);
}
#output::-webkit-scrollbar { width: 10px; height: 10px; }
#output::-webkit-scrollbar-track { background: var(--bg); }
#output::-webkit-scrollbar-thumb { background: var(--line); }

/* Мигающий курсор-блок в конце вывода во время загрузки */
body[data-booting="1"] #output::after {
  content: "\2588";
  content: "\2588" / "";
  display: inline-block;
  color: var(--fg-bright);
  animation: blink 1s steps(1, end) infinite;
}

.line {
  margin: 0;
  min-height: calc(1em * var(--lh));   /* пустая строка = 1 строка высоты */
  white-space: pre-wrap;
}

.line--text { color: var(--fg); }

/* Заголовок: жирный белый + разделитель */
.line--title {
  margin-top: 0.6em;
  color: var(--fg-bright);
  font-weight: bold;
}
.line--title::before {
  content: "## ";
  content: "## " / "";
  color: var(--fg-dim);
}
.line--title::after {
  content: "";
  display: block;
  width: min(100%, 40ch);
  margin: 2px 0 4px;
  border-top: 1px solid var(--line);
}

/* Подзаголовок: жирный, префикс «-- » */
.line--subtitle {
  margin-top: 0.4em;
  color: var(--fg-bright);
  font-weight: bold;
}
.line--subtitle::before {
  content: "-- ";
  content: "-- " / "";
  color: var(--fg-dim);
  font-weight: normal;
}

/* Ошибка: метка «ошибка:» в инверсии + жирный текст */
.line--error {
  color: var(--fg-bright);
  font-weight: bold;
}
.line--error::before {
  content: "ошибка:";
  content: "ошибка:" / "";
  display: inline-block;
  margin-right: 1ch;
  padding: 0 0.5ch;
  background: var(--inv-bg);
  color: var(--inv-fg);
}

.line--hint { color: var(--fg-dim); }

.line--ok { color: var(--fg-bright); }

.line--echo {
  margin-top: 0.5em;
  color: var(--fg-bright);
}
.line--echo .prompt { font-weight: bold; }
.echo-cmd { color: var(--fg-bright); }

/* Ключ — значение: ключи в колонку */
.line--kv {
  display: grid;
  grid-template-columns: minmax(20ch, max-content) minmax(0, 1fr);
  column-gap: 2ch;
  align-items: baseline;
}
.kv-key { color: var(--fg-dim); }
.kv-val { color: var(--fg); min-width: 0; }

/* ASCII-арт и код: без переноса, своя горизонтальная прокрутка */
.line--ascii,
.line--code {
  white-space: pre;
  overflow-x: auto;
  overflow-y: hidden;
  max-width: 100%;
  overflow-wrap: normal;
  word-wrap: normal;
  tab-size: 4;
  -moz-tab-size: 4;
  scrollbar-width: thin;
  scrollbar-color: var(--line) var(--bg);
}
.line--ascii::-webkit-scrollbar,
.line--code::-webkit-scrollbar { height: 8px; }
.line--ascii::-webkit-scrollbar-thumb,
.line--code::-webkit-scrollbar-thumb { background: var(--line); }

.line--ascii {
  color: var(--fg-bright);
  line-height: 1.15;
}

.line--code {
  margin: 6px 0;
  padding: 8px 12px;
  color: var(--fg);
  background: var(--code-bg);
  border: 1px solid var(--line);
  border-left: 3px solid var(--fg);
  line-height: 1.4;
}

/* ---------- 5. Инлайн-классы ---------- */
.cmd-link {
  color: var(--fg-bright);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  cursor: pointer;
}

.cmd-link:hover,
.cmd-link:focus-visible {
  background: var(--fg-bright);
  color: var(--bg);
  text-decoration: none;
  outline: none;
}

.hl {
  color: var(--fg-bright);
  font-weight: bold;
}

.muted { color: var(--fg-dim); }

/* Метки модулей: одинаковые, в квадратных скобках, различаются текстом */
.tag {
  color: var(--fg-bright);
  white-space: nowrap;
}
.tag::before {
  content: "[";
  content: "[" / "";
  color: var(--fg-dim);
}
.tag::after {
  content: "]";
  content: "]" / "";
  color: var(--fg-dim);
}
/* tag--loop, tag--input, tag--physics, tag--output, tag--render, tag--serve
   намеренно выглядят одинаково (монохромная тема). */

/* ---------- 6. Строка ввода и курсор ---------- */
/* Сетка: промпт | поле ввода. Само поле прозрачное (текст и каретка не видны),
   а под ним в той же ячейке лежит #cmd-view — его рисует terminal.js:
   текст + курсор-прямоугольник на клетке символа, как в консоли Linux. */
#input-line {
  flex: none;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 1ch;
  align-items: baseline;
  padding: 2px var(--gutter) 8px;
}

.prompt {
  color: var(--fg-bright);
  font-weight: bold;
  white-space: nowrap;
}

#cmd-input {
  grid-row: 1;
  grid-column: 2;
  position: relative;
  z-index: 1;                   /* поверх #cmd-view: клики и ввод идут в поле */
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: transparent;           /* текст рисует #cmd-view */
  caret-color: transparent;     /* каретку тоже: вместо неё .term-cursor */
  font: inherit;
  font-size: max(16px, 1em);   /* 16px — чтобы iOS не зумил страницу при фокусе */
  line-height: inherit;
  -webkit-appearance: none;
  appearance: none;
  border-radius: 0;
}
#cmd-input::selection { color: transparent; background: transparent; }

#cmd-view {
  grid-row: 1;
  grid-column: 2;
  min-width: 0;
  overflow: hidden;
  white-space: pre;
  font-size: max(16px, 1em);    /* та же метрика, что у #cmd-input */
  line-height: inherit;
  color: var(--fg-bright);
  pointer-events: none;
}

/* Курсор — прямоугольник на всю клетку символа. Символ под ним
   рисуется в инверсии (чёрный на белом), поэтому не сливается с курсором. */
.term-cursor {
  background: var(--fg-bright);
  color: var(--bg);
}
/* Мигает только в фокусе; при каждом нажатии клавиши мигание начинается заново
   (элемент создаётся заново), как в консоли */
#cmd-input:focus ~ #cmd-view .term-cursor {
  animation: cursor-blink 1s steps(1, end) infinite;
}
/* Без фокуса — полый прямоугольник, как в xterm */
#cmd-input:not(:focus) ~ #cmd-view .term-cursor {
  background: transparent;
  color: var(--fg-bright);
  outline: 1px solid var(--fg-bright);
  outline-offset: -1px;
}
/* Выделенный мышью текст — в инверсии */
.term-sel {
  background: var(--fg);
  color: var(--bg);
}
#cmd-input:disabled ~ #cmd-view { color: var(--fg-dim); }
#cmd-input:disabled ~ #cmd-view .term-cursor { display: none; }

/* ---------- 7. Игра ---------- */
#game {
  container-type: inline-size;   /* масштаб поля по ширине окна игры */
  --game-chrome: 220px;          /* высота всего, кроме поля: заголовок, статус, кнопки, подсказка */
  --field-side: 0px;             /* ширина, занятая кнопками по бокам поля (альбомный сенсорный режим) */
  --field-min: 9px;              /* нижний предел шрифта поля (на сенсорных — 7px) */
}

/* Статус-строка игры: в инверсии, как строка tmux */
#game-status {
  flex: none;
  padding: 0 1ch;
  background: var(--inv-bg);
  color: var(--inv-fg);
  white-space: pre-wrap;
}

/* Индикаторы состояния (монохромные символы) */
#game-status::before {
  display: inline-block;
  min-width: 2ch;
  margin-right: 1ch;
  font-weight: bold;
}
#game[data-mode="real"][data-paused="0"]:not([data-over="1"]) #game-status::before {
  content: "\25CF";                /* ● — идёт игра */
  content: "\25CF" / "";
}
#game[data-mode="step"] #game-status::before {
  content: "\25B6|";               /* ▶| — пошагово */
  content: "\25B6|" / "";
}
#game[data-paused="1"] #game-status::before {
  content: "\275A\275A";           /* ❚❚ — пауза */
  content: "\275A\275A" / "";
}
#game[data-over="1"] #game-status::before {
  content: "\25A0";                /* ■ — игра окончена */
  content: "\25A0" / "";
}
#game[data-ai="on"] #game-status::after {
  content: "  [ИИ]";               /* правой ракеткой управляет компьютер */
  content: "  [ИИ]" / "";
  font-weight: bold;
}

/* Поле 80×26.
   Шрифт: не больше 16px, вписывается по ширине (80 колонок ≈ 48–49em с запасом
   на разные моноширинные шрифты) и по высоте (26 строк × 1.1 + интерфейс).
   Нижний предел 9px ради читаемости: на узком экране (≈ до 450px) поле
   шире окна и прокручивается внутри себя по горизонтали, страница — нет. */
#game-field {
  flex: none;
  align-self: center;
  max-width: 100%;
  margin: auto 0 0;
  padding: 0 4px;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: pre;
  overflow-wrap: normal;
  word-wrap: normal;
  color: var(--fg-bright);
  line-height: 1.1;
  font-size: max(9px, min(16px, 1.9vw, calc((100vh - 200px) / 29)));
  font-size: max(var(--field-min), min(16px, calc((100vw - 24px - var(--field-side)) / 50), calc((100dvh - var(--game-chrome)) / 29)));
  font-size: max(var(--field-min), min(16px, calc((100cqi - 16px - var(--field-side)) / 50), calc((100dvh - var(--game-chrome)) / 29)));
  scrollbar-width: thin;
  scrollbar-color: var(--line) var(--bg);
}

#game[data-paused="1"] #game-field { color: #666; }
#game[data-over="1"]   #game-field { color: var(--fg-dim); }

#game-message {
  flex: none;
  min-height: calc(2em * 1.4);
  margin: 8px var(--gutter) auto;
  color: var(--fg-bright);
  text-align: center;
  white-space: pre-line;
  line-height: 1.4;
}
#game[data-over="1"] #game-message { font-weight: bold; }

/* Сенсорные кнопки. Порядок на экране: поле, сообщение, кнопки, подсказка.
   На десктопе блока нет (выход — Esc/Q); кнопки видны только на сенсорных
   устройствах (см. @media (hover: none), (pointer: coarse) ниже). */
#touch-controls {
  order: 1;
  flex: none;
  display: none;
  justify-content: center;
  padding: 0 var(--gutter) 8px;
  user-select: none;
  -webkit-user-select: none;
}

.tc-btn {
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  padding: 0 14px;
  font: inherit;
  line-height: 1.2;
  color: var(--fg-bright);
  background: var(--bg);
  border: 1px solid var(--fg-dim);
  border-radius: 0;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-appearance: none;
  appearance: none;
}
.tc-btn:hover { border-color: var(--fg-bright); }
.tc-btn:active {
  background: var(--fg-bright);
  color: var(--bg);
  border-color: var(--fg-bright);
}
.tc-btn:focus-visible {
  outline: 2px solid var(--fg-bright);
  outline-offset: 2px;
}
/* ИИ ведёт правую ракетку — её кнопки не действуют */
#game[data-ai="on"] .tc-group--right .tc-btn {
  color: var(--fg-dim);
  border-style: dashed;
}

/* Подсказка по управлению — окно по центру поверх игры, только на паузе.
   Рамка и заголовок в инверсии, как окно в консольном TUI. */
#game { position: relative; }
#game-help {
  display: none;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: max-content;
  max-width: calc(100% - 2 * var(--gutter));
  max-height: calc(100% - 2 * var(--gutter));
  overflow: auto;
  padding: 0 0 10px;
  background: var(--bg);
  border: 1px solid var(--fg-bright);
  color: var(--fg);
}
#game[data-paused="1"] #game-help {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
#game-help::before {
  content: "ПАУЗА · УПРАВЛЕНИЕ";
  content: "ПАУЗА · УПРАВЛЕНИЕ" / "";
  display: block;
  margin-bottom: 6px;
  padding: 0 2ch;
  background: var(--inv-bg);
  color: var(--inv-fg);
  font-weight: bold;
  text-align: center;
}
.help-item {
  padding: 0 3ch;
  white-space: nowrap;
}

kbd {
  display: inline-block;
  min-width: 2ch;
  padding: 0 0.5ch;
  margin: 0 1px;
  color: var(--fg-bright);
  text-align: center;
  border: 1px solid var(--fg-dim);
  line-height: 1.3;
  font-size: 1em;
}

/* ---------- 8. Анимации и адаптивность ---------- */
@keyframes blink {
  0%, 49.9% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
/* Курсор не исчезает целиком: в «погасшей» фазе символ под ним виден как обычный текст */
@keyframes cursor-blink {
  0%, 49.9% { background: var(--fg-bright); color: var(--bg); }
  50%, 100% { background: transparent; color: var(--fg-bright); }
}

@media (max-width: 640px) {
  :root { --gutter: 10px; }

  .win-app { display: none; }

  /* kv: ключ над значением, значение с отступом */
  .line--kv { grid-template-columns: minmax(0, 1fr); }
  .kv-val { padding-left: 2ch; }

  .line--code { font-size: 0.9em; padding: 6px 8px; }

  #game-status { font-size: 0.85em; }
  #game-help { gap: 2px; font-size: 0.85em; }
}

/* Сенсорные устройства: полный набор кнопок.
   Слева A/Z, справа K/M, по центру шаг / пауза / режим / ИИ / заново / выход. */
@media (hover: none), (pointer: coarse) {
  /* Поле, видимое целиком, важнее крупного шрифта: предел 7px.
     Если и этого мало — прокрутка; #game тоже может прокручиваться,
     чтобы кнопки (и «выход») никогда не оказались недоступны. */
  #game {
    --game-chrome: 340px;
    --field-min: 7px;
    overflow-y: auto;
  }

  #touch-controls {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: stretch;
    gap: 8px;
  }

  .tc-group--left,
  .tc-group--right {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .tc-group--left .tc-btn,
  .tc-group--right .tc-btn {
    flex: 1;
    min-width: 60px;
    min-height: 52px;
    font-weight: bold;
  }

  .tc-group--center {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    max-width: 420px;
    width: 100%;
    justify-self: center;
  }
  .tc-group--center .tc-btn:not(.tc-btn--exit) { display: block; }
  .tc-group--center .tc-btn {
    padding: 0 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* На сенсорном экране нет «наведения» — не залипает рамка */
  .tc-btn:hover { border-color: var(--fg-dim); }
  .tc-btn:active { border-color: var(--fg-bright); }

  /* Подсказка про клавиатуру на сенсорном экране не нужна: есть кнопки */
  #game[data-paused="1"] #game-help { display: none; }
}

/* Низкие экраны (телефон в альбомной ориентации) */
@media (max-height: 520px) {
  #game .win-bar { display: none; }
}

/* Сенсорный экран в альбомной ориентации (низкий): сетка
     статус  статус  статус
     A/Z     поле    K/M
     A/Z     сообщ.  K/M
     служебные кнопки одной строкой
   #touch-controls становится display: contents, его группы — ячейки сетки #game.
   Подсказка по клавиатуре скрыта: на сенсорном экране она не нужна, а место дорого. */
@media (max-height: 520px) and (hover: none), (max-height: 520px) and (pointer: coarse) {
  #game {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: auto minmax(0, 1fr) auto auto;
    grid-template-areas:
      "status status status"
      "left   field  right"
      "left   msg    right"
      "center center center";
    column-gap: 8px;
    --game-chrome: 112px;   /* статус ≈22 + сообщение ≈20 + ряд кнопок 44 + отступы */
    --field-side: 152px;    /* 2 × (кнопка 60 + отступы) */
  }

  #game-status  { grid-area: status; }
  #game-field   { grid-area: field; margin: auto; align-self: center; justify-self: center; }
  #game-message {
    grid-area: msg;
    min-height: 0;
    margin: 2px 0 0;
    font-size: 0.85em;
    line-height: 1.25;
  }
  #game-help { display: none; }

  #touch-controls { display: contents; }

  .tc-group--left  { grid-area: left;  padding: 6px 0 0 8px; }
  .tc-group--right { grid-area: right; padding: 6px 8px 0 0; }
  .tc-group--left .tc-btn,
  .tc-group--right .tc-btn { min-height: 44px; }

  .tc-group--center {
    grid-area: center;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 6px;
    max-width: 640px;
    padding: 6px 8px;
  }
  .tc-group--center .tc-btn { min-height: 44px; }
}

/* Уменьшенное движение: курсор и индикаторы не мигают */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* Повышенный контраст: светлее приглушённый текст */
@media (prefers-contrast: more) {
  :root {
    --fg: #e6e6e6;
    --fg-dim: #b3b3b3;
    --line: #999;
  }
}
