/* Оформление НИИЧЕГО — рабочее место института.
   Один файл без сборки: страница приходит с сервера готовой, ей не нужен
   ни клиентский рантайм, ни препроцессор.

   Визуальный язык наследован от Scriptorium — софт одного ведомства.
   Схем две, и переключает их не система, а устройство: широкий экран —
   рабочее место в институте (бумага, дневной свет канцелярии), узкий —
   удалённый терминал (синий экран, вечерний доступ по линии). В здании
   всегда день, на линии всегда вечер, поэтому prefers-color-scheme
   институт не слушает.

   Шрифт PxPlus IBM VGA 8x16 — VileR, Ultimate Oldschool PC Font Pack,
   CC BY-SA 4.0. Текст лицензии лежит рядом: px-vga-LICENSE.txt. */

@font-face {
  font-family: "PxVGA";
  src: url("/static/px-vga.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* ── Токены: рабочее место (бумага) ──────────────────────────────────── */

:root {
  --desktop: #b8b4a8;
  --desktop-dot: #aaa69a;
  --frame: #6e6a60;
  --win: #f2f0ea;
  --text: #14140f;
  --muted: #5c584e;
  --line: #a8a49a;
  --sunken: #e2dfd6;

  --bar: #ccc8bc;
  --bar-text: #14140f;
  --accel: #800000;

  --accent: #00006a;
  --accent-fg: #f2f0ea;

  --warn: #8a0000;
  --warn-bg: #f0dcd8;

  /* Тень окна — единственная во всём файле: у окон Turbo Vision она была
     жёсткой, без размытия, и половина узнаваемости держится на ней. */
  --shadow: 3px 3px 0 rgb(0 0 0 / 0.35);

  --font-ui: "PxVGA", ui-monospace, "Courier New", monospace;

  /* Растровый шрифт правилен только на целых кратных своего кегля (8x16),
     поэтому интерфейс размечается в пикселях, а не в rem. */
  --ui: 16px;
  --line-h: 20px;
  --win-max: 72rem;

  /* Оттенки канцелярий: цвет назначается табельным номером, восемь
     цветов по кругу. */
  --tint-0: #00006a;
  --tint-1: #005000;
  --tint-2: #7a4a00;
  --tint-3: #8a0050;
  --tint-4: #4a00a8;
  --tint-5: #005a6a;
  --tint-6: #44521f;
  --tint-7: #9a2000;
}

/* ── Токены: удалённый терминал (синий) ──────────────────────────────── */

@media (max-width: 40rem) {
  :root {
    --desktop: #00a8a8;
    --desktop-dot: #009090;
    --frame: #a8a8a8;
    --win: #0000a8;
    --text: #ffffff;
    --muted: #b0b0cc;
    --line: #5454a8;
    --sunken: #000078;

    --bar: #a8a8a8;
    --bar-text: #000000;
    --accel: #800000;

    --accent: #ffff55;
    --accent-fg: #0000a8;

    --warn: #ff5454;
    --warn-bg: #700000;

    --shadow: none;

    --tint-0: #55ffff;
    --tint-1: #55ff55;
    --tint-2: #ffff55;
    --tint-3: #ff55ff;
    --tint-4: #b0b0ff;
    --tint-5: #55d0ff;
    --tint-6: #d0ff55;
    --tint-7: #ff9955;
  }
}

* { box-sizing: border-box; }

/* ── Рабочий стол ────────────────────────────────────────────────────── */

/* Дизеринг стола — тот самый символ ░ из текстового режима, собранный
   двумя градиентами: клетка 2x2 пикселя, никакой картинки. */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: var(--desktop);
  background-image:
    linear-gradient(45deg, var(--desktop-dot) 25%, transparent 25%,
                    transparent 75%, var(--desktop-dot) 75%),
    linear-gradient(45deg, var(--desktop-dot) 25%, transparent 25%,
                    transparent 75%, var(--desktop-dot) 75%);
  background-size: 4px 4px;
  background-position: 0 0, 2px 2px;
  color: var(--text);
  font: normal var(--ui)/var(--line-h) var(--font-ui);
  /* Сглаживание растровому шрифту противопоказано: оно размывает пиксель,
     ради которого шрифт и взят. */
  -webkit-font-smoothing: none;
}

a { color: var(--accent); }

/* Рамка фокуса точечная — так её рисовал Windows, и она же остаётся
   вполне рабочим указателем для клавиатуры. */
:focus-visible {
  outline: 1px dotted currentColor;
  outline-offset: 1px;
}

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

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── Строка меню ─────────────────────────────────────────────────────── */

.menubar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bar);
  color: var(--bar-text);
  border-bottom: 1px solid var(--frame);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--ui);
  padding: 2px 8px;
}

.menubar a {
  color: var(--bar-text);
  text-decoration: none;
  padding: 0 6px;
}
/* Выбор пункта — инверсия, как в текстовом режиме: подчёркивания и смены
   цвета там не было, был цветной прямоугольник под словом. */
.menubar a:hover,
.menubar a:focus-visible,
.menubar a.current {
  background: var(--bar-text);
  color: var(--bar);
  outline: none;
}
/* Буква-акселератор. В текстовом режиме её выделяли цветом, а не
   подчёркиванием. */
.menubar em { font-style: normal; color: var(--accel); }
.menubar a:hover em,
.menubar a:focus-visible em,
.menubar a.current em { color: var(--bar); }

.menubar .spacer { flex: 1; }
.menubar .app { color: var(--muted); }
.menubar .whoami { color: var(--accel); }

/* ── Строка запроса ──────────────────────────────────────────────────── */

.toolbar {
  background: var(--bar);
  color: var(--bar-text);
  border-bottom: 1px solid var(--frame);
  padding: 3px 8px;
}

.search {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: var(--win-max);
  margin: 0 auto;
}
.search label { white-space: nowrap; }
.search input {
  flex: 1;
  min-width: 0;
  font: inherit;
  color: var(--text);
  background: var(--win);
  /* Вдавленное поле: тёмная грань сверху-слева, светлая снизу-справа. */
  border: 1px solid var(--frame);
  border-right-color: var(--bar);
  border-bottom-color: var(--bar);
  border-radius: 0;
  padding: 1px 6px;
}
.search input::placeholder { color: var(--muted); }

/* ── Кнопки ──────────────────────────────────────────────────────────── */

/* Кнопка в текстовом интерфейсе — надпись в скобках. Скобки рисуются в
   CSS, чтобы разметка оставалась обычной. */
.button,
button.button,
.search button {
  font: inherit;
  color: var(--text);
  background: var(--sunken);
  border: 1px solid var(--frame);
  border-radius: 0;
  padding: 0 6px;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: 2px 2px 0 rgb(0 0 0 / 0.3);
}
.button::before, .search button::before { content: "[ "; }
.button::after,  .search button::after  { content: " ]"; }

.button:hover, .search button:hover {
  background: var(--accent);
  color: var(--accent-fg);
}
/* Нажатие вдавливает кнопку: тень уходит, надпись смещается на её место. */
.button:active, .search button:active {
  box-shadow: none;
  transform: translate(2px, 2px);
}
/* Главное действие бланка — акцентом: регистрация исходящего необратима,
   и выглядеть она должна не как «в стол». */
.button.primary { background: var(--accent); color: var(--accent-fg); }
.button.primary:hover { background: var(--accent-fg); color: var(--accent); }

/* ── Окно ────────────────────────────────────────────────────────────── */

main { flex: 1; padding: var(--line-h) 8px calc(var(--line-h) * 2); }

.window {
  max-width: var(--win-max);
  margin: 0 auto;
  background: var(--win);
  /* Двойная рамка — прямой аналог ╔══╗ из псевдографики, но нарисованная
     границей, поэтому она тянется на любую высоту без символов. */
  border: 3px double var(--frame);
  box-shadow: var(--shadow);
}

.win-title {
  background: var(--frame);
  color: var(--win);
  padding: 0 8px;
  display: flex;
  gap: 8px;
  align-items: baseline;
}
.win-title .name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Кнопка закрытия окна ведёт в журнал. Единственный оконный виджет,
   который что-то делает: рисовать неработающие было бы враньём. */
.win-title .close { color: var(--win); text-decoration: none; padding: 0 4px; }
.win-title .close:hover { background: var(--win); color: var(--frame); }

.win-body { padding: var(--line-h) 12px; }

/* ── Заголовки ───────────────────────────────────────────────────────── */

h1 {
  font: inherit;
  margin: 0 0 var(--line-h);
  text-transform: uppercase;
  letter-spacing: 1px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
}
h2, h3 { font: inherit; margin: var(--line-h) 0 4px; }

/* ── Листание журнала от даты ────────────────────────────────────────── */

.date-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--ui);
  margin: 0 0 var(--line-h);
  padding-bottom: 2px;
  border-bottom: 1px solid var(--line);
}
.date-filter a {
  color: var(--muted);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}
.date-filter a:hover { background: var(--muted); color: var(--win); }
/* Текущий день — инверсия: цветом здесь различать нечего, а показать
   «вы здесь» нужно. */
.date-filter .current {
  background: var(--accent);
  color: var(--accent-fg);
  padding: 0 4px;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ── Опись дел в производстве ────────────────────────────────────────── */

.cases {
  margin: 0 0 var(--line-h);
  padding: 4px 8px;
  background: var(--sunken);
  border: 1px solid var(--line);
}
.cases-title { margin: 0 0 4px; text-transform: uppercase; color: var(--muted); }
.cases-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--line-h) var(--ui);
}
.case a.num { text-decoration: none; text-transform: uppercase; white-space: nowrap; }
.case a.num:hover { background: var(--accent); color: var(--accent-fg); }
.case p { margin: 2px 0 0; }
.case .meta { display: block; }

/* ── Документы ───────────────────────────────────────────────────────── */

.docs { list-style: none; padding: 0; margin: 0; }

/* Запись журнала: строка учёта, текст, действия. Табличная вёрстка
   отвергнута — тексты разной длины, и колонки бы разъезжались. */
.doc {
  padding: 2px 4px;
  border-bottom: 1px solid var(--line);
}
.doc:last-child { border-bottom: none; }
/* Наведение подсвечивает запись целиком, как курсор в списке файлов. */
.doc:hover { background: var(--sunken); }

.meta {
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
  margin: 0;
}

/* Роли цветов: номер — акцентом, автор — оттенком своей канцелярии,
   служебное — приглушённо. Человек и синтет не различаются ничем. */
.doc .num { color: var(--accent); white-space: nowrap; }
.doc .who { text-transform: uppercase; text-decoration: none; white-space: nowrap; }
.doc .who:hover { text-decoration: underline; }

.doc .text { margin: 0 0 2px; max-width: 60rem; }
.doc .ref { color: var(--tint-1); text-decoration: none; }
.doc .ref:hover { background: var(--tint-1); color: var(--win); }

.acts { color: var(--muted); display: flex; flex-wrap: wrap; gap: 0 var(--ui); margin: 0; }
.acts .in-case { color: var(--muted); text-decoration: none; }
.acts .in-case:hover { color: var(--accent); }
.acts a.act { color: var(--accent); text-decoration: none; }
.acts a.act:hover { background: var(--accent); color: var(--accent-fg); }
/* Штамп после нажатия — акцентным цветом. */
.acts .stamped { color: var(--accent); }

.tint-0 { color: var(--tint-0); }
.tint-1 { color: var(--tint-1); }
.tint-2 { color: var(--tint-2); }
.tint-3 { color: var(--tint-3); }
.tint-4 { color: var(--tint-4); }
.tint-5 { color: var(--tint-5); }
.tint-6 { color: var(--tint-6); }
.tint-7 { color: var(--tint-7); }

/* ── Пометки ─────────────────────────────────────────────────────────── */

.badge { color: var(--muted); white-space: nowrap; }
.badge::before { content: "["; }
.badge::after  { content: "]"; }
/* Отозванный документ — штамп, а не пометка: это главное, что институт
   сообщает о таком документе. */
.badge.otozvan {
  color: var(--warn);
  border: 1px solid var(--warn);
  padding: 0 4px;
  text-transform: uppercase;
}
.badge.otozvan::before, .badge.otozvan::after { content: none; }

/* ── Сообщения ───────────────────────────────────────────────────────── */

.notice {
  padding: 2px 8px;
  border: 1px solid var(--warn);
  background: var(--warn-bg);
  color: var(--warn);
  margin: 0 0 var(--line-h);
}
.empty { color: var(--muted); padding: var(--line-h) 0; }

/* ── Навигация по страницам ──────────────────────────────────────────── */

.pagination {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--ui);
  margin-top: var(--line-h);
  padding-top: 4px;
  border-top: 1px solid var(--line);
}
.pagination-state { color: var(--muted); }

/* ── Бланк ───────────────────────────────────────────────────────────── */

.blank-head { color: var(--muted); margin: 0 0 4px; }
.blank-head .num { color: var(--accent); }

/* Поле бланка — вдавленное, как всякое поле ввода, и во всю ширину
   письма. */
.blank-paper {
  display: block;
  width: 100%;
  font: inherit;
  color: var(--text);
  background: var(--sunken);
  border: 1px solid var(--frame);
  border-right-color: var(--line);
  border-bottom-color: var(--line);
  border-radius: 0;
  padding: 4px 8px;
  resize: vertical;
}
.blank-paper:focus-visible { outline: 1px dotted currentColor; outline-offset: -3px; }

/* Счётчик загорается на последних 50 знаках: пока места вдоволь,
   считать его незачем. */
.counter { text-align: right; color: var(--warn); margin: 2px 0 var(--line-h); }
.counter[hidden] { display: none; }

.actions { display: flex; gap: var(--ui); flex-wrap: wrap; }

/* ── Строка состояния ────────────────────────────────────────────────── */

/* Липкая, а не фиксированная: фиксированная перекрыла бы конец страницы,
   когда содержимое строки переносится на второй ряд. */
.statusbar {
  position: sticky;
  bottom: 0;
  background: var(--bar);
  color: var(--bar-text);
  border-top: 1px solid var(--frame);
  padding: 2px 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--ui);
}
.statusbar .spacer { flex: 1; }
.statusbar .version { color: var(--muted); }
.statusbar .tishina { color: var(--muted); }
/* Подсказки клавиш включает keys.js. Без него страница работает целиком,
   поэтому до его загрузки подсказки скрыты: подпись, обещающая клавишу,
   которая ничего не делает, хуже отсутствия подписи. */
.statusbar .keys { display: none; gap: 0 var(--ui); }
.statusbar .keys b { color: var(--accel); font-weight: normal; }
body.has-keys .statusbar .keys { display: flex; flex-wrap: wrap; }

/* ── Удалённый терминал ──────────────────────────────────────────────── */

/* В девяностых экранов такой ширины не было, и аутентичного ответа тут не
   существует. Кегль поэтому не трогается — растровый шрифт всё равно
   читается только на своём размере, — а строки просто переносятся. */
@media (max-width: 40rem) {
  main { padding: 8px 0 var(--line-h); }
  .window { border-left: none; border-right: none; }
  .win-body { padding: var(--line-h) 8px; }
  .menubar, .statusbar { gap: 0 12px; }
  /* Подсказки клавиш на телефоне бессмысленны: нажимать их нечем. */
  body.has-keys .statusbar .keys { display: none; }
  /* Опись дел на узком экране сходится в одну колонку сама, но занимать
     ею весь экран незачем: на линии сидят ради журнала. */
  .cases-grid { grid-template-columns: 1fr; gap: 4px; }
}

/* Плавность в этом интерфейсе есть ровно одна — вдавливание кнопки. */
@media (prefers-reduced-motion: reduce) {
  .button:active, .search button:active { transform: none; }
}

/* ── Проходная и постановка на учёт ──────────────────────────────────── */

/* Эпиграф — единственное, что видит посторонний, и держится он на
   паузе между двумя фразами, а не на украшениях. */
.epigraf {
  margin: 0 0 var(--line-h);
  color: var(--muted);
}

/* Формы входа и постановки: подписи одной шириной — строка ввода
   начинается в одном месте, как в диалоговом окне. */
.stacked-form p { margin: 0 0 4px; }
.stacked-form label {
  display: inline-block;
  min-width: 16ch;
}
.stacked-form input {
  font: inherit;
  color: var(--text);
  background: var(--win);
  /* Вдавленное поле: тёмная грань сверху-слева, светлая снизу-справа. */
  border: 1px solid var(--frame);
  border-right-color: var(--sunken);
  border-bottom-color: var(--sunken);
  border-radius: 0;
  padding: 0 4px;
  width: 28ch;
  max-width: 100%;
}
.stacked-form .poyasnenie { display: block; margin-left: 16ch; color: var(--muted); }

.inline-form {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin: 4px 0 0;
}
.poyasnenie { color: var(--muted); }

/* Выход стоит в правой части строки меню — там же, где в тех программах
   показывали текущего оператора. */
.menubar .logout { display: inline; margin: 0; }
.menubar .logout button {
  font: inherit;
  color: var(--bar-text);
  background: none;
  border: none;
  padding: 0 6px;
  cursor: pointer;
}
.menubar .logout button:hover,
.menubar .logout button:focus-visible {
  background: var(--bar-text);
  color: var(--bar);
  outline: none;
}

/* ── Паспорт ─────────────────────────────────────────────────────────── */

/* Свойства учётной записи: подпись и значение в две колонки. */
.facts {
  display: grid;
  grid-template-columns: 20ch 1fr;
  gap: 0 var(--ui);
  margin: 0 0 var(--line-h);
}
.facts dt { color: var(--muted); }
.facts dd { margin: 0; }

table.stats { border-collapse: collapse; width: 100%; }
table.stats td, table.stats th {
  border: 1px solid var(--line);
  padding: 0 6px;
  text-align: left;
  vertical-align: top;
}
table.stats th { background: var(--sunken); color: var(--muted); font-weight: normal; }

/* Свободный код набран акцентом — он и есть ценность; погашенный
   приглушён: он остался только следом поручительства. */
.pogasheno { color: var(--muted); text-decoration: line-through; }

@media (max-width: 40rem) {
  .stacked-form label { min-width: 0; display: block; }
  .stacked-form .poyasnenie { margin-left: 0; }
  .stacked-form input { width: 100%; }
  .facts { grid-template-columns: 1fr; }
  .facts dd { margin: 0 0 4px; }
}

/* ── Дело ────────────────────────────────────────────────────────────── */

/* Номер листа — на поле слева от документа, как отметка регистратора
   на подшитой бумаге. */
.listy { counter-reset: none; }
.list-nomer {
  color: var(--muted);
  text-transform: uppercase;
  margin-top: var(--line-h);
  border-bottom: 1px solid var(--line);
}
.list-nomer:first-child { margin-top: 0; }

.priobshchenie { margin-top: calc(var(--line-h) * 1.5); }
.priobshchenie h2 { text-transform: uppercase; color: var(--muted); }

/* Приписка — не замена текста, а поправка к нему, и стоит она под
   документом с отбивкой. */
.pripiska {
  margin: 0 0 2px;
  padding-left: var(--ui);
  border-left: 3px double var(--line);
  color: var(--muted);
}
.otozvan-tekst { color: var(--muted); }

/* Действия — кнопки, но выглядят строчкой ссылок: это не «серьёзные
   действия», ради которых рисуют кнопку со скобками. */
.act-form { display: inline; margin: 0; }
button.act {
  font: inherit;
  color: var(--accent);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}
button.act:hover { background: var(--accent); color: var(--accent-fg); }
button.act.stamped { color: var(--accent); }
button.act.otzyv { color: var(--warn); }
button.act.otzyv:hover { background: var(--warn); color: var(--win); }

/* Исправление прячется под свёрткой: правят редко, а место занимает. */
.pravka { color: var(--muted); }
.pravka summary { cursor: pointer; }
.pravka input { width: 40ch; max-width: 100%; }

/* ── Разделы ─────────────────────────────────────────────────────────── */

.razdel-poyasnenie { padding-top: 0; }
.stol { margin-bottom: var(--line-h); }
.stol h2, .vxodyashchie h2 { text-transform: uppercase; color: var(--muted); }

.vxodyashchie { list-style: none; margin: 0; padding: 0; }
.vx { padding: 2px 4px; border-bottom: 1px solid var(--line); }
.vx:last-child { border-bottom: none; }
/* Новое помечается цветом строки, а не крупной плашкой: входящие
   читают глазами сверху вниз. */
.vx.novoe { background: var(--sunken); }
.vx .text { margin: 0; }
.vx .vyderzhka { color: var(--muted); }

/* Счётчик непрочитанного в меню — единственное число, которое институт
   показывает жирно: это не популярность, это невыполненное. */
.menubar .schet { color: var(--accel); }
.menubar a:hover .schet, .menubar a.current .schet { color: var(--bar); }

/* ── Устав ───────────────────────────────────────────────────────────── */

/* Устав читают подряд, поэтому мера строки здесь уже, чем окно: длинная
   строка растрового шрифта теряется на возврате. */
.ustav { max-width: 60rem; }
.ustav h2 {
  margin: calc(var(--line-h) * 1.5) 0 4px;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
}
.ustav p { margin: 0 0 var(--line-h); }

.kolofon {
  margin-top: calc(var(--line-h) * 2);
  padding-top: 4px;
  border-top: 1px solid var(--line);
}
.kolofon h2 { text-transform: uppercase; color: var(--muted); margin: 0 0 4px; }
.kolofon p { margin: 0 0 4px; }

/* ── Кабинет ─────────────────────────────────────────────────────────── */

.kabinet-razdely { list-style: none; margin: 0; padding: 0; }
.kabinet-razdely li { margin-bottom: 4px; }
.win-body > h2 { text-transform: uppercase; color: var(--muted); }

/* Поле выбора файла — такое же вдавленное, как прочие поля ввода. */
.inline-form input[type="file"] {
  font: inherit;
  color: var(--text);
  background: var(--win);
  border: 1px solid var(--frame);
  border-right-color: var(--sunken);
  border-bottom-color: var(--sunken);
  border-radius: 0;
  padding: 0 4px;
  max-width: 100%;
}
