/* Тема зафиксирована и не следует system prefers-color-scheme — раньше
   следовала, а часть страниц Каспаны (Каталог/Поставщики/Деньги — ещё
   не досвёрстанные под общую оболочку статичные макеты) системную тему
   не подхватывала вовсе. В сумме это давало разнобой «то чёрный фон, то
   белый» между пунктами одного меню (замечание Хозяина 2026-09-10).
   Один фиксированный набор цветов на весь сайт — гарантия одинакового
   вида везде, независимо от настройки браузера.
   Светлая тема — решение Хозяина 2026-09-10 («Мне не нравится черный
   фон» → «Полностью светлая тема»). */
:root {
  --bg: #f7f7f8;
  --text: #1a1a1a;
  --text-dim: #595959;
  --accent: #2e7d32;
  --border: #cbcbcf;
  --trevoga: #c62828;
  --predupr: #8a5700;
  --radius: 4px;
  --transition: 0.2s ease;
}
@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}
body {
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, sans-serif;
  margin: 0;
  padding: 0.5rem;
}
/* Табло: показатели работы, а не состояния. Счётчик «сайта нет» говорил о
   моих недоделках, а не о работе Колхоза, и с первого места убран. */
.tablo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  margin: 0.75rem 0;
}
.tablo-kletka {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.6rem 0.7rem;
  min-width: 0;
}
.tablo-podpis {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-dim); font-weight: 600;
}
.tablo-chislo {
  margin-top: 0.15rem;
  font-size: 1.5rem; font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tablo-ed { display: block; font-size: 0.7rem; font-weight: 400; color: var(--text-dim); }
.tablo-slovom { font-size: 0.95rem; font-weight: 500; color: var(--text-dim); }
.tablo-vtoraya { margin-top: 0.2rem; font-size: 0.7rem; color: var(--text-dim); }
.tablo-vtoraya.ploho { color: var(--trevoga); font-weight: 600; }
.tablo-tiho {
  display: flex; flex-wrap: wrap; gap: 0.4rem 0.35rem;
  margin-bottom: 0.75rem;
  font-size: 0.75rem; color: var(--text-dim);
}
/* Правка 3 оценщика (02.10): простыня через пробел → отдельные плашки,
   каждая читается как самостоятельный факт; тревожные сохраняют свой цвет. */
.tablo-tiho > span {
  padding: 0.2rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  white-space: nowrap;
}
.tablo-tiho > span.vopros-neizvestno { border-color: var(--trevoga); }

/* Сбой orc question list — не то же самое, что «вопросов нет»: цвет
   тревоги, чтобы не потерялось среди соседних приглушённых строк. */
.vopros-neizvestno { color: var(--trevoga); font-weight: 600; }

.vremya { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.6rem; }
/* Возраст данных читается с одного взгляда, а не вычисляется по времени в
   подзаголовке: правило Колхоза от 2026-08-31. */
.svezhest { font-size: 0.95rem; font-weight: 600; }
/* Хозяин 02.09: возраст данных Каспаны читался тем же неприметным шрифтом,
   что и остальной текст — «2 суток назад» проходило мимо взгляда. Порог
   и цвет тревоги делают старость данных таким же явным сигналом, как
   .tablo-vtoraya.ploho для нулевого «влито». */
.svezhest.ustarela { color: var(--trevoga); font-size: 1.1rem; }
.vremya .tiho { font-size: 0.75rem; color: var(--text-dim); }
.obnovit {
  border: none; background: none; padding: 0; margin-left: auto;
  color: var(--text-dim); font-size: 1rem; line-height: 1; cursor: pointer;
}
.obnovit:hover { color: var(--text); }

.hozyaystvo {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.6rem;
  margin-bottom: 0.6rem;
}
.kolhoz { font-size: 1.05rem; font-weight: 700; letter-spacing: 0.01em; }
.panel-imya { font-size: 0.75rem; color: var(--text-dim); }

.svodka {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.schetchik {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--border);
  border-radius: var(--radius);
  padding: 0.25rem 0.5rem;
  min-width: 4rem;
}
.schetchik b {
  font-size: 2rem;
  line-height: 1;
}
.schetchik span {
  font-size: 0.7rem;
  letter-spacing: 0.05em;
}
.proveryeno {
  font-size: 0.8rem;
  color: var(--text-dim);
}
.izmeneniya {
  font-size: 0.9rem;
  margin: 0.25rem 0;
  flex-basis: 100%;
}
.proekty {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.75rem;
  align-items: start; /* карточка не тянется до самой высокой в ряду (судья 19.10) */
  list-style: none;
  padding: 0;
  margin: 0;
}
@media (min-width: 768px) {
  .proekty {
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  }
}
.proekty li {
  background: var(--border);
  border-radius: var(--radius);
  padding: 0.5rem;
  margin-bottom: 0;
  position: relative;
  border: 1px solid var(--border);
}
/* Название — ссылка в тоне страницы, а не браузерная синяя (судья 19.10, находка 5). */
.proekty .imya a {
  color: var(--text);
  font-weight: 600;
  text-decoration-color: var(--accent);
  text-underline-offset: 0.2em;
}
.proekty .imya a:hover { color: var(--accent); }
.proekty a.imya, .proekty .sostoyanie {
  display: inline;
  margin-right: 0.5rem;
}
.proekty .sut {
  font-size: 0.8rem;
  color: var(--text-dim);
  margin: 0.25rem 0;
}
/* Разделение Хозяина 02.09: подход сменён с ярлычка на карточке (легко
   потерялся среди прочего текста) на структурное разделение — два
   раздела со своим счётом, «результат» выше «накладных». */
.razryad-zagolovok {
  font-size: 1rem;
  margin: 1.25rem 0 0.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
}
.razryad-zagolovok .tiho {
  font-size: 0.75rem;
  font-weight: normal;
}
.proekty-razryad:first-of-type .razryad-zagolovok { margin-top: 0; }
.proekty-razryad[data-razryad="колхозник"] .razryad-zagolovok { color: var(--text-dim); }
.proekty .sostoyanie {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--bg);
}
.proekty li[data-sostoyanie="отвечает"] .sostoyanie { background: var(--accent); }
.proekty li[data-sostoyanie="лежит"] .sostoyanie { background: var(--trevoga); }
.proekty li[data-sostoyanie="пусто"] .sostoyanie { background: var(--text-dim); }
.proekty li[data-sostoyanie="сайта нет"] .sostoyanie { background: var(--text-dim); }
.proekty li[data-sostoyanie="лежит"] {
  border-left: 0.5rem solid var(--trevoga);
}
.proekty li[data-sostoyanie="сайта нет"] {
  border: 1px dashed var(--border);
}
.proekty li[data-sostoyanie="пусто"] {
  opacity: 1;
}
.proekty li[data-sostoyanie="отвечает"] {
  background: var(--bg);
}
.proekty .oshibka {
  margin-top: 0.4rem;
  padding: 0.3rem 0.5rem;
  border-left: 0.25rem solid var(--trevoga);
  color: var(--trevoga);
  font-size: 0.85rem;
}
.pokazateli {
  list-style: none;
  padding: 0;
  margin: 0.35rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  font-size: 0.8rem;
}
/* Цифра без подписи ничего не говорит: имя показателя мельче, цифра крупнее. */
.pokazatel {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  /* Длинный текст без пробелов (Codex, 02.09: у 14 проектов текст своих
     сборщиков не ограничен ничем) не должен растягивать карточку. */
  max-width: 100%;
  min-width: 0;
}
.pokazatel .nazvanie,
.pokazatel .tekst {
  overflow-wrap: anywhere;
}
.pokazatel .nazvanie {
  font-size: 0.75rem;
  color: var(--text-dim);
  text-transform: lowercase;
}
.pokazatel .tekst {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}
/* Обрезанный этап раскрывается кликом: голое «…» без выхода — тупик. */
button.tekst.razvernut {
  font: inherit; font-weight: 500; color: inherit; background: none; border: 0;
  padding: 0; text-align: left; cursor: pointer;
}
/* Стрелка, не подчёркивание: подчёркнутое читалось как ссылка (судья, находка 4). */
button.tekst.razvernut::after { content: " ▸"; color: var(--text-dim); }
button.tekst.razvernut[aria-expanded="true"]::after { content: " ▾"; }
/* Возраст данных — по правилу Хозяина читается с одного взгляда: крупнее и
   выносится в начало ряда показателей, а не тонет среди остальных цифр. */
.pokazatel.vozrast {
  order: -1;
}
.pokazatel.vozrast .tekst {
  font-size: 1.15rem;
  font-weight: 700;
}
.pokazatel.vozrast .tekst .poyasnenie {
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--text-dim);
}
/* Дверь. Её видит и Хозяин, и любой прохожий из интернета: новый поддомен
   сканеры находят через журнал сертификатов за час. Поэтому здесь ровно две
   вещи — сторож, который спрашивает «вы кто такие?», и поле пароля. */
.vhod-oblast {
  max-width: 26rem;
  margin: 0 auto;
  padding: 2rem 1rem 3rem;
  text-align: center;
}
.vhod-oblast .storozh {
  display: block;
  width: 100%;
  height: auto;
  max-width: 22rem;
  margin: 0 auto 1.25rem;
  border-radius: var(--radius);
}
.vhod-oblast h1 {
  margin: 0 0 1.25rem;
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.vhod-oblast form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.vhod-oblast input,
.vhod-oblast button {
  /* Без border-box поле и кнопка расходятся по ширине на толщину рамки. */
  box-sizing: border-box;
  width: 100%;
  padding: 0.6rem 0.75rem;
  font: inherit;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
}
.vhod-oblast button {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}
.vhod-oblast .oshibka {
  margin-bottom: 0.75rem;
  padding: 0.4rem 0.6rem;
  border-left: 0.25rem solid var(--trevoga);
  color: var(--trevoga);
  text-align: left;
}

.vhod {
  display: flex;
  justify-content: center;
  margin: 1rem 0;
}
.vhod form {
  width: 100%;
  max-width: 22rem;
}
.vhod input, .vhod button {
  width: 100%;
  padding: 0.5rem;
  margin-bottom: 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
}
.vhod button {
  background: var(--accent);
  color: white;
  cursor: pointer;
}

/* Блок «Очередь»: Конферансье гоняет наряды, пока Хозяин спит. Полоса,
   а не карточка: рамка съела бы первый экран телефона ради красоты. */
/* Живость идёт впереди объёма: молчащий Конферансье при полной очереди —
   беда, а полная очередь при живом — обычный рабочий день. */
/* На узком экране полоса остаётся только у наряда, который идёт сейчас:
   прочие сжимаются до имени и остатка, но не прячутся — беда не должна
   оказаться за раскрытием. */


/* Оркестры: две исполняющие единицы со своими ключами. Разреза по отдельным
   исполнителям здесь нет — Хозяин просил его не показывать. */

/* Ближайшие шаги в порядке взятия. Четыре видны всегда, остальные под
   раскрытием: двадцать строк вытолкнули бы сводку за первый экран телефона. */

@media (min-width: 700px) {
  .tablo { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .naryad:not([data-v-rabote]) .polosa {
    display: block;
  }
  .svodka {
    flex-wrap: nowrap;
  }
  /* сетка .proekty теперь задаётся своим правилом с auto-fit — фиксированных 2 колонок и data-raskryto здесь больше нет */
}

/* Ручка перестановки. Кнопки есть всегда: тащить строку пальцем в списке из
   двадцати — мучение, а Хозяин смотрит панель с телефона. */
/* Строка, на которую отпустят: без неё пальцем не понять, куда попадёшь. */
/* Иначе браузер уводит страницу в прокрутку вместо перетаскивания. */
@media (max-width: 699px) {
  /* Палец накрывает около 44 px — всё, во что нужно попасть, не мельче. */
  .sh-ruchka button { min-width: 2.75rem; min-height: 2.75rem; }
}

/* Доли работ. Отвечают на вопрос «почему сейчас делается именно это»:
   Конферансье берёт канал, отставший от своей доли за последний час.
   Метка на полосе — сколько положено, заливка — сколько вышло. */

/* Очередь разложена по нарядам: у каждого своя, и переставляют каждую
   отдельно. Общего порядка между нарядами нет — Конферансье выбирает наряд
   по доле его канала, а не по месту в списке. */

/* ===================== ФЕСТИВАЛЬ =====================
   Переделано целиком 2026-08-31: Хозяин сказал «непонятно, что тут что».
   Прежний блок рос заплатками, наряды перечислялись дважды — списком и
   заголовками групп очереди.

   Одна мысль держит всё: НАРЯД — главная единица, его шаги живут внутри
   него, а не отдельным списком. Оркестры и доли стоят выше нарядов и не
   разрывают связь «наряд — его очередь».

   Ширина ограничена: на мониторе в 1700 точек строка растягивалась во всю
   ширину, и глаз шёл от имени слева к числу справа через пустоту. Рамка
   блока идёт во всю ширину страницы (в одну сетку с карточками), а
   строки внутри остаются в 62rem. */
.ochered {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 0.75rem 0;
  margin-bottom: 0.75rem;
}
.ochered > * { max-width: 62rem; }
.ochered.net-dannyh { color: var(--text-dim); padding: 0.5rem 0; }
.ochered .shapka {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.3rem 0.75rem;
}
.ochered .shapka h2 {
  margin: 0; font-size: 0.8rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
}
.ochered .itog { font-size: 0.9rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.ochered .zahod { margin-left: auto; font-size: 0.75rem; color: var(--text-dim); }

/* Отложенное — не беда и не провал, Конферансье поднимет само по сроку:
   нейтральный цвет, не тревожный. Молчание выглядело бы как опустевшая
   без причины очередь (Шишкарь, 02.09). */
.otlozheno {
  margin-top: 0.3rem; font-size: 0.8rem; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

.ochered .trevoga {
  margin-top: 0.45rem; padding: 0.35rem 0.55rem;
  border-left: 0.25rem solid var(--trevoga);
  color: var(--trevoga); font-weight: 600; font-size: 0.85rem;
}
.ochered .tiho-trevoga { font-weight: 500; }

/* Кто играет сейчас — одной полосой, а не двумя карточками посреди экрана. */
.seychas {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 1rem;
  margin-top: 0.6rem; font-size: 0.8rem;
}
.seychas-podpis {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-dim); font-weight: 600;
}
.ork { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ork[data-zanyat="нет"] { color: var(--text-dim); }

.doli-blok { margin-top: 0.75rem; }
.doli-zagolovok, .naryady-zagolovok {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-dim); font-weight: 600;
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: baseline;
}
.naryady-zagolovok { margin: 0.9rem 0 0.35rem; }
.naryady-zagolovok .tiho { text-transform: none; letter-spacing: 0; font-weight: 400; }

.doli { list-style: none; padding: 0; margin: 0.35rem 0 0; }
.dolya {
  display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) 6rem;
  align-items: center; gap: 0.5rem; padding: 0.15rem 0; font-size: 0.75rem;
}
.dolya-imya { color: var(--text-dim); }
.dolya-polosa {
  position: relative; display: block; height: 0.45rem;
  border-radius: var(--radius); background: var(--border); overflow: hidden;
}
.dolya-fakt { display: block; height: 100%; background: var(--accent); }
.dolya-metka { position: absolute; top: -0.15rem; bottom: -0.15rem; width: 2px; background: var(--text); }
.dolya-chisla { font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.dolya[data-otstal] .dolya-imya { color: var(--trevoga); font-weight: 600; }
.dolya[data-otstal] .dolya-fakt { background: var(--trevoga); }

/* Наряд — карточка со своей очередью внутри. */
/* Заголовок канала связывает полосы долей с нарядами: Хозяин не понимал,
   какая работа по повышенному приоритету, а какая по прочим. */
/* Заголовок канала — настоящая граница между группами приоритета, а не
   мелкая серая надпись: Хозяин просил группировать очевиднее. */
.kanal-zagolovok {
  display: flex; align-items: center; gap: 0.5rem;
  margin: 1.1rem 0 0.4rem;
  padding: 0.3rem 0.6rem;
  background: var(--border);
  border-radius: var(--radius);
  font-size: 0.9rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  transition: opacity 0.15s ease;
}
.kanal-skolko {
  margin-left: auto;
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0;
  color: var(--text-dim);
}
.kanal-zagolovok + .naryady { padding-left: 0.6rem; border-left: 2px solid var(--border); }
.poisk {
  margin-left: auto;
  min-width: 12rem; max-width: 100%;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg); color: var(--text);
  font: inherit; font-size: 0.8rem; text-transform: none; letter-spacing: 0;
}
#poisk-itog { width: 100%; font-size: 0.75rem; }
/* Доделанный наряд свёрнут, но в разметке есть: иначе поиск не нашёл бы его
   ровно тогда, когда проект всё доделал. */
.naryad[data-dodelan] { display: none; }
.naryad[data-dodelan].nayden { display: block; opacity: 0.75; }

.naryady { list-style: none; padding: 0; margin: 0; }
.naryad {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.5rem 0.6rem;
  margin-bottom: 0.5rem;
  /* Перетаскивание — только за ручку ⠿ слева (см. .ruchka), не за
     карточку целиком: иначе палец, коснувшийся где угодно на наряде,
     вместо скролла страницы всякий раз получал попытку перетащить. */
}
.naryad[data-v-rabote] { border-left: 0.25rem solid var(--accent); }
.naryad.tashchat { opacity: 0.5; }
.naryad-shapka {
  display: grid; grid-template-columns: 1rem minmax(0, 1fr) auto auto;
  align-items: center; gap: 0.5rem;
}
.ruchka {
  color: var(--text-dim); cursor: grab; touch-action: none;
  /* Без этого нажатие с ведением выделяет текст, браузер начинает своё
     перетаскивание выделенного и глушит события указателя. Тот же класс
     беды, что был с атрибутом draggable. */
  user-select: none; -webkit-user-select: none;
  /* Без этого удержание на iPhone открывает системную выноску/меню
     Safari (Codex, 02.09) — жест обрывается pointercancel раньше, чем
     наш обработчик успевает начать перетаскивание. */
  -webkit-touch-callout: none;
}
.naryad .imya {
  font-weight: 600; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.starshinstvo {
  font-size: 0.7rem; color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 999px; padding: 0 0.4rem;
  max-width: 11rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.naryad[data-ruchnoy] .starshinstvo { border-style: dashed; }
.naryad .schet { font-size: 0.8rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.naryad-polosa {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: 0.5rem; margin: 0.3rem 0 0 1.5rem;
}
.polosa { display: block; height: 0.3rem; border-radius: var(--radius); background: var(--border); overflow: hidden; }
.polosa .sdelano { display: block; height: 100%; background: var(--accent); }
.naryad .zhdet { font-size: 0.7rem; color: var(--text-dim); white-space: nowrap; }
.ruchnoy-uroven {
  margin: 0.25rem 0 0 1.5rem; font-size: 0.7rem; color: var(--text-dim);
  display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap;
}
.vernut-uroven {
  border: none; background: none; padding: 0; font: inherit;
  color: var(--accent); text-decoration: underline; cursor: pointer;
}
.naryad-vyshe, .naryad-nizhe {
  border: 1px solid var(--border); background: var(--bg); border-radius: var(--radius);
  padding: 0.15rem 0.45rem; font: inherit; font-size: 0.7rem; color: var(--text);
  cursor: pointer; line-height: 1.4;
}
.naryad-vyshe:hover, .naryad-nizhe:hover { border-color: var(--accent); color: var(--accent); }
.naryad-vyshe:disabled, .naryad-nizhe:disabled { opacity: 0.4; cursor: not-allowed; }

/* Шаги наряда — его собственная очередь. */
.shagi { list-style: none; padding: 0; margin: 0.4rem 0 0 1.5rem; }
.shag {
  display: grid;
  grid-template-columns: 1rem 2.5rem minmax(0, 1fr) auto auto;
  align-items: center; gap: 0.5rem;
  padding: 0.25rem 0;
  border-top: 1px solid var(--border);
  font-size: 0.8rem;
}
.shag.tashchat { opacity: 0.5; }
.shag[data-dvigat] .sh-ruchka {
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.sh-ruchka { color: var(--text-dim); text-align: center; }
.sh-nomer { font-variant-numeric: tabular-nums; color: var(--text-dim); text-align: right; }
.sh-zadacha { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-profil {
  font-size: 0.7rem; color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 999px; padding: 0 0.4rem;
}
.sh-sostoyanie { font-size: 0.7rem; color: var(--text-dim); white-space: nowrap; text-align: right; }
.shag[data-sostoyanie="в работе"] .sh-sostoyanie { color: var(--accent); }

/* Строка, на которую отпустят: без неё пальцем не понять, куда попадёшь. */
.tsel { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius); }

.eshchyo > summary {
  cursor: pointer; padding: 0.35rem 0 0.35rem 1.5rem;
  font-size: 0.75rem; color: var(--text-dim);
}
.eshchyo .shagi { margin-top: 0; }

.ochered .podval {
  display: flex; flex-wrap: wrap; gap: 0.25rem 1rem;
  margin-top: 0.6rem; font-size: 0.75rem; color: var(--text-dim);
}
.ochered .podval .ploho { color: var(--trevoga); font-weight: 600; }
.ochered-otvet {
  margin: 0.4rem 0; padding: 0.3rem 0.5rem;
  border-left: 0.25rem solid var(--accent); font-size: 0.8rem;
}
.ochered-otvet.ploho { border-left-color: var(--trevoga); color: var(--trevoga); }

@media (max-width: 699px) {
  .ochered > * { max-width: none; }
  .dolya { grid-template-columns: 5.5rem minmax(0, 1fr) 4.5rem; }

  /* Имена нарядов и текст задач были почти не видны — их съедала неявная
     раскладка грида: элементы с явной позицией (профиль, состояние)
     сталкивались с элементами без неё (текст задачи), и текст падал в
     чужую, узкую в 1,5rem ячейку. Явно расставляем все пять элементов по
     двум рядам — коллизий больше нет ни при каком порядке в разметке. */
  /* Номер шага и текст задачи начинались с одной и той же колонки —
     номер и первые буквы задачи рисовались друг на друге. Номеру
     нужна своя, отдельная от текста колонка. */
  .shag {
    grid-template-columns: 2.75rem 2.3rem minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    row-gap: 0.15rem;
  }
  .sh-ruchka { grid-column: 1; grid-row: 1 / span 2; }
  .sh-nomer { grid-column: 2; grid-row: 1; justify-self: start; }
  .sh-zadacha { grid-column: 3 / -1; grid-row: 1; }
  .sh-profil { grid-column: 2 / -2; grid-row: 2; justify-self: start; }
  .sh-sostoyanie { grid-column: 4; grid-row: 2; justify-self: end; }

  /* Имя наряда делило ширину с ярлыком уровня («разработка Фестиваля» —
     почти половина экрана телефона) и от него оставалось несколько букв.
     Уровень уже назван заголовком канала выше — здесь ему хватит отдельной
     строки, а не половины строки с именем. */
  .naryad-shapka {
    grid-template-columns: 2.75rem minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    row-gap: 0.15rem;
  }
  .naryad-shapka .ruchka { grid-column: 1; grid-row: 1 / span 2; }
  .naryad-shapka .imya { grid-column: 2; grid-row: 1; }
  .naryad-shapka .schet { grid-column: 3; grid-row: 1; }
  .naryad-shapka .starshinstvo { grid-column: 2 / -1; grid-row: 2; justify-self: start; max-width: none; }

  .shagi, .naryad-polosa, .ruchnoy-uroven { margin-left: 0; }
  /* Палец накрывает около 44 точек: ручке нужны и высота, и ширина —
     тонкая полоска роняет захват, а на неё же приходится удержание.
     Раньше min-width был 1.75rem вопреки этому же комментарию (Codex,
     02.09) — реальная ширина колонки грида ниже отставала от заявленной. */
  .sh-ruchka, .ruchka {
    min-height: 2.75rem; min-width: 2.75rem;
    display: flex; align-items: center; justify-content: center;
  }
}

/* ===================== СТРАНИЦА КАСПАНЫ =====================
   Своя страница внутри панели: у Каспаны нет своей вёрстки, только
   JSON-ручки, поэтому вид собираем здесь и ходим к ней за данными.
   Переработка 03.09 (Хозяин: «вижу только какую-то заглушку») — макет
   выбран голосованием Оркестра, числа сверены с реальным /run/N. */
.kaspana-oblast {
  max-width: 64rem;
  margin: 0 auto;
  padding: 0 1rem 2rem;
}
.k-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin: 0.75rem 0;
}
@media (min-width: 48rem) {
  .k-cards { grid-template-columns: 1fr 1fr; }
  .k-card-wide { grid-column: 1 / -1; }
}
.k-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  min-width: 0;
}
.k-card-h {
  font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-dim); font-weight: 600; margin-bottom: 0.6rem;
}
.k-itog-chislo {
  font-size: 2.2rem; font-weight: 700; line-height: 1.1; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.k-itog-podpis { font-size: 0.85rem; color: var(--text-dim); margin-top: 0.15rem; }
.k-delta { margin-top: 0.5rem; font-size: 0.85rem; color: var(--text-dim); }
.k-delta.k-good { color: var(--accent); }
.k-delta.k-plokho { color: var(--trevoga); }
.k-good { color: var(--accent); }
.k-plokho { color: var(--trevoga); }
.k-stats-row {
  display: flex; gap: 1rem; margin-top: 0.9rem; flex-wrap: wrap;
  padding-top: 0.75rem; border-top: 1px solid var(--border);
}
.k-stat { flex: 1; min-width: 5.5rem; }
.k-stat-znach { font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.k-stat-podpis { font-size: 0.75rem; color: var(--text-dim); }
.k-run-list { list-style: none; padding: 0; margin: 0; }
.k-run-item {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 0.75rem; padding: 0.55rem 0; border-bottom: 1px solid var(--border);
}
.k-run-item:last-child { border-bottom: none; }
.k-run-date { font-size: 0.75rem; color: var(--text-dim); white-space: nowrap; }
.k-run-note { font-size: 0.85rem; flex: 1; min-width: 0; }
.k-run-pct { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.k-table th, .k-table td { text-align: left; padding: 0.45rem 0.4rem; border-bottom: 1px solid var(--border); }
.k-table th { color: var(--text-dim); font-weight: 500; font-size: 0.7rem; text-transform: uppercase; }
.k-table td:last-child, .k-table th:last-child { text-align: right; }
.k-note {
  font-size: 0.75rem; color: var(--text-dim); margin-top: 0.75rem;
  padding-top: 0.6rem; border-top: 1px solid var(--border);
}
.k-bar-row { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
.k-bar-label { font-size: 0.75rem; color: var(--text-dim); width: 1.2rem; text-align: right; }
.k-bar-label-shirokiy { width: 7.5rem; text-align: left; flex-shrink: 0; }
.k-bar-track { flex: 1; background: var(--border); border-radius: 2px; overflow: hidden; height: 0.9rem; }
.k-bar { display: block; height: 100%; background: var(--accent); }
.k-bar-red { background: var(--trevoga); }
.k-bar-yellow { background: var(--predupr); }
.k-bar-green { background: var(--accent); }
.k-bar-value { font-size: 0.8rem; font-weight: 600; min-width: 3rem; text-align: right; font-variant-numeric: tabular-nums; }
.k-chernovik { margin: 0.75rem 0; }
.k-chernovik p { margin: 0 0 0.5rem; font-size: 0.9rem; color: var(--text-dim); }
.k-chernovik-ssylka { color: var(--accent); font-weight: 600; text-decoration: none; }
.k-chernovik-ssylka:hover { text-decoration: underline; }
.k-makety-spisok { display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; margin: 0 !important; }
.k-makety-spisok a { color: var(--accent); font-weight: 600; text-decoration: none; white-space: nowrap; }
.k-makety-spisok a:hover { text-decoration: underline; }

/* Навигация из 6 пунктов новой структуры меню (утверждена Хозяином
   08.09, docs/kaspana-struktura-menyu.html) — общая для всех экранов. */
.k-nav {
  display: flex; flex-wrap: wrap; gap: 0.25rem;
  margin: 0 0 1.25rem; padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}
.k-nav a {
  color: var(--text-dim); text-decoration: none; font-weight: 600;
  font-size: 0.9rem; padding: 0.4rem 0.7rem; border-radius: var(--radius);
}
.k-nav a:hover { color: var(--text); background: rgba(127,127,127,0.08); }
.k-nav a.k-nav-tekushiy { color: var(--accent); background: rgba(127,127,127,0.08); }
.k-alert {
  display: flex; gap: 0.6rem; align-items: flex-start;
  border: 1px solid var(--trevoga); border-radius: var(--radius);
  padding: 0.7rem 0.9rem; margin-bottom: 0.75rem; font-size: 0.9rem;
}
.k-alert .k-alert-ikonka { flex-shrink: 0; }
.k-glavnaya-summa {
  font-size: 2rem; font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
header a.tiho {
  margin-left: auto;
  align-self: center;
  text-decoration: none;
}
.k-status {
  font-size: 0.75rem; font-weight: 600; padding: 0.15rem 0.6rem;
  border-radius: 999px; white-space: nowrap; flex-shrink: 0;
  border: 1px solid var(--border); color: var(--text-dim);
}
.k-status-completed { color: var(--accent); border-color: var(--accent); }
.k-status-cancelled { color: var(--trevoga); border-color: var(--trevoga); }
.k-status-green { color: var(--accent); border-color: var(--accent); }
.k-status-yellow { color: var(--predupr); border-color: var(--predupr); }
.k-status-red { color: var(--trevoga); border-color: var(--trevoga); }
.k-status-net-dannykh { color: var(--text-dim); }
.k-katalog-kategorii {
  display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.75rem 0 0;
}
.k-katalog-kategoriya {
  font-size: 0.75rem; color: var(--text-dim); border: 1px solid var(--border);
  border-radius: 999px; padding: 0.15rem 0.6rem;
}
.k-katalog-listalka { display: flex; justify-content: space-between; gap: 1rem; margin-top: 1rem; }
.k-katalog-chislo { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.k-table tbody tr:nth-child(even) { background: rgba(127,127,127,0.045); }
.k-zakaz-shapka {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0 0 0.4rem; font-size: 0.7rem; color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.02em;
}
.k-zakaz-stroka {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.6rem 0; border-bottom: 1px solid var(--border);
  text-decoration: none; color: inherit;
}
.k-zakaz-stroka:last-child { border-bottom: none; }
.k-zakaz-stroka:hover { background: rgba(127,127,127,0.06); }
.k-zakaz-data { font-size: 0.75rem; color: var(--text-dim); width: 3rem; flex-shrink: 0; }
.k-zakaz-gorod { flex: 1; min-width: 0; }
.k-zakaz-summa { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 30rem) {
  .k-zakaz-stroka { flex-wrap: wrap; }
  .k-zakaz-gorod { min-width: 100%; order: 1; }
}

/* ===================== СТРАНИЦА СИНХРОНИСТА =====================
   Разбор макетов одного наряда: список, каждый — галочка + живой
   просмотр в iframe, общее поле замечаний. */
.maket-detali { margin-top: 1rem; }
/* Отправка сворачивает форму: открыт, пока нет сохранённого отзыва,
   после сохранения — сводка одной строкой и явное «Изменить». */
.maket-svodka-otzyva {
  cursor: pointer;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-dim);
  font-size: 0.9rem;
}
.maket-detali[open] .maket-svodka-otzyva { margin-bottom: 0.75rem; }
.maket-forma { margin-top: 1rem; }
.maket-blok {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem;
  margin-bottom: 1rem;
}
.maket-shapka {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.5rem;
}
.maket-galochka {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  cursor: pointer;
}
.maket-galochka input { width: 1.2rem; height: 1.2rem; }
.maket-tiho { color: var(--text-dim); font-size: 0.85rem; text-decoration: none; }
.maket-ramka {
  width: 100%;
  aspect-ratio: 1280 / 800;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fff;
  overflow: hidden;
  position: relative;
}
/* Внутри — настоящие 1280×800, снаружи резиновая рамка: без масштаба
   (см. скрипт в sinkhronist.html) была бы видна только середина между
   окнами макета, а не сам макет. */
.maket-ramka iframe {
  width: 1280px;
  height: 800px;
  border: 0;
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: top left;
}
.maket-podpis-polya {
  display: block;
  margin: 1rem 0 0.3rem;
  font-size: 0.85rem;
  color: var(--text-dim);
}
.maket-forma textarea {
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  resize: vertical;
}
.maket-otpravit {
  margin-top: 0.75rem;
  padding: 0.6rem 1.4rem;
  border: none;
  border-radius: var(--radius);
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.maket-otpravit:disabled { opacity: 0.5; cursor: not-allowed; }

.ot-vhod {
  display: block;
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  margin-bottom: 0.75rem;
}
.ot-oshibki-spisok { margin: 0.4rem 0 0; padding-left: 1.1rem; }
.ot-oshibki-spisok li { margin-bottom: 0.2rem; }

.k-filtr {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem 1.25rem;
  margin-bottom: 1rem; padding-bottom: 0.9rem; border-bottom: 1px solid var(--border);
}
.k-filtr-presety { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.k-filtr-btn {
  padding: 0.35rem 0.8rem; border: 1px solid var(--border); border-radius: var(--radius);
  color: var(--text-dim); text-decoration: none; font-size: 0.85rem;
  transition: var(--transition);
}
.k-filtr-btn:hover { color: var(--text); border-color: var(--accent); }
.k-filtr-btn-tekushiy { background: var(--accent); border-color: var(--accent); color: #fff; }
.k-filtr-svoy { display: flex; flex-wrap: wrap; align-items: end; gap: 0.6rem; }
.k-filtr-svoy label {
  display: flex; flex-direction: column; gap: 0.2rem;
  font-size: 0.75rem; color: var(--text-dim);
}
.k-filtr-svoy input, .k-filtr-svoy select {
  padding: 0.4rem 0.5rem; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg); color: var(--text); font: inherit;
}
.k-filtr-svoy .maket-otpravit { margin-top: 0; padding: 0.4rem 1rem; }

/* Готовность полосой: голое «53 %» не отвечает на вопрос «много это или мало».
   Полоса отвечает с одного взгляда, а число остаётся для точности.
   Хозяин 05.09: «мне не нравятся карточки проектов». */
.pokazatel.gotovnost {
  flex-basis: 100%;
  min-width: 8rem;
}
.pokazatel.gotovnost .polosa {
  display: block;
  height: 0.35rem;
  margin-top: 0.2rem;
  border-radius: 0.2rem;
  /* Не var(--border): у карточек без службы это и есть цвет фона, полоса
     сливалась бы с ней целиком (поймано живым снимком 05.09). */
  background: var(--bg);
  overflow: hidden;
}
.pokazatel.gotovnost .polosa::before {
  content: "";
  display: block;
  height: 100%;
  width: var(--dolya, 0%);
  background: var(--accent);
  border-radius: inherit;
}
/* Карточка без службы бейджа не носит: «сайта нет» — про веб-морду, а не про
   проект. У Синхрониста он стоял рядом с «3 часа назад» и «53 %», и карточка
   кричала «нет» о проекте живее многих. Отсутствие бейджа и значит «службы,
   которую можно опросить, у проекта нет». */
.proekty li[data-sostoyanie="сайта нет"] {
  opacity: 1;
  border: 1px solid var(--border);
  border-left: 0.5rem solid var(--border);
}

/* Фоновый сбор сломался — говорим об этом рядом с возрастом данных, а не
   молчим. Возраст сам по себе скажет «данные старые», но не скажет почему. */
.beda-sbora {
  flex-basis: 100%;
  margin: 0.35rem 0;
  padding: 0.4rem 0.65rem;
  border-radius: var(--radius);
  background: var(--trevoga);
  color: var(--bg);
  font-size: 0.9rem;
  font-weight: 600;
}

/* Каталог v2: фасеты слева, карточки Kaspi справа. Хозяин прямо
   недоволен прежним построчным списком («всё свалено в кучу») —
   боковая панель отвечает на «что тут вообще есть», список — на
   «какой конкретно товар». */
.k-katalog-v2 { display: grid; grid-template-columns: 15rem 1fr; gap: 1.5rem; align-items: start; }
@media (max-width: 800px) { .k-katalog-v2 { grid-template-columns: 1fr; } }

.k-facety { display: flex; flex-direction: column; gap: 1rem; position: sticky; top: 1rem; }
.k-facet-gruppa { border: 1px solid var(--border); border-radius: var(--radius); padding: 0.75rem 0.9rem; }
.k-facet-gruppa h3 {
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--text-dim); margin: 0 0 0.6rem; font-weight: 600;
}
.k-facet-stroka {
  display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem;
  padding: 0.2rem 0; cursor: pointer;
}
.k-facet-stroka input { flex-shrink: 0; }
.k-facet-znachenie { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-facet-chislo { color: var(--text-dim); font-variant-numeric: tabular-nums; font-size: 0.8rem; }
.k-facet-primeniti {
  margin-top: 0.6rem; width: 100%; padding: 0.4rem; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--bg); color: var(--text); font: inherit; cursor: pointer;
}
.k-facet-primeniti:hover { border-color: var(--accent); color: var(--accent); }
.k-facet-primechanie { font-size: 0.75rem; color: var(--text-dim); margin-top: 0.4rem; }

.k-tovar-karta { border: 1px solid var(--border); border-radius: var(--radius); padding: 0.9rem 1rem; margin-bottom: 0.75rem; }
.k-tovar-shapka { display: flex; justify-content: space-between; gap: 1rem; align-items: flex-start; flex-wrap: wrap; }
.k-tovar-nazvanie { font-weight: 600; font-size: 0.95rem; }
.k-tovar-kaspi-id { font-size: 0.75rem; color: var(--text-dim); margin-top: 0.1rem; }
.k-tovar-summa { text-align: right; white-space: nowrap; }
.k-tovar-roznica { font-weight: 700; font-variant-numeric: tabular-nums; }
.k-tovar-ostatok { font-size: 0.8rem; color: var(--text-dim); }
.k-tovar-postavshchiki { margin-top: 0.6rem; }
.k-tovar-postavshchiki summary {
  cursor: pointer; font-size: 0.8rem; color: var(--accent); list-style: none;
}
.k-tovar-postavshchiki summary::-webkit-details-marker { display: none; }
.k-tovar-postavshchiki[open] summary { margin-bottom: 0.4rem; }
.k-soderzhimoye { display: flex; gap: 0.35rem; margin-top: 0.5rem; }
.k-indikator {
  font-size: 0.7rem; padding: 0.1rem 0.45rem; border-radius: 10px;
  border: 1px solid var(--border); color: var(--text-dim);
}
.k-indikator-est { border-color: var(--accent); color: var(--accent); }

.k-nesopostavlennye { margin-top: 1.75rem; border-top: 1px dashed var(--border); padding-top: 1rem; }
.k-nesopostavlennye h2 { font-size: 1rem; margin-bottom: 0.5rem; }

.doli-legenda { margin: 0.15rem 0 0.5rem; font-size: 0.75rem; max-width: 60ch; }
.doli-legenda .doli-krasnyy { color: var(--trevoga); font-weight: 600; }
/* Иерархия чисел: возраст данных крупнее всего, готовность вторая, остальное ровно. */
.pokazatel.gotovnost .tekst { font-size: 1rem; font-weight: 700; }

/* Требует решения Хозяина (макет docs/maket-glavnaya-trebuet-resheniya.html).
   Первым на странице, красная шапка, значок: раньше это был мелкий шрифт. */
.reshit { border: 2px solid var(--trevoga); border-radius: var(--radius); background: #fff; margin: 0.6rem 0; }
.reshit h2 { margin: 0; padding: 0.45rem 0.7rem; font-size: 1.05rem; background: var(--trevoga); color: #fff; }
.reshit ul { list-style: none; margin: 0; padding: 0; }
.reshit li { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.55rem 0.7rem; border-top: 1px solid var(--border); }
.reshit li:first-child { border-top: 0; }
.reshit .znak { flex: none; width: 1.4rem; height: 1.4rem; border-radius: 50%; color: #fff; font-weight: 700; text-align: center; line-height: 1.4rem; font-size: 0.9rem; }
.reshit .znak.bad { background: var(--trevoga); }
.reshit .znak.warn { background: var(--predupr); }
.reshit .chto { font-size: 1.05rem; font-weight: 600; }
.reshit .pochemu { font-size: 0.88rem; color: var(--text-dim); }
.reshit a.kuda { margin-left: auto; flex: none; font-size: 0.9rem; color: var(--text); border: 1px solid var(--text); border-radius: var(--radius); padding: 0.2rem 0.5rem; text-decoration: none; white-space: nowrap; }
.reshit.pusto { border-color: var(--accent); }
.reshit.pusto h2 { background: var(--accent); }
@media (max-width: 600px) { .reshit li { flex-wrap: wrap; } .reshit a.kuda { margin-left: 2rem; } }
/* «устарел» в карточке проекта — цветом и значком (судья 15.10, находка 2) */
.pokazatel.vozrast.ustarel .tekst, .pokazatel.ustarel .tekst { color: var(--trevoga); font-weight: 600; }
.pokazatel.ustarel .tekst::before { content: "⏱ "; }
.net-sayta { font-size: 0.75rem; color: var(--text-dim); }
.doli-bez-raboty { font-size: 0.8rem; color: var(--text-dim); margin: 0.4rem 0 0; }

.bez-sayta { margin-top: 12px; }
.bez-sayta > summary { cursor: pointer; color: var(--text-dim); padding: 6px 0; }
.bez-sayta[open] > summary { margin-bottom: 8px; }
