@import url('fonts.css');

/* ============================================================================
   Экран руководителя СНТР. Язык оформления взят из ролика, который прислал
   Камиль: матовый почти чёрный фон с зерном, тяжёлый гротеск заголовков,
   техническая моноширинная подпись, тонкие линии, концентрические окружности
   радара. Центр делает беспилотные системы — отсюда развёртка луча в фоне и
   приборная сетка, а не абстрактные градиенты.

   Четыре правила, которые здесь нельзя нарушать:
   1. Ни одной загрузки со стороны. Закрытый контур внешние библиотеки и
      шрифты не пропустит, и экран приедет чужим.
   2. Движение служит делу. Анимация показывает, что данные пришли, что строка
      сменила состояние, что фон живой — но не развлекает и не мешает читать.
   3. Цвет — только сигнал. Палитра одноцветная; краска появляется там, где
      человек должен отреагировать, и больше нигде.
   4. Состояние задачи и её срок — РАЗНЫЕ знаки. Пока просрочка красила метку
      состояния, «в работе» у просроченной задачи было красным: два разных
      факта дрались за один знак, и оба читались неверно.
   ========================================================================= */

:root {
  color-scheme: dark;

  --bg:        #141416;
  --bg-deep:   #0F0F11;
  --panel:     #1A1A1C;
  --panel-up:  #202023;
  --panel-hi:  #26262A;
  --line:      #2A2A2E;
  --line-soft: #212125;

  --ink:       #F4F2EC;   /* тёплый белый из ролика */
  --ink-mid:   #B4B2AC;
  /* Технической краской набрано подразделение рядом с фамилией, подписи
     колонок и объяснения настроек. #6E6C68 давал 3,3:1 — ниже нормы
     читаемости; на матовом чёрном это заметно сразу. */
  --ink-dim:   #8E8B85;

  /* Сигналы. Приглушены намеренно: на чёрном чистый красный визжит и
     перетягивает внимание с содержания на себя. */
  --late:      #D9553F;   /* просрочено */
  --soon:      #D9A441;   /* горит: сегодня-завтра */
  --wait:      #7FA8BF;   /* ждёт вашего решения */
  --done:      #6E8F72;   /* принято */
  --work:      #C9C6BE;   /* в работе — нейтральный, это норма */
  --sign:      #9A86C4;   /* согласование и особые права */

  /* Производные краски. Каждая строка ниже раньше стояла числом ПО МЕСТУ —
     в рамке метки, в тени, в градиенте шапки. На светлой теме такие числа
     не переопределяются ничем и остаются тёмными пятнами посреди бумаги,
     поэтому они собраны сюда. Правило простое: если в файле ниже появился
     `#…` или `rgba(…)` — ему место здесь, а не там. */
  --chip-work-line: #3A3A3F;
  --chip-wait-line: rgba(127,168,191,.4);
  --chip-done-line: rgba(110,143,114,.45);
  --chip-late-line: rgba(217,85,63,.45);
  --chip-soon-line: rgba(217,164,65,.45);
  --chip-sign-line: rgba(154,134,196,.45);
  --chip-back-line: rgba(217,164,65,.35);
  --danger-line:    rgba(217,85,63,.4);
  --danger-wash:    rgba(217,85,63,.12);
  --today-wash:     rgba(217,164,65,.06);
  --today-line:     rgba(217,164,65,.3);
  --empty-day:      rgba(0,0,0,.14);
  --field-focus:    #0C0C0E;
  --placeholder:    #7A7770;
  --check-accent:   #8A8780;
  --top-a:          rgba(20,20,22,.96);
  --top-b:          rgba(20,20,22,.75);
  --bg-fade:        rgba(20,20,22,0);
  --grain:          .07;

  /* Фон-радар рисуется скриптом. Скрипт не видит классы и берёт краску
     отсюда: иначе на светлой теме поверх бумаги остались бы белые линии,
     то есть пустой экран вместо фона. */
  --radar-grid:   rgba(255,255,255,.022);
  --radar-ring:   rgba(255,255,255,.045);
  --radar-beam:   244,242,236;
  --radar-beam-a: .05;

  --mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;
  --sans: 'Golos Text', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --gap: 20px;
  --radius: 3px;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ---------------------------------------------------------- светлая тема

   Тёмная выше — исходная и главная: её видят каждый день, и она не меняется
   ни на одно число. Светлая только ПЕРЕОПРЕДЕЛЯЕТ токены, ни одного нового
   правила вёрстки здесь нет.

   Язык оформления тот же и на бумаге: одноцветность (краска — только сигнал),
   срок и состояние — разные знаки, тонкие линии, моноширинные подписи.
   Сигналы затемнены: #D9553F на белом даёт 3,1:1 и читается как розовый —
   на бумаге кричит не насыщенность, а тёмность.

   ДВА БЛОКА НИЖЕ ОБЯЗАНЫ СОВПАДАТЬ. Первый — явный выбор человека, второй —
   умолчание по настройке системы. Правишь цвет — правь в обоих; расхождение
   даст экран, который выглядит по-разному до и после нажатия переключателя.
   Одним блоком это не пишется: медиазапрос нельзя вложить в список
   селекторов, а `light-dark()` уронил бы палитру целиком на браузере,
   который его не знает. */

:root[data-theme="light"] {
  color-scheme: light;

  --bg:        #EFEDE7;   /* тёплая бумага, не белизна экрана */
  --bg-deep:   #E4E1DA;
  --panel:     #F7F5F0;
  --panel-up:  #ECE9E2;
  --panel-hi:  #E3E0D8;
  --line:      #CFCBC0;
  --line-soft: #DFDBD1;

  --ink:       #17171A;
  --ink-mid:   #4A4842;
  --ink-dim:   #6B6862;   /* 4,7:1 к бумаге — приглушённое, но читаемое */

  --late:      #A8341C;
  --soon:      #7A5410;   /* охра: жёлтый на бумаге не виден вовсе */
  --wait:      #2C5F7C;
  --done:      #3A6140;
  --work:      #55524B;
  --sign:      #5B4288;

  --chip-work-line: #C6C2B6;
  --chip-wait-line: rgba(44,95,124,.45);
  --chip-done-line: rgba(58,97,64,.45);
  --chip-late-line: rgba(168,52,28,.45);
  --chip-soon-line: rgba(122,84,16,.45);
  --chip-sign-line: rgba(91,66,136,.45);
  --chip-back-line: rgba(122,84,16,.35);
  --danger-line:    rgba(168,52,28,.4);
  --danger-wash:    rgba(168,52,28,.1);
  --today-wash:     rgba(122,84,16,.09);
  --today-line:     rgba(122,84,16,.35);
  --empty-day:      rgba(23,23,26,.06);
  --field-focus:    #FFFFFF;
  --placeholder:    #6F6C64;
  --check-accent:   #55524B;
  --top-a:          rgba(239,237,231,.96);
  --top-b:          rgba(239,237,231,.75);
  --bg-fade:        rgba(239,237,231,0);
  /* Зерно на бумаге грязнит вдвое сильнее, чем на чёрном: та же плотность
     читается как плохая печать, а не как матовая поверхность. */
  --grain:          .035;

  --radar-grid:   rgba(20,20,26,.05);
  --radar-ring:   rgba(20,20,26,.08);
  --radar-beam:   30,30,38;
  --radar-beam-a: .05;
}

@media (prefers-color-scheme: light) {
  /* Умолчание — настройка системы. `:not([data-theme="dark"])` обязательно:
     без него явно выбранная тёмная переставала работать на светлой системе. */
  :root:not([data-theme="dark"]) {
    color-scheme: light;

    --bg:        #EFEDE7;
    --bg-deep:   #E4E1DA;
    --panel:     #F7F5F0;
    --panel-up:  #ECE9E2;
    --panel-hi:  #E3E0D8;
    --line:      #CFCBC0;
    --line-soft: #DFDBD1;

    --ink:       #17171A;
    --ink-mid:   #4A4842;
    --ink-dim:   #6B6862;

    --late:      #A8341C;
    --soon:      #7A5410;
    --wait:      #2C5F7C;
    --done:      #3A6140;
    --work:      #55524B;
    --sign:      #5B4288;

    --chip-work-line: #C6C2B6;
    --chip-wait-line: rgba(44,95,124,.45);
    --chip-done-line: rgba(58,97,64,.45);
    --chip-late-line: rgba(168,52,28,.45);
    --chip-soon-line: rgba(122,84,16,.45);
    --chip-sign-line: rgba(91,66,136,.45);
    --chip-back-line: rgba(122,84,16,.35);
    --danger-line:    rgba(168,52,28,.4);
    --danger-wash:    rgba(168,52,28,.1);
    --today-wash:     rgba(122,84,16,.09);
    --today-line:     rgba(122,84,16,.35);
    --empty-day:      rgba(23,23,26,.06);
    --field-focus:    #FFFFFF;
    --placeholder:    #6F6C64;
    --check-accent:   #55524B;
    --top-a:          rgba(239,237,231,.96);
    --top-b:          rgba(239,237,231,.75);
    --bg-fade:        rgba(239,237,231,0);
    --grain:          .035;

    --radar-grid:   rgba(20,20,26,.05);
    --radar-ring:   rgba(20,20,26,.08);
    --radar-beam:   30,30,38;
    --radar-beam-a: .05;
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Зерно поверх всего. SVG-шум встроен прямо сюда: отдельной картинкой это
   была бы ещё одна загрузка, а в закрытом контуре каждая загрузка — риск. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 90;
  opacity: var(--grain);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
}

/* Холст фона: медленные окружности и развёртка луча. Лежит под всем и не
   ловит мышь. Рисуется в `app.js`, здесь только место. */
#bg {
  position: fixed;
  inset: 0;
  /* Ширина и высота обязательны. `inset: 0` растягивает обычный блок, но у
     canvas есть собственный размер 300x150, и без этих двух строк фон
     рисуется в левом верхнем углу — что и произошло при первой выкладке. */
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.wrap { position: relative; z-index: 1; }
.shell { max-width: 1420px; margin: 0 auto; padding: 0 32px 80px; }

/* ------------------------------------------------------------ типографика */

h1, h2, h3 {
  font-weight: 900;
  letter-spacing: -.02em;
  line-height: 1.05;
  margin: 0;
  text-transform: uppercase;
}
h1 { font-size: clamp(30px, 3.4vw, 46px); }
h2 { font-size: clamp(19px, 1.7vw, 24px); }
h3 { font-size: 17px; letter-spacing: -.01em; }

a { color: inherit; text-decoration: none; }

.label {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-dim);
  display: inline-block;
}
.meta {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--ink-dim);
}
.mono { font-family: var(--mono); }
.hint { display: block; font-family: var(--mono); font-size: 11px; color: var(--ink-dim);
        margin-top: 5px; letter-spacing: .02em; }

.body-text { white-space: pre-wrap; word-wrap: break-word; margin-top: 6px; }

.mb-h { margin-bottom: 14px; }
.mb-s { margin-bottom: 10px; }
.mb-m { margin-bottom: 22px; }
.mb-l { margin-bottom: 42px; }
.mt-s { margin-top: 12px; }
.ml-s { margin-left: 10px; }
.grow { flex: 1 1 220px; }

/* ------------------------------------------------------------------ шапка */

.top {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 22px 0 16px;
  border-bottom: 1px solid var(--line-soft);
  position: sticky;
  top: 0;
  z-index: 40;
  background: linear-gradient(to bottom, var(--top-a) 60%, var(--top-b));
  backdrop-filter: blur(6px);
}
.spacer { flex: 1; }
.mark { display: flex; align-items: baseline; gap: 12px; }
.mark b {
  font-size: 21px; font-weight: 900; letter-spacing: .16em;
  font-family: var(--mono);
}
.mark span { font-family: var(--mono); font-size: 10px; letter-spacing: .3em;
             color: var(--ink-dim); text-transform: uppercase; }
.mark.big { display: block; text-align: center; margin-bottom: 26px; }
.mark.big b { font-size: 40px; display: block; }
.mark.big .sub { display: block; margin-top: 8px; letter-spacing: .26em; }
.me { display: flex; align-items: center; gap: 9px; }
.out { opacity: .7; transition: opacity .2s var(--ease); }
.out:hover { opacity: 1; color: var(--late); }

/* Переключатель темы. Значок — половина закрашенного круга, нарисован рамкой
   и псевдоэлементом: ещё один файл значка в закрытом контуре не нужен, а
   встроенный `style=` режет политика безопасности. Краски своей у значка нет,
   он берёт `currentColor` — то есть переворачивается вместе с темой сам. */
.theme-btn { padding: 9px 11px; }
.theme-ic {
  display: block; width: 15px; height: 15px; border-radius: 50%;
  border: 1.5px solid currentColor; position: relative; overflow: hidden;
}
.theme-ic::after {
  content: ''; position: absolute; top: -1px; bottom: -1px; left: 50%; right: -1px;
  background: currentColor;
}

/* Вкладки. Полоска под активной едет за курсором — это единственное место,
   где движение отвечает на наведение: по вкладкам ходят чаще всего. */
.tabs { display: flex; gap: 4px; padding: 14px 0 0; margin-bottom: 30px;
        border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
.tabs a {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-dim);
  padding: 9px 15px 13px; position: relative;
  transition: color .2s var(--ease);
}
.tabs a::after {
  content: ''; position: absolute; left: 15px; right: 15px; bottom: -1px;
  height: 2px; background: var(--ink); transform: scaleX(0); transform-origin: left;
  transition: transform .28s var(--ease);
}
.tabs a:hover { color: var(--ink-mid); }
.tabs a:hover::after { transform: scaleX(.4); background: var(--ink-dim); }
.tabs a.on { color: var(--ink); }
.tabs a.on::after { transform: scaleX(1); }

/* ---------------------------------------------------------------- панели */

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px 20px;
  position: relative;
}
/* Уголки-скобки — приборная деталь из ролика. Рисуются градиентами, чтобы не
   плодить элементы в разметке. */
.panel.bracketed::before,
.panel.bracketed::after {
  content: ''; position: absolute; width: 12px; height: 12px; pointer-events: none;
  border-color: var(--ink-dim); border-style: solid; opacity: .5;
}
.panel.bracketed::before { top: -1px; left: -1px; border-width: 1px 0 0 1px; }
.panel.bracketed::after { bottom: -1px; right: -1px; border-width: 0 1px 1px 0; }

.grid { display: grid; gap: var(--gap); }
.grid.four { grid-template-columns: repeat(4, 1fr); }
.grid.two { grid-template-columns: repeat(2, 1fr); }

.sec-head { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
            margin-bottom: 14px; }
.sec-head h1, .sec-head h2 { margin-bottom: 0; }
.sec-head .meta { margin-left: auto; }

/* Плитка со счётчиком. Кликается целиком и ведёт на отобранный список: число
   без перехода к тому, из чего оно сложилось, — украшение. */
.tile {
  display: flex; flex-direction: column; gap: 6px; min-height: 118px;
  transition: transform .25s var(--ease), border-color .25s var(--ease),
              background .25s var(--ease);
}
a.tile:hover { transform: translateY(-2px); border-color: var(--ink-dim);
               background: var(--panel-up); }
a.tile:hover .tile-go { opacity: 1; transform: translateX(0); }
.tile-go { font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em;
           text-transform: uppercase; color: var(--ink-dim); margin-top: auto;
           opacity: 0; transform: translateX(-4px);
           transition: opacity .25s var(--ease), transform .25s var(--ease); }
.num {
  font-family: var(--mono); font-size: 44px; font-weight: 700; line-height: 1;
  letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.num.small { font-size: 26px; }
.num.tiny { font-size: 17px; }
.num.zero { color: var(--ink-dim); }
.num.late { color: var(--late); }
.num.wait { color: var(--wait); }
.num.soon { color: var(--soon); }
.num.sign { color: var(--sign); }

/* ---------------------------------------------------------------- таблицы */

.tablewrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead th {
  font-family: var(--mono); font-size: 10px; letter-spacing: .17em;
  text-transform: uppercase; color: var(--ink-dim); font-weight: 400;
  text-align: left; padding: 0 14px 10px 0; white-space: nowrap;
}
td { padding: 13px 14px 13px 0; border-top: 1px solid var(--line-soft);
     vertical-align: top; }
th.last, td.last { text-align: right; padding-right: 0; }
td.n { width: 46px; color: var(--ink-dim); font-size: 12px; }
td.when { font-family: var(--mono); font-size: 11.5px; color: var(--ink-mid);
          white-space: nowrap; }
td.when.late { color: var(--late); }
td.when.soon { color: var(--soon); }
td.title a { border-bottom: 1px solid transparent; transition: border-color .2s var(--ease); }
td.title a:hover { border-bottom-color: var(--ink); }
td.note-cell { color: var(--ink-mid); font-size: 13.5px; max-width: 280px; }

/* Строка кликается целиком: попадать мышью в ссылку названия на строке
   высотой в две строки текста — отдельное упражнение. Слева у строки
   появляется полоска состояния. */
tr[data-href] { cursor: pointer; transition: background .18s var(--ease); }
tr[data-href]:hover { background: var(--panel-up); }
tr[data-href] td:first-child { position: relative; }
tr[data-href] td:first-child::before {
  content: ''; position: absolute; left: -10px; top: 8px; bottom: 8px; width: 2px;
  background: transparent; transition: background .2s var(--ease);
}
tr.late td:first-child::before { background: var(--late); }
tr.soon td:first-child::before { background: var(--soon); }
tr.wait td:first-child::before { background: var(--wait); }
tr.done td:first-child::before { background: var(--done); }

/* ------------------------------------------------------------------ метки */

.chip {
  display: inline-block; font-family: var(--mono); font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase;
  padding: 3px 8px; border: 1px solid var(--line); border-radius: 2px;
  color: var(--ink-mid); white-space: nowrap;
}
.chip.work { color: var(--work); border-color: var(--chip-work-line); }
.chip.wait { color: var(--wait); border-color: var(--chip-wait-line); }
.chip.done { color: var(--done); border-color: var(--chip-done-line); }
.chip.late { color: var(--late); border-color: var(--chip-late-line); }
.chip.soon { color: var(--soon); border-color: var(--chip-soon-line); }
.chip.sign { color: var(--sign); border-color: var(--chip-sign-line); }
.chip.back { color: var(--soon); border-color: var(--chip-back-line); }
.chip.off  { color: var(--ink-dim); }

/* Кружок с инициалами. Две буквы, а не одна: в центре две Вероники, две
   Анастасии и пять Александров. */
.ava {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex: 0 0 30px; border-radius: 50%;
  background: var(--panel-hi); border: 1px solid var(--line);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .04em;
  color: var(--ink-mid);
}
.ava.small { width: 24px; height: 24px; flex-basis: 24px; font-size: 9px; }
.ava.big { width: 62px; height: 62px; flex-basis: 62px; font-size: 20px;
           color: var(--ink); }

.who { display: inline-flex; align-items: center; gap: 10px; }
.who-name { display: flex; flex-direction: column; line-height: 1.25; }
.who-unit { font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
            text-transform: uppercase; color: var(--ink-dim); }
a.who:hover .who-name { color: var(--ink); }
a.who:hover .ava { border-color: var(--ink-dim); }

/* Полоска загрузки. Ширина задаётся классом с шагом 5%: встроенный стиль
   режет политика безопасности, и полоска молча оставалась бы нулевой. */
.bar { display: block; height: 3px; background: var(--line); margin-top: 7px;
       max-width: 160px; border-radius: 2px; overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--ink-mid);
         transition: width .5s var(--ease); }
.bar.full i { background: var(--soon); }
.bar.over i { background: var(--late); }
.load { font-family: var(--mono); font-size: 12px; color: var(--ink-mid); }
.load b { color: var(--ink); font-weight: 700; }
.load b.late { color: var(--late); }
/* Красным — только сама цифра или слово о просрочке. Общее правило `.late`
   красило ВСЮ строку таблицы, потому что этот же класс стоит на `tr` ради
   полоски состояния слева: название задачи становилось красным, и «горит»
   переставало отличаться от «просрочено». */
span.late, b.late { color: var(--late); }

.w0 { width: 0; } .w5 { width: 5%; } .w10 { width: 10%; } .w15 { width: 15%; }
.w20 { width: 20%; } .w25 { width: 25%; } .w30 { width: 30%; } .w35 { width: 35%; }
.w40 { width: 40%; } .w45 { width: 45%; } .w50 { width: 50%; } .w55 { width: 55%; }
.w60 { width: 60%; } .w65 { width: 65%; } .w70 { width: 70%; } .w75 { width: 75%; }
.w80 { width: 80%; } .w85 { width: 85%; } .w90 { width: 90%; } .w95 { width: 95%; }
.w100 { width: 100%; }

.empty {
  padding: 34px 0; text-align: center; font-family: var(--mono); font-size: 11.5px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-dim);
}
.note { border-left: 2px solid var(--late); padding: 11px 14px; background: var(--panel-up);
        font-size: 14px; }
.note.ok { border-left-color: var(--done); }

/* -------------------------------------------------------- кнопки и формы */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink);
  background: var(--panel-hi); border: 1px solid var(--line);
  padding: 11px 18px; border-radius: var(--radius); cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease),
              transform .1s var(--ease);
}
.btn:hover { background: var(--panel-up); border-color: var(--ink-dim); }
/* Видимый фокус с клавиатуры. Без него человек, идущий по форме табуляцией,
   не знает, где он находится, — а на тёмной теме собственная рамка браузера
   почти не читается. `:focus-visible`, а не `:focus`: обводка после щелчка
   мышью выглядит поломкой. */
.btn:focus-visible, a:focus-visible, summary:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
.switch input:focus-visible + i {
  outline: 2px solid var(--wait);
  outline-offset: 2px;
}
tr[data-href]:focus-within { background: var(--panel-up); }
.btn:active { transform: translateY(1px); }
.btn.ghost { background: transparent; color: var(--ink-mid); }
.btn.ghost:hover { color: var(--ink); }
.btn.small { padding: 7px 12px; font-size: 10px; }
.btn.btn-wide { width: 100%; }
.btn.danger { color: var(--late); border-color: var(--danger-line); }
.btn.danger:hover { background: var(--danger-wash); border-color: var(--late); }

.field { display: block; margin-bottom: 16px; }
.field .label { margin-bottom: 7px; }
input[type=text], input[type=password], input[type=number], textarea, select {
  width: 100%; background: var(--bg-deep); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 11px 13px; font-family: var(--mono); font-size: 13px;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
textarea { font-family: var(--sans); font-size: 14.5px; resize: vertical; }
input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--ink-dim); background: var(--field-focus);
}
/* Подсказка в поле — единственное указание формата срока. Прежний #4A4844
   давал контраст 2,1:1: её просто не было видно. */
input::placeholder, textarea::placeholder { color: var(--placeholder); }
select { cursor: pointer; }
.pick { width: auto; min-width: 150px; }
/* Внутри поля с подписью выпадающий список тянется на всю ширину: «по
   содержимому» он встаёт в строку с подписью, и форма выглядит собранной
   наспех. */
.field .pick, .field select { width: 100%; }
.pick.narrow { min-width: 90px; width: 90px; text-align: right; }
.check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.check input { width: auto; }
input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--check-accent); cursor: pointer; }
/* Квадратик галочки не тянется во всю строку. Правило `.panel.side input`
   ниже написано для полей ввода в боковой колонке — но по весу попадает и
   сюда: на карточке задачи галочка «снять срок» раздувалась до 125 пикселей
   в ширину, отнимала место у подписи, и подпись рвалась в узкий столбик,
   разъезжаясь с самим квадратиком. Видно на любой ширине, не только на
   телефоне. Оба селектора нужны: второй перевешивает `.panel.side input`,
   первый закрывает те же галочки вне боковой колонки. */
.check input[type=checkbox],
.panel.side .check input[type=checkbox] { flex: 0 0 16px; width: 16px; height: 16px; }
/* В боковой колонке поля во всю ширину: там 340 пикселей, и поле «по
   содержимому» уезжает под подпись. */
.panel.side .pick, .panel.side select, .panel.side input { width: 100%; }
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.edit-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; }
.row-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* Выключатель для настроек. Обычная галочка на тёмном почти не видна, а
   настройку «выходные — тоже тишина» читают глазами по одному знаку. */
.switch { position: relative; display: inline-block; width: 42px; height: 22px;
          flex: 0 0 42px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%;
                margin: 0; cursor: pointer; z-index: 2; }
.switch i { position: absolute; inset: 0; background: var(--bg-deep);
            border: 1px solid var(--line); border-radius: 12px;
            transition: background .2s var(--ease), border-color .2s var(--ease); }
.switch i::after { content: ''; position: absolute; top: 3px; left: 3px;
                   width: 14px; height: 14px; border-radius: 50%;
                   background: var(--ink-dim); transition: transform .22s var(--ease),
                   background .22s var(--ease); }
.switch input:checked + i { border-color: var(--chip-done-line); }
.switch input:checked + i::after { transform: translateX(20px); background: var(--done); }

/* ------------------------------------------------------------- сообщение */

.toast {
  position: sticky; top: 74px; z-index: 45;
  display: flex; align-items: center; gap: 14px;
  background: var(--panel-up); border: 1px solid var(--line);
  border-left: 2px solid var(--done);
  padding: 12px 16px; margin-bottom: 20px; border-radius: var(--radius);
  animation: toast-in .45s var(--ease) both;
}
.toast.bad { border-left-color: var(--late); }
.toast span { flex: 1; font-size: 14px; }
.toast .x { background: none; border: none; color: var(--ink-dim); font-size: 19px;
            cursor: pointer; line-height: 1; padding: 0 4px; }
.toast .x:hover { color: var(--ink); }
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px); } }

/* --------------------------------------------------------------- разделы */

.two-col { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 28px;
           align-items: start; }
.col-side { position: sticky; top: 96px; }
.panel.side { padding: 16px 18px; }
.panel.side .label { margin-bottom: 10px; }
.side-people { display: flex; flex-direction: column; gap: 14px; }
.side-person .meta { margin-top: 4px; margin-left: 40px; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 7px 14px; align-items: baseline; }
.kv .k { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em;
         text-transform: uppercase; color: var(--ink-dim); }
.kv .v { font-size: 13.5px; text-align: right; }

.back { display: inline-block; font-family: var(--mono); font-size: 11px;
        letter-spacing: .12em; color: var(--ink-dim); margin-bottom: 14px;
        transition: color .2s var(--ease); }
.back:hover { color: var(--ink); }
.task-head { margin-bottom: 26px; }
.task-head h1 { margin-bottom: 10px; }

/* Обсуждение лентой. Тип записи виден полоской слева: отчёт о работе,
   возврат и обычный комментарий читаются по-разному, а выглядели одинаково. */
.tl .talk { display: flex; gap: 12px; padding: 14px 0 14px 14px;
            border-top: 1px solid var(--line-soft); border-left: 2px solid transparent; }
.tl .talk:first-child { border-top: none; }
.tl .talk.report { border-left-color: var(--done); }
.tl .talk.back { border-left-color: var(--soon); }
.tl .talk.ask { border-left-color: var(--wait); }
.tl .talk.done { border-left-color: var(--done); }
.talk-body { flex: 1; min-width: 0; }

.comment textarea { min-height: 80px; }

details.panel { padding: 0; }
details.panel > summary {
  list-style: none; cursor: pointer; padding: 16px 20px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-mid);
  display: flex; align-items: center; gap: 10px;
  transition: color .2s var(--ease);
}
details.panel > summary::-webkit-details-marker { display: none; }
details.panel > summary::before { content: '+'; font-size: 15px; color: var(--ink-dim); }
details.panel[open] > summary::before { content: '−'; }
details.panel > summary:hover { color: var(--ink); }
details.panel > form, details.panel > div, details.panel > .tablewrap {
  padding: 0 20px 20px;
}
details.panel.danger > summary { color: var(--late); }
details.panel.side { margin-top: 0; }

.journal td { font-size: 13px; }

/* --------------------------------------------------------------- календарь */

.cal-top { display: flex; align-items: flex-end; justify-content: space-between;
           gap: 20px; flex-wrap: wrap; }
.cal { padding: 12px; }
.cal-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-head .cal-cell { min-height: 0; padding: 6px 8px; border: none; }
.cal-cell { min-height: 112px; border-top: 1px solid var(--line-soft);
            border-left: 1px solid var(--line-soft); padding: 8px; min-width: 0;
            transition: background .2s var(--ease); }
.cal-week .cal-cell:first-child { border-left: none; }
.cal-cell:hover { background: var(--panel-up); }
.cal-cell.empty-day { background: var(--empty-day); }
.cal-cell.today { background: var(--today-wash); box-shadow: inset 0 0 0 1px var(--today-line); }
.cal-day { font-family: var(--mono); font-size: 12px; color: var(--ink-dim);
           margin-bottom: 6px; }
.cal-item { display: block; font-size: 12px; line-height: 1.3; padding: 4px 6px;
            margin-bottom: 4px; border-left: 2px solid var(--line);
            background: var(--panel-up); border-radius: 2px;
            overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
            transition: transform .18s var(--ease), background .18s var(--ease); }
.cal-item:hover { transform: translateX(2px); background: var(--panel-hi); }
.cal-item b { font-family: var(--mono); font-size: 10px; color: var(--ink-dim);
              margin-right: 4px; }
.cal-item.late { border-left-color: var(--late); }
.cal-item.soon { border-left-color: var(--soon); }
.cal-item.wait { border-left-color: var(--wait); }
.cal-item.done { border-left-color: var(--done); opacity: .55; }
.legend { margin-top: 14px; display: flex; align-items: center; gap: 8px;
          flex-wrap: wrap; }
.legend .dot { display: inline-block; width: 8px; height: 8px; border-radius: 2px;
               background: var(--line); margin-left: 12px; }
.legend .dot:first-child { margin-left: 0; }
.legend .dot.work { background: var(--work); }
.legend .dot.wait { background: var(--wait); }
.legend .dot.soon { background: var(--soon); }
.legend .dot.late { background: var(--late); }

/* -------------------------------------------------------------------- люди */

.person-head { display: flex; align-items: center; gap: 20px; margin-bottom: 26px; }
.people td { vertical-align: middle; }
/* Чем человек занят: одна-две ближайшие задачи прямо в списке людей. Полоска
   слева — то же состояние, что и в таблице задач, чтобы взгляд не переучивался. */
.work-cell { max-width: 300px; }
a.work { display: block; font-size: 13px; line-height: 1.3; padding: 2px 0 2px 8px;
         border-left: 2px solid var(--line); margin-bottom: 3px;
         overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
         color: var(--ink-mid); transition: color .18s var(--ease); }
a.work:hover { color: var(--ink); }
a.work.late { border-left-color: var(--late); }
a.work.soon { border-left-color: var(--soon); }
a.work.wait { border-left-color: var(--wait); }
.unit-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px;
             margin: 14px 0; }
.unit-grid .label { display: block; margin-bottom: 3px; }
a.unit { display: block; transition: transform .25s var(--ease),
         border-color .25s var(--ease), background .25s var(--ease); }
a.unit:hover { transform: translateY(-2px); border-color: var(--ink-dim);
               background: var(--panel-up); }

/* --------------------------------------------------------------- настройки */

.settings { padding: 0; }
.setting { display: flex; align-items: flex-start; gap: 24px;
           padding: 16px 20px; border-top: 1px solid var(--line-soft); }
.setting:first-child { border-top: none; }
.setting-text { flex: 1; min-width: 0; }
.setting-title { font-size: 14.5px; display: flex; align-items: center; gap: 10px;
                 flex-wrap: wrap; margin-bottom: 4px; }
.setting-control { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.setting-control .unit { font-family: var(--mono); font-size: 10.5px;
                         color: var(--ink-dim); width: 54px; }
.sticky-save { position: sticky; bottom: 0; background: linear-gradient(to top,
               var(--bg) 55%, var(--bg-fade)); padding: 18px 0 22px; z-index: 30; }
/* Место под липкой кнопкой: без него последняя строка настроек навсегда
   остаётся под ней и её нельзя ни прочитать, ни нажать. */
.settings + .sticky-save, section:last-of-type .settings { margin-bottom: 0; }
form .settings:last-child { margin-bottom: 12px; }

/* -------------------------------------------------------------------- вход */

.login-page { min-height: 100vh; display: flex; align-items: center;
              justify-content: center; padding: 40px 20px; }
.login-card { width: 100%; max-width: 380px; }
.login-foot { margin-top: 18px; text-align: center; font-family: var(--mono);
              font-size: 10.5px; letter-spacing: .1em; color: var(--ink-dim); }

/* ------------------------------------------------------------------ движение
   Появление — короткое и один раз. Оно отвечает на вопрос «страница живая или
   зависла», и на этом его работа кончается: бесконечное движение на экране, за
   которым сидят по часу, утомляет быстрее, чем помогает. */

@keyframes rise { from { opacity: 0; transform: translateY(9px); } }
.rise { animation: rise .5s var(--ease) both; }
.i0 { animation-delay: .02s; } .i1 { animation-delay: .06s; }
.i2 { animation-delay: .10s; } .i3 { animation-delay: .14s; }
.i4 { animation-delay: .18s; } .i5 { animation-delay: .22s; }
.i6 { animation-delay: .26s; } .i7 { animation-delay: .30s; }
.i8 { animation-delay: .34s; }

@keyframes wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
.wipe { animation: wipe .6s var(--ease) both; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ------------------------------------------------------------------ узкий
   На телефоне таблица из шести колонок нечитаема в принципе. Здесь она
   превращается в карточки: заголовки колонок подставляются подписями. */

@media (max-width: 1180px) {
  .two-col { grid-template-columns: 1fr; }
  .col-side { position: static; }
  .grid.four { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
  .shell { padding: 0 18px 60px; }
  .grid.two { grid-template-columns: 1fr; }
  .edit-grid { grid-template-columns: 1fr; }
  .cal-cell { min-height: 84px; font-size: 11px; }
  .cal-item { font-size: 10.5px; }
}

@media (max-width: 760px) {
  .grid.four { grid-template-columns: 1fr 1fr; }
  .num { font-size: 34px; }
  .top { flex-wrap: wrap; gap: 10px; }
  .me .meta { display: none; }
  table.rows thead { display: none; }
  table.rows, table.rows tbody, table.rows tr, table.rows td { display: block; width: 100%; }
  table.rows tr { border-top: 1px solid var(--line-soft); padding: 12px 0 12px 12px;
                  position: relative; }
  table.rows td { border: none; padding: 3px 0; }
  /* Подписи колонок, которые на широком экране стоят в шапке. Без них
     карточка на телефоне — столбик без пояснений, где две даты подряд и
     непонятно, какая из них срок. */
  table.rows td[data-label]::before {
    content: attr(data-label) ': ';
    font-family: var(--mono); font-size: 10px; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-dim);
  }
  table.rows td[data-label] { display: flex; gap: 8px; align-items: baseline; }
  /* Метка задачи («Чуприков-2») — ПЕРВОЙ строкой карточки, в общем потоке.
     Раньше стояла `position: absolute; right: 0` в расчёте на короткий номер
     вроде «47». С переходом на «Фамилия-N» ширина 46px перестала действовать
     (её перебивает `width: 100%` строкой выше), коробка растянулась на всю
     карточку и легла ПОВЕРХ названия задачи: на телефоне из-под заголовка
     торчали обрубленные буквы фамилии. */
  table.rows td.n { position: static; width: auto; padding: 0 0 4px; }
  /* Полоска состояния — на всю высоту карточки и на самой строке, а не на
     первой ячейке. На первой ячейке она получала высоту в одну строку минус
     24px отступов, то есть отрицательную, и не рисовалась вовсе: на телефоне
     состояние задачи не показывалось ничем. */
  table.rows tr[data-href] td:first-child::before { display: none; }
  table.rows tr[data-href]::before {
    content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 2px;
    background: transparent;
  }
  table.rows tr.late::before { background: var(--late); }
  table.rows tr.soon::before { background: var(--soon); }
  table.rows tr.wait::before { background: var(--wait); }
  table.rows tr.done::before { background: var(--done); }
  .cal-week { grid-template-columns: 1fr; }
  .cal-cell { min-height: 0; border-left: none; }
  .cal-cell.empty-day { display: none; }
  .setting { flex-direction: column; gap: 10px; }
}


/* ---------------------------------------------------------------- файлы
   Список вложений и форма загрузки на странице задачи. Файл, копию которого
   ещё не забрали или забрать нельзя, показан приглушённым и С ОБЪЯСНЕНИЕМ:
   ссылка, которая ничего не открывает, читается как поломка экрана. */
.files .count {
  font-family: var(--mono); font-size: 11px; color: var(--ink-mid);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 0 5px; margin-left: 6px;
}
.filelist { list-style: none; margin: 10px 0 0; padding: 0; }
.filelist li {
  padding: 8px 0; border-bottom: 1px solid var(--line-soft);
}
.filelist li:last-child { border-bottom: 0; }
.filelist a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--line); }
.filelist a:hover { border-bottom-color: var(--ink-mid); }
.filelist .dim { color: var(--ink-dim); }
.upload { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.upload input[type="file"] {
  width: 100%; font-family: var(--mono); font-size: 12px; color: var(--ink-mid);
  background: var(--panel-up); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 8px;
}
.upload input[type="file"]::file-selector-button {
  font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  color: var(--ink); background: var(--panel-hi); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 5px 10px; margin-right: 10px;
  cursor: pointer;
}
.upload input[type="file"]:hover::file-selector-button { border-color: var(--ink-dim); }
/* Недоставленный файл. Красным — потому что это требует действия: сходить к
   человеку и попросить открыть бота. */
.meta.bad { color: var(--late); }

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

   Мера цели нажатия — 44 пикселя. Это не круглое число из воздуха: столько
   занимает подушечка пальца, и всё, что меньше, человек нажимает со второго
   раза. Экран открывают на ходу, одной рукой. */

@media (max-width: 760px) {
  /* Подпись раздела («срок сегодня, завтра или уже прошёл») прижималась
     вправо `margin-left: auto` — на широком экране это правильно, а на
     телефоне подпись вставала в правый край впритык, без единого пикселя
     воздуха, и читалась как уехавшая за границу экрана. Под заголовком
     слева она просто читается. */
  .sec-head { display: block; }
  .sec-head .meta { display: block; margin-left: 0; margin-top: 5px; }
  .sec-head h1, .sec-head h2 { margin-bottom: 0; }

  /* Цели нажатия. Ширину не трогаем там, где элемент и так во всю строку. */
  .btn { min-height: 44px; }
  .btn.small { min-height: 44px; padding: 11px 14px; }
  .theme-btn { min-width: 44px; }
  .tabs a { display: flex; align-items: center; min-height: 44px;
            padding: 11px 13px; }
  .tabs a::after { left: 13px; right: 13px; }
  .mark { min-height: 44px; align-items: center; }
  /* От «меня» на телефоне остаётся один кружок с инициалами — 28 пикселей
     поперёк. Ведёт он на смену пароля, промахиваться по нему обидно. */
  .me { min-height: 44px; min-width: 44px; justify-content: center; }

  /* Шапка липкая, поэтому её высота — это отнятый у содержания экран.
     Подросшие до 44 пикселей цели и добавленный переключатель разложили её
     на телефоне в ТРИ ряда: 191 пиксель, почти четверть экрана, которая едет
     за человеком при прокрутке. Порядок ниже собирает её обратно в два ряда —
     сверху кто смотрит и выход, снизу действие, тема и часы, — не убирая с
     экрана ни одного элемента и не уменьшая ни одной цели. */
  .top { padding: 12px 0 10px; gap: 8px; }
  .top .me   { order: 1; }
  .top .out  { order: 2; }
  .top .btn:not(.theme-btn) { order: 3; }
  .top .theme-btn { order: 4; }
  .top [data-clock] { order: 5; }
  /* Разрядка подписи убавлена ровно настолько, чтобы «СНТР ЭКРАН
     РУКОВОДИТЕЛЯ» и выход встали в один ряд. Слова не тронуты. */
  .mark span { letter-spacing: .18em; }
  /* «выйти» — 37×17 до правки: самая мелкая цель в шапке и при этом
     единственная необратимая. */
  .out { display: inline-flex; align-items: center; min-height: 44px;
         padding: 0 4px; }
  /* Название задачи. В списках строка кликается целиком и промах по ссылке
     всё равно ведёт куда надо, но в «Бот напомнит» строка НЕ кликается —
     там эта ссылка единственная цель, и в одну строку она была 30 пикселей. */
  td.title a { display: block; min-height: 44px; padding: 8px 0; }
  .filelist a { display: inline-block; padding: 6px 0; }
  details.panel > summary { min-height: 44px; padding: 14px 18px; }
  /* Человек в списке: кружок с фамилией — 31 пиксель в высоту. */
  a.who { min-height: 44px; align-items: center; }
  .back { display: inline-flex; align-items: center; min-height: 44px; }
  .cal-item { min-height: 44px; padding: 10px 8px; }
  /* Выключатель настройки. Сама пилюля остаётся 42×22 — она узнаваемая, и
     трогать её вид незачем. Растягивается ПРОЗРАЧНАЯ галочка поверх неё:
     палец попадает в 44 пикселя, глаз видит прежний переключатель. */
  .switch input { top: -11px; height: 44px; left: -2px; width: 46px; }
  /* Ближайшая задача человека в списке людей — 21 пиксель в высоту. */
  a.work { min-height: 44px; padding: 11px 0 11px 8px; }

  /* Поля ввода — ровно 16px. Меньший размер iOS считает «мелким» и при
     касании увеличивает всю страницу; обратно она сама не отматывается, и
     человек остаётся на увеличенном экране до перезагрузки. */
  input[type=text], input[type=password], input[type=number], input[type=date],
  input[type=search], input[type=email], textarea, select {
    font-size: 16px; min-height: 44px;
  }
  textarea { min-height: 88px; }
  /* Поля стали крупнее — значит, подсказка внутри них стала длиннее в
     пикселях. Отступы по бокам ужимаются, чтобы вернуть эти пиксели тексту:
     у поля срока подсказка — единственное указание формата, и обрезанное
     «01.09.2026 18:0» не просто некрасиво, а показывает НЕВЕРНЫЙ формат. */
  input[type=text], input[type=password], input[type=number], input[type=date],
  input[type=search], input[type=email] { padding-left: 9px; padding-right: 9px; }
  .panel.side { padding-left: 14px; padding-right: 14px; }
  .upload input[type="file"] { font-size: 16px; }
  .pick.narrow { width: 100%; min-width: 0; text-align: left; }
  /* Выпадающий список берёт ширину по самому длинному пункту. В настройках
     это «только напоминания и известия о правках с экрана» — 327 пикселей
     при 302 доступных, и вся страница уезжала вбок горизонтальной прокруткой.
     `min-width: 0` обязателен: без него `min-width: 150px` у `.pick` не даёт
     сжаться, и `max-width` ничего не решает. */
  .setting-control { min-width: 0; max-width: 100%; align-self: stretch; }
  .setting-control .pick, .setting-control select,
  .filters .pick, .filters select { min-width: 0; max-width: 100%; }

  /* Галочка с длинной подписью. `.panel.side input { width: 100% }` в боковой
     колонке попадал и в саму галочку: она раздувалась во всю строку, отнимала
     место у текста, и подпись «снять срок — задача уйдёт из календаря и из
     просрочки» ломалась в узкий столбик, разъезжаясь с квадратиком. */
  .check { display: flex; align-items: flex-start; gap: 10px;
           min-height: 44px; padding: 6px 0; }
  .check input[type=checkbox],
  .panel.side .check input[type=checkbox] {
    flex: 0 0 20px; width: 20px; height: 20px; margin: 1px 0 0;
  }

  /* Айфоны с вырезом. Липкая шапка и липкая кнопка «сохранить» иначе уезжают
     под скруглённый угол и под полосу жеста. */
  .shell { padding-left: max(18px, env(safe-area-inset-left));
           padding-right: max(18px, env(safe-area-inset-right)); }
  .sticky-save { padding-bottom: max(22px, env(safe-area-inset-bottom)); }
  .login-page { padding-left: max(20px, env(safe-area-inset-left));
                padding-right: max(20px, env(safe-area-inset-right)); }

  /* Календарь: неделя разложена в столбик по дням, и шапка с названиями
     дней при этом лишняя — семь подписей подряд перед семью же ячейками
     читаются как первая неделя месяца. День подписан внутри ячейки. */
  .cal-head { display: none; }
  .cal-item { white-space: normal; }
}
:is(.assistant-answer, .panel pre) {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-width: 100%;
}
.assistant-examples { margin: 10px 0 0; padding-left: 20px; color: var(--ink-dim); }
.assistant-examples li + li { margin-top: 5px; }
.assistant-recent { margin-top: 26px; }
.assistant-job { scroll-margin-top: 24px; }
.assistant-question { margin: 12px 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.assistant-coverage { line-height: 1.6; }
.assistant-result { margin-top: 10px; }
.assistant-result summary, .assistant-history summary, .compact-attach summary {
  cursor: pointer; color: var(--ink-dim); font-size: 13px;
}
.assistant-result pre { margin-top: 8px; }
.assistant-source-result { padding: 10px 0; border-top: 1px solid var(--line-soft); }
.assistant-source-result:first-of-type { margin-top: 8px; }
.corpus-coverage { margin: 0 2px 18px; }
.assistant-history { padding: 12px 16px; }
.assistant-history[open] > article:first-of-type { margin-top: 12px; }
.compact-attach { padding: 12px 16px; }
.compact-attach[open] > p { margin: 10px 0; }
.compact-attach form { align-items: end; }
.compact-attach input[type="file"] { max-width: 100%; }
