/* Внешний вид платформы.

   Перенесён из школьной платформы BEST вместе с каркасом: палитра,
   типографика (IBM Plex), шкалы отступов и скруглений. Имена состояний —
   done / wip / todo / na. Старые имена (ok, warn, bad, navy, ink) оставлены
   псевдонимами: на них опираются правила ниже.

   Тёмная тема появляется сама по системной настройке. Правила, которые
   нужны только школьным экранам, при переносе убраны; образцы всех
   оставшихся компонентов — на странице /design. */

@import url("fonts.css");

:root{
  color-scheme:light;
  --paper:#F2F2F5; --surface:#FFFFFF; --raised:#F7F7F9;
  --line:#E3E3E8; --line-soft:#ECECF0;
  --text:#1B1B1F; --muted:#6E6E73; --faint:#86868B;
  --accent:#1B3A6B; --accent-soft:#E7ECF5;
  --done:#16603F; --done-bg:#E6F2EC;
  --wip:#7A5B0F;  --wip-bg:#FFF4DA;
  --todo:#8C2F38; --todo-bg:#FFE8E9;
  --na:#86868B;   --na-bg:#EDEDF1;
  /* Тень вместо рамки. Карточка в рамке внутри страницы в рамке — это коробки
     в коробках, и именно это выдаёт возраст интерфейса. Приподнятую плоскость
     читает глаз, линию — чертёжник. */
  --shadow:0 1px 2px rgba(16,24,40,.04),0 1px 3px rgba(16,24,40,.06);

  /* Шесть ролей вместо семнадцати размеров. Семнадцать — это было не
     разнообразие, а отсутствие решения: в CSS стояли 12 и 12,5 рядом, и
     разницы не видел никто, кроме того, кто её выбирал. */
  --t-page:32px;      /* заголовок страницы */
  --t-section:17px;   /* заголовок раздела внутри карточки */
  --t-body:15px;      /* основной текст */
  --t-small:14px;     /* таблицы и плотные места */
  --t-caption:13px;   /* подписи и пояснения */
  --t-label:11px;     /* надписи прописными над блоком */

  /* Четыре скругления вместо девяти. */
  --r-field:6px; --r-control:10px; --r-card:12px; --r-round:999px;

  /* Шкала отступов. Шесть значений, и других быть не должно: пока их не
     было, в шаблонах завелись 6, 10, 12 и 14 пикселей вперемешку, и экраны
     разошлись на глаз. Правило к шкале одно и важнее самих чисел: блок не
     задаёт себе отступ сверху. Расстояние между блоками — дело родителя,
     иначе каждый второй стиль в разметке оказывается margin-top:0. */
  --s1:4px; --s2:6px; --s3:10px; --s4:14px; --s5:18px; --s6:22px;
  --s7:28px; --s8:40px;        /* поля страницы и расстояние между разделами */

  /* Меню USAT — тёмно-синее в обеих темах (решение 23.10.2026): так
     платформа вуза с первого взгляда не путается со школьной, у которой меню
     светлое. Цвета меню — отдельными токенами: когда будут утверждены цвета
     брендбука USAT, их меняют здесь, в одном месте. */
  --nav-bg:#13294B; --nav-text:#D3DCEA; --nav-bright:#FFFFFF; --nav-dim:#8C9DBA;
  --nav-logo:#F4C05B;                     /* логотип: Chaqmoq sariq из брендбука, жёлтый на синем */
  --nav-on:rgba(255,255,255,.09);         /* подсветка пункта под курсором и открытого */
  --nav-mark:#F2B544;                     /* полоса открытого пункта меню */
  --nav-line:rgba(255,255,255,.12);       /* разделители и рамки внутри меню */
  --nav-field:rgba(255,255,255,.07);      /* поле поиска в меню */
  --thumb:#C9C9CF; --thumb-on:#A8A8B2;    /* полоса прокрутки: в покое и под курсором */
  --nav-thumb:rgba(255,255,255,.28);      /* полоса прокрутки самого меню */
  --gold:#9C7B46;

  /* Псевдонимы прежних имён */
  --navy:var(--accent); --ink:var(--text); --bg:var(--paper); --card:var(--surface);
  --alt:var(--raised);
  --ok:var(--done); --okbg:var(--done-bg);
  --warn:var(--wip); --warnbg:var(--wip-bg);
  --bad:var(--todo); --badbg:var(--todo-bg);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --paper:#141416; --surface:#1C1C1F; --raised:#232327;
    --line:#2E2E33; --line-soft:#272729;
    --text:#F2F2F5; --muted:#9A9AA0; --faint:#86868B;
    --accent:#9FBDEE; --accent-soft:#1F2838;
    --done:#74CE9C; --done-bg:#163023;
    --wip:#E2B65E;  --wip-bg:#33280F;
    --todo:#EE8B94; --todo-bg:#361B1E;
    --na:#8C8C94;   --na-bg:#27272B;
    --shadow:0 1px 2px rgba(0,0,0,.5),0 1px 3px rgba(0,0,0,.35);
    --nav-bg:#0E1C33; --nav-text:#D3DCEA; --nav-bright:#FFFFFF;
    --nav-dim:#8392AD; --nav-on:rgba(255,255,255,.08);
    --thumb:#35353B; --thumb-on:#4A4A52;
  }
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:#141416; --surface:#1C1C1F; --raised:#232327;
  --line:#2E2E33; --line-soft:#272729;
  --text:#F2F2F5; --muted:#9A9AA0; --faint:#86868B;
  --accent:#9FBDEE; --accent-soft:#1F2838;
  --done:#74CE9C; --done-bg:#163023;
  --wip:#E2B65E;  --wip-bg:#33280F;
  --todo:#EE8B94; --todo-bg:#361B1E;
  --na:#8C8C94;   --na-bg:#27272B;
  --shadow:0 1px 2px rgba(0,0,0,.5),0 1px 3px rgba(0,0,0,.35);
  --nav-bg:#0E1C33; --nav-text:#D3DCEA; --nav-bright:#FFFFFF;
  --nav-dim:#8392AD; --nav-on:rgba(255,255,255,.08);
  --thumb:#35353B; --thumb-on:#4A4A52;
}
*{box-sizing:border-box}

/* --- полосы прокрутки ---------------------------------------------------
   Windows рисует их серыми, со стрелками и шириной в палец. В меню такая
   полоса становится второй вертикальной линией рядом с подписями разделов,
   и глаз цепляется за неё, а не за них.

   Совсем убрать нельзя: полоса — единственный признак того, что ниже есть
   ещё что-то. Поэтому она не исчезает, а гаснет: в покое тонкая и тихая,
   под курсором темнее. В меню — прозрачная, пока на меню не навели: там
   список короткий и знакомый, и подсказывать нечего.

   Два набора правил: scrollbar-* понимает Firefox, ::-webkit-scrollbar —
   Chrome и Edge, в которых платформу и открывают. */
*{scrollbar-width:thin;scrollbar-color:var(--thumb) transparent}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-corner{background:transparent}
/* Прозрачная рамка вокруг ползунка: она же отступ от края, из-за которого
   ползунок выглядит тоньше самой полосы и не упирается в содержимое. */
::-webkit-scrollbar-thumb{background:var(--thumb);border-radius:99px;
  border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:var(--thumb-on);background-clip:content-box}

nav{scrollbar-color:transparent transparent}
nav::-webkit-scrollbar-thumb{background:transparent}
/* Ползунок меню светлый: на тёмном поле обычный серый не виден, а
   появляется он ровно затем, чтобы его заметили. */
nav:hover{scrollbar-color:var(--nav-thumb) transparent}
nav:hover::-webkit-scrollbar-thumb{background:var(--nav-thumb);
  background-clip:content-box}

body{margin:0;background:var(--paper);color:var(--text);font-size:var(--t-body);
  line-height:1.55;font-variant-numeric:tabular-nums;
  font-family:"IBM Plex Sans",-apple-system,"Segoe UI",Roboto,sans-serif}
.mono{font-family:"IBM Plex Mono",ui-monospace,Consolas,monospace;font-variant-numeric:tabular-nums}
a{color:var(--navy)}
/* Заголовок строит страницу весом и плотностью, а не линейкой под собой.
   Засечной остаётся: так заголовок страницы отличается от заголовков
   внутри карточек с первого взгляда. */
h1{font-family:"IBM Plex Serif",Georgia,serif;font-weight:600;
  font-size:clamp(24px,3vw,var(--t-page));line-height:1.12;letter-spacing:-.015em;
  margin:0 0 var(--s2);color:var(--text)}
h2{font-size:var(--t-section);margin:0 0 var(--s3);color:var(--text);font-weight:600}
h3{font-size:var(--t-label);margin:0 0 var(--s2);color:var(--muted);font-weight:600;
  letter-spacing:.14em;text-transform:uppercase}
a{color:var(--accent)}
.layout{display:flex;min-height:100vh}
/* Меню — тёмная колонка на всю высоту, страница — светлая: граница между
   «где я» и «что делаю» видна без линий. */
nav{width:248px;flex:0 0 240px;background:var(--nav-bg);color:var(--nav-text);
  padding:var(--s7) 12px;position:sticky;top:0;height:100vh;
  display:flex;flex-direction:column;overflow-y:auto}
/* Логотип вуза из брендбука: горизонтальная подпись, жёлтая на синем меню.
   Брендбук: на экране не уже 160 px, вокруг — свободное поле. */
nav .brand{padding:var(--s1) 12px var(--s6)}
nav .brand .logo{display:block;width:100%;max-width:200px;min-width:160px;height:auto;
  color:var(--nav-logo)}
nav a{display:block;color:var(--nav-text);text-decoration:none;font-size:var(--t-small)}
nav .who{margin-top:auto;padding:var(--s4) 12px 0;font-size:var(--t-caption);
  color:var(--nav-dim);border-top:1px solid var(--nav-line)}
nav .who b{display:block;color:var(--nav-bright);font-weight:500;font-size:var(--t-small)}
/* «Выйти» в меню — тихая кнопка по цвету меню, а не белая плашка. */
nav .btn.plain{background:transparent;color:var(--nav-text);border-color:var(--nav-line)}
nav .btn.plain:hover{background:var(--nav-on);color:var(--nav-bright)}
/* min-width:0 обязателен: без него широкая таблица растягивает колонку
   и вся страница уезжает вбок вместе с меню. */
main{flex:1;min-width:0;padding:var(--s8) 44px;max-width:1560px}
.card{background:var(--surface);border-radius:var(--r-card);padding:var(--s7) 26px;
  margin-bottom:var(--s4);overflow:auto;box-shadow:var(--shadow)}
/* Первый и последний внутри карточки не прибавляют своих полей к её padding.
   Без этого каждый заголовок и каждая подпись в начале карточки получали в
   разметке свой style="margin-top:0" — таких было двадцать три. */
.card > :first-child{margin-top:0}
.card > :last-child{margin-bottom:0}
/* Сводка — одна коробка с перегородками, как .summary: это один ответ на
   один вопрос, и читать его надо слева направо. Рамка вокруг каждой цифры
   превращала шапку в сетку ячеек, а цифры совсем без рамки висели над
   страницей и не читались как одно целое. */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:0;
  border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--surface);
  box-shadow:var(--shadow);margin-bottom:var(--s6)}
.tiles .tile{padding:14px 18px;border-right:1px solid var(--line-soft);min-width:0}
.tiles .tile:last-child{border-right:0}
a.tile{text-decoration:none;color:inherit}
a.tile:hover{background:var(--raised)}
.tile{min-width:120px}
.tile .n{font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums;
  font-size:28px;font-weight:500;color:var(--text);line-height:1.1}
.tile.done .n{color:var(--done)} .tile.wip .n{color:var(--wip)} .tile.todo .n{color:var(--todo)}
.tile .l{font-size:var(--t-caption);color:var(--muted);margin-top:var(--s1)}
table{border-collapse:collapse;width:100%;font-size:var(--t-small)}
/* Шапка — подпись к колонке, а не заголовок: без заливки, без прописных, без
   жира. Тёмная полоса во всю ширину перетягивала внимание с самих строк, ради
   которых таблицу и открывают, а прописные читаются медленнее строчных. */
th{background:none;color:var(--muted);text-align:left;padding:var(--s3) var(--s3);
  font-weight:500;font-size:var(--t-caption);
  border-bottom:1px solid var(--line-soft)}
td{border-bottom:1px solid var(--line-soft);padding:var(--s3);vertical-align:top}
tr:last-child td{border-bottom:0}
tbody tr:hover td{background:var(--raised)}

.pill{display:inline-block;padding:3px 10px;border-radius:var(--r-round);
  font-size:var(--t-caption);font-weight:500;line-height:1.35;
  background:var(--na-bg);color:var(--na)}  /* ярлык без цвета всё равно выглядит ярлыком */
.ok{background:var(--okbg);color:var(--ok)} .warn{background:var(--warnbg);color:var(--warn)}
.bad{background:var(--badbg);color:var(--bad)}
.muted{color:var(--muted)} .small{font-size:var(--t-caption)}
.row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;margin-bottom:12px}
label{display:block;font-size:var(--t-caption);color:var(--muted);margin:0 0 var(--s1)}
input,select,textarea{font:inherit;font-size:var(--t-small);padding:7px var(--s3);
  border:1px solid var(--line);border-radius:var(--r-field);
  background:var(--surface);color:var(--text)}

button{font:inherit;cursor:pointer}
/* Видимый фокус. Формы заполняют с клавиатуры, и без этого человек не знает,
   в каком он поле. :focus-visible — чтобы рамка не вспыхивала от мыши. */
:where(a,button,summary,input,select,textarea):focus-visible{
  outline:2px solid var(--navy);outline-offset:2px}
nav :where(a,button,summary,input):focus-visible{outline-color:var(--nav-mark)}
/* Надпись на кнопке — цветом поверхности, а не белым: в тёмной теме акцент
   светлеет, и белым по нему уже не прочитать. var(--surface) белый в светлой
   теме и почти чёрный в тёмной, то есть всегда противоположен заливке. */
.btn{background:var(--accent);color:var(--surface);border:0;border-radius:var(--r-control);
  padding:8px var(--s4);font-weight:600;font-size:var(--t-small);
  display:inline-block;text-decoration:none;line-height:1.45}
/* Одно правило на все кнопки: тёмно-синяя — действие формы, белая —
   второстепенное. Золотой остаётся цветом выделения в меню, не кнопкой. */
.btn.plain{background:var(--surface);color:var(--text);border:1px solid var(--line)}
label.btn{cursor:pointer}

/* Вкладки — один переключатель, а не ряд кнопок: по серой дорожке сразу
   видно, что это выбор одного из нескольких, а не несколько действий. */
.tabs{display:flex;gap:2px;margin-bottom:var(--s6);flex-wrap:wrap;align-items:center;
  background:var(--line);padding:2px;border-radius:var(--r-control);width:max-content;
  max-width:100%}
.tabs a{background:none;border-radius:8px;padding:6px var(--s4);text-decoration:none;
  color:var(--muted);font-size:var(--t-small);
  transition:background-color .16s ease,color .16s ease}
.tabs a:hover{color:var(--text)}
.tabs a.on{background:var(--surface);color:var(--text);font-weight:600;
  box-shadow:0 1px 2px rgba(16,24,40,.06)}
/* Две полосы вкладок подряд — «кого» и «за какие дни». Щель между ними
   меньше, чем под последней: иначе они читаются как два разных экрана, а не
   как два вопроса об одном. */
.tabs + .tabs{margin-top:calc(var(--s3) - var(--s6))}

/* Отключённая или неактуальная строка. Приглушена, но не спрятана:
   её читают последней, а ищут первой. */
tr.off td{color:var(--muted)}
.note{background:var(--wip-bg);color:var(--wip);padding:var(--s4) var(--s5);
  border-radius:var(--r-card);margin-bottom:var(--s4);font-size:var(--t-small)}
.err{background:var(--badbg);color:var(--bad);padding:var(--s4) var(--s5);
  border-radius:var(--r-card);margin:var(--s3) 0;font-size:var(--t-small)}

.login{max-width:330px;margin:12vh auto}
.login input{width:100%;margin-bottom:10px}
.htmx-request{opacity:.6}
@media (max-width:820px){
  .layout{flex-direction:column} nav{width:100%;height:auto;position:static;flex-direction:row;flex-wrap:wrap}
  nav .brand,nav .who{width:100%} main{padding:16px}
}

/* --- боковое меню ------------------------------------------------------- */
/* Боковое меню: разделы раскрываются через details/summary — без JavaScript,
   работает с клавиатуры и переживает выключенные скрипты. */
/* Подпись раздела: мелкая, прописными, приглушённая, не нажимается. Четыре
   таких подписи читаются одним взглядом, а внимание остаётся на пунктах,
   по которым ходят каждый день. */
/* Подпись раздела — строчными и без разрядки: прописные читаются медленнее,
   а здесь их читают каждый раз, когда ищут глазами нужный пункт. */
nav .cap{margin:var(--s5) 0 var(--s1);padding:0 12px;font-size:var(--t-caption);
  font-weight:600;color:var(--nav-dim)}
nav .cap:first-of-type{margin-top:var(--s2)}

/* Пункт — скруглённая плашка с отступом от края, а не строка во всю ширину:
   так видно, что это отдельная кнопка, и подсветка не упирается в край
   экрана. Переходы плавные: резкая вспышка под курсором дёргает глаз. */
nav a.item,nav .grp>summary{display:flex;align-items:center;gap:var(--s3);
  margin:1px 0;padding:7px 12px;border-radius:var(--r-control);
  color:var(--nav-text);font-size:var(--t-small);
  cursor:pointer;user-select:none;list-style:none;
  transition:background-color .16s ease,color .16s ease}
nav .grp>summary::-webkit-details-marker{display:none}
nav a.item:hover,nav .grp>summary:hover{background:var(--nav-on);color:var(--nav-bright)}
/* Открытый пункт — плотнее фон, жирнее шрифт и полоса цвета знака слева:
   на тёмном поле одной заливки мало, её легко принять за наведение. */
nav a.item.on{background:var(--nav-on);color:var(--nav-bright);font-weight:600;
  box-shadow:inset 3px 0 0 var(--nav-mark)}
nav a.item.on .ico{color:var(--nav-mark)}
nav .ico{flex:0 0 17px;width:17px;height:17px;opacity:.8;
  transition:opacity .16s ease}
nav a.item:hover .ico,nav .grp>summary:hover .ico,nav a.item.on .ico{opacity:1}
/* inline-block обязателен: transform не действует на строчные элементы,
   и стрелка не повернётся при раскрытии. */
nav .grp>summary::after{content:"›";margin-left:auto;display:inline-block;
  font-size:var(--t-body);line-height:1;opacity:.55;transition:transform .16s ease}
nav .grp[open]>summary::after{transform:rotate(90deg)}
/* Вложенные страницы: без значков — столбец из десяти значков превращается
   в рябь, по которой ничего не найти. */
nav .grp>a{margin:1px 0 1px 30px;padding:6px 12px;border-radius:var(--r-control);
  font-size:var(--t-small);color:var(--nav-dim);
  transition:background-color .16s ease,color .16s ease}
nav .grp>a:hover{background:var(--nav-on);color:var(--nav-bright)}
nav .grp>a.on{background:var(--nav-on);color:var(--nav-bright);font-weight:600;
  box-shadow:inset 3px 0 0 var(--nav-mark)}
nav .grp[open]{padding-bottom:4px}

/* Карточка «подпись — значение». Подписи здесь в th, но это НЕ заголовок
   таблицы: тёмную заливку общего правила th нужно снять, иначе подпись
   становится светло-серой на тёмно-синем и не читается. */
/* Одинаковая ширина у всех блоков карточки: иначе они смотрятся рвано. */
table.kv{margin:0 0 20px;width:100%;max-width:680px}
/* Подписи здесь в th, но это подписи, а не шапка таблицы: общее правило th
   делает их прописными и разреженными, и карточка начинает кричать. */
table.kv th{background:none;color:var(--muted);font-weight:400;text-align:left;
  width:210px;padding:7px 18px 7px 0;vertical-align:top;
  font-size:var(--t-small);letter-spacing:0;text-transform:none;
  border-bottom:1px solid var(--line-soft)}
table.kv td{padding:7px 0;border-bottom:1px solid var(--line);color:var(--ink)}
table.kv tr:last-child th,table.kv tr:last-child td{border-bottom:0}
table.kv tr:nth-child(even) td,table.kv tr:nth-child(even) th{background:none}

/* Колонок больше, чем ширины экрана: прокручивается таблица, а не вся
   страница вместе с меню. */
.scroll-x{overflow-x:auto}

/* Длинный текст не должен тянуться на весь экран — читать неудобно. */
.prose{max-width:680px}

/* Плитки: длинная подпись должна переноситься, а не уезжать за край */
.tile .l{white-space:normal;word-break:normal}

tfoot td{border-top:2px solid var(--line);font-weight:600;border-bottom:0}

/* Поле, которое не прошло маску: рамка и строка с причиной под ним. Класс свой,
   не .err — та уже занята крупной плашкой на странице входа и на странице ошибки.
   Пустое поле ошибкой не считается: карточку заполняют постепенно. */
input.bad,select.bad{border-color:var(--bad);background:var(--badbg)}
.fld-err{display:block;margin-top:4px;font-size:var(--t-caption);color:var(--bad);max-width:240px}
.fld-hint{display:block;margin-top:4px;font-size:var(--t-label);color:var(--muted);max-width:240px}
input::placeholder{color:var(--muted);opacity:.6}

/* --- формы ввода ------------------------------------------------------- */
/* Форма читается одной колонкой. Раньше поля раскладывались flex-wrap на всю
   ширину окна: на большом мониторе строка уезжала на полтора метра, а порядок
   полей менялся вместе с шириной — паспорт и ПИНФЛ могли оказаться в разных
   строках. Теперь это сетка из 12 долей с фиксированными пролётами, и пары
   полей стоят рядом всегда. */
form.card{max-width:940px}
.fields{display:grid;grid-template-columns:repeat(12,1fr);gap:14px 10px;
  align-items:start;margin-bottom:18px;max-width:940px}
.fld{min-width:0;display:flex;flex-direction:column}
.fld.w-xs{grid-column:span 2}
.fld.w-s{grid-column:span 3}
.fld.w-m{grid-column:span 4}
.fld.w-l{grid-column:span 6}
.fld.w-xl{grid-column:span 12}
.fld input:not([type=checkbox]),.fld select,.fld textarea{width:100%;box-sizing:border-box}

/* Подпись в одну строку: иначе двухстрочная подпись опускает своё поле, и ряд
   разъезжается по высоте. Полный текст остаётся во всплывающей подсказке. */
.fld>label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Пустое поле приглушено, заполненное — белое и чёткое: когда полей двадцать,
   иначе не видно, что уже сделано. Работает без JavaScript: у всех полей есть
   placeholder, поэтому :placeholder-shown = поле пустое. */
.fld input:placeholder-shown,.fld textarea:placeholder-shown{background:var(--raised)}
.fld select:has(option[value=""]:checked){background:var(--raised);color:var(--muted)}
::placeholder{color:var(--muted);opacity:.6;font-style:italic}   /* пример, а не значение */

/* Обязательное поле видно до отправки, а не после отказа */
.req{color:var(--bad);margin-left:2px}

/* Галочка: подпись справа от квадратика и переносится — обрезать её нельзя.
   Отступ сверху ставит её на линию соседних полей, у которых есть подпись. */
.fld.check{padding-top:19px}
label.check{display:flex;align-items:flex-start;gap:7px;white-space:normal;
  color:var(--ink);font-size:var(--t-caption);cursor:pointer;line-height:1.3}
label.check input[type=checkbox]{margin:1px 0 0}

/* На узком экране сетка складывается: сначала по два поля в ряд, на телефоне —
   по одному. Иначе «Телефон» превращается в поле шириной в четыре символа. */
@media (max-width:760px){
  .fld.w-xs,.fld.w-s{grid-column:span 6}
  .fld.w-m,.fld.w-l{grid-column:span 12}
}
@media (max-width:520px){
  .fld.w-xs,.fld.w-s,.fld.w-m,.fld.w-l{grid-column:span 12}
}

/* Отбор ярлыками со счётчиками: один список, а не несколько — искать по
   нескольким спискам заставляло бы смотреть во все. */
.chips{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 12px}
.chip{font-size:var(--t-caption);padding:5px 12px;border-radius:99px;text-decoration:none;
  border:1px solid var(--line);background:var(--surface);color:var(--muted)}
.chip b{font-weight:600;margin-left:5px;font-variant-numeric:tabular-nums}
.chip.on{background:var(--accent-soft);border-color:transparent;color:var(--accent);font-weight:600}

/* Форма, которую открывают по надобности. Страница — это прежде всего то,
   что уже сделано; форма нужна изредка. Раскрытая пустая форма во весь
   экран сразу после отправки выглядит так, будто отправить не получилось. */
details.fold{padding:0}
details.fold>summary{list-style:none;cursor:pointer;padding:14px 18px;
  font-weight:600;display:flex;align-items:center;gap:9px}
details.fold>summary::-webkit-details-marker{display:none}
details.fold>summary::before{content:"+";font:600 17px/1 var(--mono, monospace);
  color:var(--accent);width:14px;text-align:center}
details.fold[open]>summary::before{content:"–"}
details.fold>summary:hover{color:var(--accent)}
details.fold[open]>summary{border-bottom:1px solid var(--line-soft)}
details.fold>form{padding:16px 18px 18px}

/* Печать: лист остаётся, всё остальное уходит. */
@media print{
  nav, .note{display:none !important}
  main{padding:0;max-width:none}
}

/* Переключатель языка в меню. Две кнопки по три знака: занимает одну строку
   и не притворяется разделом. */
nav .lang{display:flex;gap:4px;margin-top:8px}
nav .lang button{font:inherit;font-size:var(--t-label);font-weight:600;letter-spacing:.04em;
  padding:4px 10px;border-radius:var(--r-field);border:0;
  background:transparent;color:var(--nav-dim);
  transition:background-color .16s ease,color .16s ease}
nav .lang button:hover{color:var(--nav-bright);background:var(--nav-on)}
nav .lang button.on{background:var(--nav-on);color:var(--nav-bright)}

/* Образцы цвета на странице «Как собраны экраны». Класс на каждый токен, а не
   style="background:var(--…)" в разметке: страница, которая учит не держать
   цвета в шаблонах, сама этого делать не может. */
.swatch{height:22px;border-radius:5px;border:1px solid var(--line)}
.sw-paper{background:var(--paper)} .sw-surface{background:var(--surface)}
.sw-text{background:var(--text)}   .sw-muted{background:var(--muted)}
.sw-accent{background:var(--accent)}
.sw-done{background:var(--done)}   .sw-wip{background:var(--wip)}
.sw-todo{background:var(--todo)}   .sw-na{background:var(--na)}
.sw-gold{background:var(--gold)}

/* Поиск по платформе. В меню — одно поле со значком внутри: рамка вокруг
   значка и поля читается как одна вещь, а отдельная кнопка «Найти» рядом
   заняла бы половину столбца ради нажатия, которое делает Enter. */
.find{position:relative;margin:0 0 var(--s5);padding:0 12px}
.find .ico{position:absolute;left:21px;top:50%;transform:translateY(-50%);
  width:15px;height:15px;color:var(--nav-dim);pointer-events:none}
/* Рамка у поля есть всегда, а не появляется при наведении: в тёмной теме
   меню и поверхность поля одного цвета, и без рамки поле пропадает —
   остаются значок и текст, висящие в пустоте. */
.find input{width:100%;background:var(--nav-field);color:var(--nav-bright);
  border:1px solid var(--nav-line);border-radius:var(--r-control);
  padding:7px var(--s3) 7px 31px;font-size:var(--t-caption);
  transition:border-color .16s ease}
.find input:hover{border-color:var(--nav-dim)}
.find input::placeholder{color:var(--nav-dim)}
.find input::-webkit-search-cancel-button{opacity:.5}
/* Поле на самой странице поиска — то же, но в полную ширину и с кнопкой:
   сюда приходят по ссылке, и запрос здесь правят, а не набирают заново. */
.findbig{display:flex;gap:var(--s3);margin:0 0 var(--s6);max-width:620px}
.findbig input{flex:1;min-width:0;font-size:var(--t-body);padding:9px var(--s4)}
/* Находки — список, а не таблица: у строк разная длина и один общий смысл
   «вот это, откройте». Таблица из одного столбца обещает столбцы, которых нет. */
.hits{list-style:none;margin:0;padding:0}
.hits li{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s3);
  padding:var(--s3) 0;box-shadow:inset 0 -1px 0 var(--line-soft)}
.hits li:last-child{box-shadow:none}
.hits li>a{font-weight:500;text-decoration:none}
.hits li>a:hover{text-decoration:underline}
.hits .pill{margin-left:auto}

/* Галочка. Браузер рисует её цветом операционной системы — на макбуке это
   ярко-синий, единственное кричащее пятно на экране, который весь построен
   на том, что ничего не кричит. А в таблице выгрузки таких пятен сразу
   двадцать, и глаз идёт по ним, а не по строкам.

   Рисуем сами. Квадратик того же размера, что поле ввода по высоте строки,
   с тем же скруглением; отмеченный заливается акцентом, галочка внутри —
   цветом поверхности, то есть белая в светлой теме и почти чёрная в
   тёмной. Форма галочки — многоугольник в clip-path: картинка в данных
   не умеет менять цвет вместе с темой, а свой шрифт значков платформа не
   держит.

   appearance:none снимает и системную отрисовку, и поведение — поэтому
   ниже восстановлено всё, что оно уносит: размер, курсор, видимый фокус
   (он общий, строкой выше по файлу) и состояние «выключено». В режиме
   высокой контрастности Windows возвращаем системную галочку: там цвета
   назначает не сайт. */
input[type=checkbox]{appearance:none;-webkit-appearance:none;
  flex:none;width:17px;height:17px;margin:0;padding:0;vertical-align:-3px;
  border:1.5px solid var(--line);border-radius:var(--r-field);
  background:var(--surface);cursor:pointer;
  display:inline-grid;place-content:center;
  transition:background-color .14s ease,border-color .14s ease}
input[type=checkbox]::before{content:"";width:10px;height:10px;
  background:var(--surface);transform:scale(0);transition:transform .14s ease;
  clip-path:polygon(14% 44%,0 60%,39% 100%,100% 18%,85% 3%,39% 70%)}
input[type=checkbox]:hover:not(:disabled){border-color:var(--muted)}
/* «Выключено» идёт до «отмечено»: иначе серая заливка съела бы акцент
   у отмеченной и выключенной разом — а это два разных сообщения. */
input[type=checkbox]:disabled{cursor:default;opacity:.55;background:var(--raised)}
input[type=checkbox]:checked{background:var(--accent);border-color:var(--accent)}
input[type=checkbox]:checked::before{transform:scale(1)}
/* Галочка в ячейке таблицы — с полем вокруг: по квадратику 17 пикселей
   попадают не все. */
td>input[type=checkbox]{margin:2px}
@media (forced-colors: active){
  input[type=checkbox]{appearance:auto}
  input[type=checkbox]::before{display:none} }

/* Пустой экран. Не серая строчка в углу, а объяснение: что это за место,
   почему оно пусто и что здесь делают. Ширину держим в 560 пикселей —
   объяснение в три строки на всю ширину таблицы не читается. */
.empty{padding:var(--s7) 0;max-width:560px}
.empty .what{margin:0 0 var(--s2);font-weight:500;color:var(--text)}
.empty .why{margin:0;color:var(--muted);font-size:var(--t-caption);line-height:1.5}
.empty .go{margin:var(--s5) 0 0}
/* Внутри формы и внутри ячейки объяснения хватает строкой: большой блок
   разрывает форму пополам. */
.empty.tight,td>.empty{padding:var(--s3) 0}
.empty.tight .what{font-weight:400;color:var(--muted)}

/* Применённые отборы. Отвечают на вопрос, который человек задаёт себе,
   глядя на короткий список: «почему так мало — я что-то выбрал или столько
   и есть?» Каждое условие снимается само по себе: сняв «нет», человек
   должен остаться в блокирующих, а не вывалиться в полный реестр. */
.picked{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s3);align-items:center;
  margin:0 0 var(--s4)}
.picked>a{display:inline-flex;align-items:center;gap:var(--s2);
  background:var(--accent-soft);color:var(--accent);text-decoration:none;
  border-radius:var(--r-round);padding:3px var(--s3);
  font-size:var(--t-caption);line-height:1.35;
  transition:background-color .14s ease}
.picked>a i{font-style:normal;opacity:.55;font-size:var(--t-small);line-height:1}
.picked>a:hover{background:var(--line)}
.picked>a:hover i{opacity:1}
/* «Сбросить всё» — не ярлык: это выход из отбора, а не одно из условий. */
.picked>a.reset{background:none;color:var(--muted);padding:3px 0;
  text-decoration:underline}
.picked>a.reset:hover{color:var(--text);background:none}

/* --- общее для всех таблиц ------------------------------------------------
   Правила для всех таблиц сразу: каждый новый экран получает их даром, а
   не повторяет своими строками. */

/* Шапка не уезжает: таблицу на тридцать строк листают, и к середине списка
   человек уже не помнит, что это за столбец. Заливка обязательна — сквозь
   прозрачную шапку видны проезжающие строки. */
thead th{position:sticky;top:0;z-index:2;background:var(--surface)}

/* Ссылка в строке таблицы не подчёркнута: тридцать подчёркнутых фамилий
   подряд — это рябь, а не выделение. Подчёркивание возвращается под
   курсором, то есть там, где человек уже выбрал строку. */
tbody td > a:not(.btn):not(.pill){text-decoration:none}
tbody td > a:not(.btn):not(.pill):hover{text-decoration:underline}

/* Строка отборов над экраном. Набор полей у каждого экрана свой, но ведут
   они себя одинаково: одно правило вместо слегка разных на каждом. */
.row.filters{margin-bottom:var(--s5)}

/* Поле на всю ширину карточки или формы. */
input.wide,textarea.wide{width:100%}

.btn.small{padding:5px 12px}

.note.bad{background:var(--badbg);color:var(--bad)}

/* Недоступная кнопка должна выглядеть недоступной, а не «нажми — ничего не будет». */
.btn:disabled{opacity:.45;cursor:not-allowed}

h1 + .tiles,h1 + p + .tiles{margin-top:var(--s4)}

details.card > summary{cursor:pointer}

/* --- Пользователи ---------------------------------------------------------
   Строка говорит, кто это и что не так; действия — в раскрывающейся части,
   по блоку на действие. Четыре открытые формы в каждой строке читались как
   бланк, а не как список людей. */
.users-head{display:flex;align-items:center;justify-content:space-between;gap:var(--s4);flex-wrap:wrap}
.users-head .btn{text-decoration:none}
.ulist{list-style:none;margin:0 0 var(--s6)}
.card.ulist{padding:0;overflow:hidden}
.ulist>li{border-bottom:1px solid var(--line-soft)}
.ulist>li:last-child{border-bottom:0}
.urow>summary{list-style:none;cursor:pointer;display:grid;align-items:center;gap:var(--s4);
  grid-template-columns:36px minmax(170px,1.3fr) minmax(150px,1fr) minmax(150px,1.1fr) 270px 88px;
  padding:var(--s3) 18px}
.urow>summary::-webkit-details-marker{display:none}
.urow>summary:hover{background:var(--raised)}
.urow[open]>summary{background:var(--raised)}
.urow.off>summary>:not(.uflags){opacity:.55}
.uface{width:36px;height:36px;border-radius:var(--r-round);display:flex;align-items:center;
  justify-content:center;background:var(--accent-soft);color:var(--accent);font-weight:600}
.uname,.urole{display:flex;flex-direction:column;gap:2px;min-width:0}
.uname b{overflow-wrap:anywhere}
.uname small,.urole small{font-size:var(--t-caption);color:var(--muted)}
.urole .pill{width:max-content}
.pill.role-admin{background:var(--accent-soft);color:var(--accent)}
.uflags{display:flex;gap:var(--s1);flex-wrap:wrap;justify-content:flex-end}
.uopen{font-size:var(--t-caption);color:var(--accent);text-align:right;white-space:nowrap}
.uopen::after{content:" ›";display:inline-block;transition:transform .15s}
.urow[open] .uopen::after{transform:rotate(90deg)}
.ubody{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:var(--s5);
  padding:var(--s4) 18px var(--s5) 68px;border-top:1px solid var(--line-soft)}
.ubody h3{font-size:var(--t-caption);font-weight:600;color:var(--muted);margin:0 0 var(--s2)}
.ubody p{margin:var(--s2) 0 var(--s3)}
.uform{display:flex;gap:var(--s2)}
.uform select,.uform input{flex:1;min-width:0}
.btn.danger{color:var(--bad);border-color:var(--bad)}

.role-notes{margin:0;padding:var(--s4) 18px var(--s4) 38px}
.role-notes li{margin-bottom:var(--s1)}
@media (max-width:900px){
  .urow>summary{grid-template-columns:36px 1fr;gap:var(--s2) var(--s3)}
  .urow .uopen{display:none}
  .urow .urole,.urow .uflags{grid-column:2;justify-content:flex-start}
  .ubody{padding-left:18px}
}

.tile .n small{font-size:var(--t-body);color:var(--muted);font-weight:400;margin-left:2px}

.nowrap{white-space:nowrap}


/* --- каркас USAT ------------------------------------------------------------ */
/* Низ меню: смена пароля и выход — тихие ссылки, не кнопки раздела. */
nav .who-link{display:block;padding:var(--s2) 0 0;color:var(--nav-text)}
nav .who-link:hover{color:var(--nav-bright)}
nav .who-out{margin-top:var(--s2)}
/* Кнопки в ряд на маленьких страницах (ошибка, вход). */
.actions-row{display:flex;gap:var(--s3);flex-wrap:wrap}
/* Узкая карточка формы: смена пароля, одна колонка полей. */
.card.narrow{max-width:420px}
.card.narrow input{margin-bottom:var(--s3)}
/* Временный пароль: крупно и моноширинно — его диктуют и переписывают. */
.secret .big{font-size:var(--t-section);font-weight:600;letter-spacing:.06em}
/* Журнал действий: открытие личных данных — полоса слева, чтобы такие строки
   находились глазом, не читая столбец «Действие». */
tr.is-read td:first-child{box-shadow:inset 3px 0 0 var(--wip)}

/* --- студенты и контракты ---------------------------------------------------- */
/* Заголовок страницы и действие справа: «Договоры» и «Скачать в Excel». */
.page-head{display:flex;justify-content:space-between;align-items:center;gap:var(--s3);flex-wrap:wrap;
  margin-bottom:var(--s4)}
.page-head h1{margin:0}
/* Деньги и счёт — по правому краю и цифрами одной ширины: столбец читается сверху вниз. */
th.num,td.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
/* Доля строки от целого — полоса без цифр рядом с самой цифрой. */
td.bar-cell{width:30%;min-width:120px}
progress.share{appearance:none;-webkit-appearance:none;width:100%;height:8px;border:0;
  border-radius:var(--r-round);background:var(--na-bg);overflow:hidden;vertical-align:middle}
progress.share::-webkit-progress-bar{background:var(--na-bg);border-radius:var(--r-round)}
progress.share::-webkit-progress-value{background:var(--accent);border-radius:var(--r-round)}
progress.share::-moz-progress-bar{background:var(--accent);border-radius:var(--r-round)}
/* Матрица «курс × форма»: в клетке число, под ним доля, всего и долг.
   Цвет — доля неплативших; рядом всегда число, цвет смысл не несёт один. */
table.mx td{padding:var(--s2) var(--s3)}
table.mx th{white-space:nowrap}
table.mx .cnt{display:block;font-weight:600;font-size:var(--t-body)}
table.mx .sub{display:block;font-size:var(--t-caption);color:var(--muted)}
table.mx td.off{color:var(--faint)}
table.mx td.total,table.mx tr.total th{background:var(--raised)}
table.mx td.lvl1{background:var(--wip-bg)}
table.mx td.lvl2{background:var(--todo-bg)}
table.mx td.lvl3{background:var(--todo-bg);box-shadow:inset 0 0 0 2px var(--todo)}
table.mx td.lvl2 .cnt,table.mx td.lvl3 .cnt{color:var(--todo)}
/* Было → станет в предпросмотре загрузки. */
.diff del{color:var(--muted)}
.diff ins{text-decoration:none;font-weight:600}
/* --- всплывающее окно ------------------------------------------------------- */
/* Родной <dialog>, открывается dialog.js поверх экрана с затемнением. Поля
   окна — у .dlg-body внутри: щелчок по самому <dialog> значит «по затемнению»
   и закрывает окно, поэтому своих полей у <dialog> нет. Цвета — токенами:
   в тёмной теме окно читается так же, как карточка. */
dialog.dlg{border:0;padding:0;border-radius:var(--r-card);background:var(--surface);
  color:var(--text);box-shadow:0 12px 40px rgba(16,24,40,.22);width:min(720px,calc(100vw - 32px));
  max-height:calc(100vh - 64px)}
dialog.dlg::backdrop{background:rgba(16,24,40,.45)}
.dlg-body{padding:var(--s7) 26px;overflow:auto;max-height:calc(100vh - 64px)}
.dlg-head{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s3);
  margin-bottom:var(--s3)}
.dlg-head h2{margin:0;font-size:var(--t-section)}
.dlg-body h3{margin:var(--s6) 0 var(--s3)}
@media (max-width:640px){.dlg-body{padding:var(--s5) 16px}}

/* Списки людей (сотрудники): имя крупно, отчество и отдел — второй строкой */
table.people td{padding:10px var(--s3);vertical-align:middle}
table.people td.person{min-width:220px}
.person>a{font-weight:500;font-size:var(--t-small)}
.person .pill{margin-left:6px;vertical-align:1px}
.person .pat,.post .dep{display:block;font-size:var(--t-caption);color:var(--muted);margin-top:1px}
.posts .post+.post{margin-top:8px}
.post .pos{color:var(--text)}
.tag{display:inline-block;margin-left:6px;padding:0 7px;border-radius:var(--r-round);
  background:var(--raised);color:var(--muted);font-size:var(--t-label);line-height:18px;white-space:nowrap}
.faint{color:var(--faint)}
table.people tr.group td{background:var(--raised);color:var(--muted);font-size:var(--t-caption);
  font-weight:600;padding:6px var(--s3);border-bottom:1px solid var(--line)}
tbody tr.group:hover td{background:var(--raised)}
table.people tr.group .cnt{font-weight:400;margin-left:6px}
table.people td.num{width:1%}

/* --- телеграм-бот ----------------------------------------------------------- */
/* Текст бота только для чтения: переносы строк — как их увидит студент. */
p.pre{white-space:pre-wrap;margin:var(--s1) 0 0}
/* --- раскрывающийся блок в карточке ------------------------------------------ */
/* Подразделение в фонде оплаты труда: строка-итог, по нажатию — люди. */
details.disclose{border-top:1px solid var(--line-soft);padding:var(--s3) 0}
details.disclose:first-of-type{border-top:0}
details.disclose>summary{cursor:pointer;font-weight:600;list-style-position:inside}
details.disclose[open]>summary{margin-bottom:var(--s3)}
/* --- отчёты P&L и Cashflow -------------------------------------------------- */
/* Строки — статьи, колонки — 12 месяцев и год. Итоги выделены фоном и весом,
   минус — словом «−» в числе и цветом рядом, не одним цветом. */
table.report th:first-child{white-space:nowrap;font-weight:400;position:sticky;left:0;
  background:var(--surface)}
table.report td{white-space:nowrap}
table.report tr.sub th,table.report tr.sub td{font-weight:600;background:var(--raised)}
table.report tr.sub th:first-child{background:var(--raised)}
table.report tr.total th,table.report tr.total td{font-weight:700;border-top:2px solid var(--line)}
table.report tr.balance th,table.report tr.balance td{font-weight:600;color:var(--accent)}
table.report td.neg{color:var(--todo)}
