/* Вёрстка админки NOTA.
   Вырезано из макета nota-admin-mockup-final.html без изменений правил;
   выкинут только блок «переписка» (этой страницы в первой версии нет),
   а встроенные base64-шрифты вынесены в static/fonts/.
   Править цвета и размеры здесь, а не в разметке. */
@font-face{
  font-family:'Inter var';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('fonts/inter-cyrillic.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face{
  font-family:'Inter var';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('fonts/inter-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2195,U+2196,U+2197,U+2198,U+2199,U+2212,U+2215,U+FEFF,U+FFFD;
}
:root{
  --canvas:#F1F3F7;
  --card:#FFFFFF;
  --line:#E3E8EF;
  --line-2:#EEF1F5;
  --text:#141A23;
  --text-2:#414D5E;
  --muted:#6D7B8D;
  --faint:#94A1B2;
  --hot:#D22F45;
  --warm:#B87512;
  --calm:#0E827A;
  --indigo:#4744AD;
  --indigo-bg:#F3F3FC;
  --ink:#141C28;

  --sh:0 1px 2px rgba(20,26,35,.05), 0 12px 28px -20px rgba(20,26,35,.24);
  --sh-lift:0 1px 2px rgba(20,26,35,.06), 0 18px 36px -22px rgba(20,26,35,.30);
  --r:12px;

  /* одна гарнитура на весь интерфейс */
  --ui:'Inter var',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  /* четыре размера: число, заголовок, тело, подпись */
  --fs-d:28px;
  --fs-h:16px;
  --fs-b:14px;
  --fs-c:12px;

  --rail:66px;
  --rail-open:242px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--canvas);color:var(--text);
  font-family:var(--ui);font-size:var(--fs-b);line-height:1.55;font-weight:400;
  -webkit-font-smoothing:antialiased;font-feature-settings:"cv05" 1,"ss03" 1;
}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.eyebrow{
  font-size:var(--fs-c);font-weight:600;letter-spacing:.075em;text-transform:uppercase;
  color:var(--faint);line-height:1.3;
}
.eyebrow.hot{color:var(--hot)}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;text-align:left}
/* Единственное добавление к вырезанному из макета CSS.
   В макете всё кликаемое — <button>, и правило выше гасит ему рамку,
   цвет и подчёркивание. В реализации это настоящие ссылки (<a href>):
   переходы между страницами должны работать без JS — средняя кнопка,
   «открыть в новой вкладке», адресная строка. Своего правила для <a>
   в макете нет и быть не могло: ссылок там не было ни одной.
   Без этого сброса браузер рисует подчёркивание и ссылочный цвет на
   заголовках счётчиков, подписях под ними, самих цифрах, «Смотреть все»
   и пунктах бокового меню — то есть почти на всей странице.
   Подчёркивание при наведении не задевается: .seeall:hover и .act:hover
   специфичнее этого правила и продолжают работать. */
a{color:inherit;text-decoration:none}

/* Вертикальный зазор между блоками страницы.
   В макете это делало правило #page-overview{...gap:14px} — там все
   страницы лежали в одном документе, каждая со своим id. У нас страница
   на запрос, и render.page() выводит только class="page", поэтому
   селектор по id не совпадал ни с чем: по горизонтали зазоры были (их
   задают .ov-top и .cards своими gap), а по вертикали блок «Требует
   решения» упирался в карточки вплотную — 0px.
   Правило по классу чинит это на всех страницах сразу, а не только на
   обзоре: на «без касания» так же слипались таблица и ссылка возврата. */
.page{display:flex;flex-direction:column;gap:14px}

/* Подпись счётчика — тёмная, как обычный текст.
   Это ссылка на раздел, а не служебная пометка: в макете .eyebrow
   задумывался блёклым ярлыком над числом, но там он ничего не открывал.
   У нас вся карточка счётчика кликабельна, и название раздела должно
   читаться. Блёклый --faint на белом почти сливался с фоном. */
.counter .eyebrow{color:var(--text)}

/* Заголовок карточки ведёт в свой раздел — как и «Смотреть все» внизу.
   Цвет не трогаем: он и так тёмный, наследуется от сброса ссылок выше. */
.card-head a:hover h2{text-decoration:underline}

/* Блок «Требует решения»: высоту строки грида задаёт колонка счётчиков —
   четыре карточки по 56px с зазорами, итого 248px, и меньше они быть не
   могут: 56px это ровно высота их содержимого.
   Пунктов в блоке обычно три, вместе они около 150px. Если блок ужать по
   содержимому, под ним остаётся полоса пустого фона до карточек; если
   растянуть и оставить пункты вверху — пустая белая половина карточки.
   Поэтому блок растягивается, а свободную высоту разбирают между собой
   сами пункты: текст в них выравнивается по центру своей строки, и блок
   выглядит просторным, а не наполовину пустым. Карточки при этом идут
   сразу под блоком. */
.ov-top .alerts .arow{flex:1 1 auto;align-items:center}

/* Заливка полоски времени должна иметь ширину.
   .fill — это <span>, то есть строчный элемент, а к строчным не
   применяется ни width, ни height. Из-за этого style="width:57%" ничего
   не делал: во ВСЕХ строках была видна только серая дорожка, и полоски
   выглядели одинаковыми при 30 днях и при 4. Проценты при этом считались
   правильно, от максимума в выборке. Правило есть и в макете — там
   заливка тоже не рисовалась ни разу. */
.timebar .fill{display:block}

/* Отступ справа у полоски, когда её колонка последняя в таблице.
   На «Горит сейчас» и «Без ответственного» колонка времени идёт последней,
   дорожка растягивается до конца ячейки, и самая длинная заливка (100% по
   построению — это максимум выборки) упиралась в рамку таблицы. Там, где
   после времени есть ещё колонка, отступ не нужен и не добавляется. */
td.timecell:last-child{padding-right:36px}
input,select{font:inherit}
:focus-visible{outline:2px solid var(--indigo);outline-offset:2px;border-radius:4px}

/* ================= боковая панель ================= */
.rail{
  position:fixed;left:0;top:0;bottom:0;width:var(--rail);z-index:40;
  background:var(--ink);color:#C4CEDC;
  display:flex;flex-direction:column;overflow:hidden;transition:width .13s ease;
}
.rail:hover,.rail:focus-within,.rail.pinned{
  width:var(--rail-open);
  box-shadow:0 0 0 1px rgba(0,0,0,.2), 26px 0 48px -28px rgba(10,15,24,.55);
}
.rail-top{
  height:58px;display:flex;align-items:center;gap:12px;padding-left:21px;flex-shrink:0;
  border-bottom:1px solid rgba(255,255,255,.07);
}
.mark{
  width:24px;height:24px;border-radius:7px;background:#fff;color:var(--ink);
  font-size:var(--fs-b);font-weight:700;display:flex;align-items:center;justify-content:center;
  flex-shrink:0;margin-left:-1px;
}
.rail-name{
  font-size:var(--fs-b);font-weight:600;letter-spacing:.18em;color:#fff;white-space:nowrap;
  opacity:0;transition:opacity .12s ease;
}
.rail:hover .rail-name,.rail:focus-within .rail-name,.rail.pinned .rail-name{opacity:1}

.nav{padding:10px 8px;display:flex;flex-direction:column;gap:2px}
.nav-item{
  display:flex;align-items:center;gap:14px;height:40px;padding:0 12px;border-radius:9px;
  color:#AFBBCB;white-space:nowrap;position:relative;flex-shrink:0;
}
.nav-item:hover{background:rgba(255,255,255,.07);color:#fff}
.nav-item[aria-current="true"]{background:rgba(255,255,255,.12);color:#fff}
.nav-item[aria-current="true"]::before{
  content:"";position:absolute;left:-8px;top:11px;bottom:11px;width:3px;
  background:#fff;border-radius:0 3px 3px 0;
}
.nav-item svg{width:18px;height:18px;flex-shrink:0;stroke:currentColor;fill:none;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.nav-label{font-size:var(--fs-b);opacity:0;transition:opacity .12s ease}
.nav-badge{
  margin-left:auto;font-size:var(--fs-c);font-weight:600;padding:1px 8px;border-radius:20px;
  background:rgba(255,255,255,.14);color:#E3EAF3;opacity:0;transition:opacity .12s ease;
  font-variant-numeric:tabular-nums;
}
.nav-badge.hot{background:#D22F45;color:#fff}
.rail:hover .nav-label,.rail:focus-within .nav-label,.rail.pinned .nav-label,
.rail:hover .nav-badge,.rail:focus-within .nav-badge,.rail.pinned .nav-badge{opacity:1}
.dot{
  position:absolute;left:31px;top:8px;width:7px;height:7px;border-radius:50%;
  background:var(--hot);border:2px solid var(--ink);
}
.dot.warm{background:var(--warm)}
.dot.mute{background:#7A8798}
.rail:hover .dot,.rail:focus-within .dot,.rail.pinned .dot{opacity:0}
.rail-foot{margin-top:auto;padding:10px 8px 14px}
.pinbtn{
  display:flex;align-items:center;gap:14px;height:34px;padding:0 12px;border-radius:8px;
  color:#7F8DA0;font-size:var(--fs-c);white-space:nowrap;width:100%;
}
.pinbtn:hover{background:rgba(255,255,255,.06);color:#DCE4EE}
.pinbtn span{opacity:0;transition:opacity .12s ease}
.rail:hover .pinbtn span,.rail.pinned .pinbtn span,.rail:focus-within .pinbtn span{opacity:1}

/* ================= каркас ================= */
.main{margin-left:var(--rail);min-height:100vh;display:flex;flex-direction:column}
.topbar{
  height:58px;flex-shrink:0;background:rgba(241,243,247,.88);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);position:sticky;top:0;z-index:20;
  display:flex;align-items:center;gap:14px;padding:0 26px;
}
.topbar h1{margin:0;font-size:var(--fs-h);font-weight:600;letter-spacing:-.015em}
.topbar .sub{font-size:var(--fs-b);color:var(--muted)}
.clock{margin-left:auto;font-size:var(--fs-c);color:var(--faint);text-align:right;line-height:1.4}
.clock b{display:block;font-weight:500;color:var(--text-2)}
.page{padding:20px 26px 34px;flex:1}
.page[hidden]{display:none}

/* ================= обзор: плитка ================= */
#page-overview{display:flex;flex-direction:column;gap:14px}
.ov-top{display:grid;grid-template-columns:2fr 1fr;gap:14px;align-items:stretch}

.alerts{
  background:var(--card);border-radius:var(--r);box-shadow:var(--sh);
  position:relative;overflow:hidden;padding:14px 22px 15px;
  display:flex;flex-direction:column;
}
.alerts::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--hot)}
.alerts .eyebrow{margin-bottom:2px}
.arow{
  display:flex;align-items:baseline;gap:20px;padding:6px 0;
  border-bottom:1px solid var(--line-2);
}
.arow:last-of-type{border-bottom:0}
.alerts-foot{padding-top:12px}
.arow .atext{
  display:block;margin:0;flex:1;min-width:0;
  font-size:var(--fs-b);line-height:1.5;
}
.arow .atext b{font-weight:600}
.arow .atext .t{
  display:inline;margin:0;padding:0;
  font-weight:600;color:var(--hot);font-variant-numeric:tabular-nums;
}
.arow .act{
  flex-shrink:0;white-space:nowrap;font-size:var(--fs-b);color:var(--indigo);font-weight:500;
}
.arow .act:hover{text-decoration:underline}

.counters{display:flex;flex-direction:column;gap:8px;height:100%}
.counter{
  background:var(--card);border-radius:var(--r);box-shadow:var(--sh);
  position:relative;overflow:hidden;padding:12px 18px;flex:1 1 0;min-height:56px;
  display:flex;align-items:center;gap:14px;
}
.counter::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--line)}
.counter.is-hot::before{background:var(--hot)}
.counter.is-warm::before{background:var(--warm)}
.counter.is-indigo::before{background:var(--indigo)}
.counter.is-calm::before{background:var(--calm)}
.counter:hover{box-shadow:var(--sh-lift)}
.counter .txt{flex:1;min-width:0}
.counter .sub{display:block;font-size:var(--fs-c);color:var(--muted);margin-top:1px}
.counter .val{
  font-size:var(--fs-d);font-weight:600;line-height:1;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;flex-shrink:0;
}
.counter.is-hot .val{color:var(--hot)}
.counter.is-warm .val{color:var(--warm)}

/* три карточки */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;align-items:start}
.card{background:var(--card);border-radius:var(--r);box-shadow:var(--sh);
  display:flex;flex-direction:column;overflow:hidden}
.card-head{padding:15px 20px 10px;display:flex;align-items:center;gap:10px;flex-shrink:0}
.card-head h2{margin:0;font-size:var(--fs-h);font-weight:600;letter-spacing:-.015em}
.card-head .cnt{font-size:var(--fs-c);color:var(--faint);font-weight:500;
  font-variant-numeric:tabular-nums}
.card-body{padding:0 20px}
.card-foot{padding:12px 20px 16px;flex-shrink:0}
.seeall{font-size:var(--fs-b);color:var(--indigo);font-weight:500;
  display:inline-flex;align-items:center;gap:6px}
.seeall:hover{text-decoration:underline}

.crow{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:12px 0;border-bottom:1px solid var(--line-2);
}
.card-body .crow:last-child{border-bottom:0}
.crow:hover .cname{color:var(--indigo)}
.crow.crit{box-shadow:inset 3px 0 0 var(--hot);padding-left:11px}
.cname{font-size:var(--fs-b);font-weight:500;flex:1;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ctime{font-size:var(--fs-b);font-variant-numeric:tabular-nums;white-space:nowrap;
  flex-shrink:0;color:var(--muted);font-weight:500}
.ctime.crit{color:var(--hot);font-weight:600}
.ctime.warn{color:var(--warm)}
.cwho{font-size:var(--fs-b);color:var(--text-2);white-space:nowrap;flex-shrink:0;
  text-align:right}
.cwho.none{font-style:italic;color:var(--faint)}

/* ================= бейджи и полоски ================= */
.pfx{
  font-size:var(--fs-c);font-weight:700;letter-spacing:.02em;
  padding:2px 6px;border-radius:5px;color:#fff;flex-shrink:0;line-height:1.35;
}
.pfx-WL{background:#3D5A80}.pfx-INV{background:#7A5195}
.pfx-IBN{background:#1F6F6A}.pfx-APM{background:#A05C1B}.pfx-C{background:#4A5568}
.prio{
  font-size:var(--fs-c);font-weight:500;color:var(--indigo);
  border:1px solid #CFCEEE;background:var(--indigo-bg);
  padding:1px 7px;border-radius:5px;white-space:nowrap;line-height:1.35;
}
.timebar{display:flex;align-items:center;gap:12px}
.timebar .t{
  font-size:var(--fs-b);font-variant-numeric:tabular-nums;
  width:88px;flex-shrink:0;text-align:right;font-weight:500;color:var(--muted);
}
.timebar .track{flex:1;height:5px;border-radius:3px;background:#EAEEF3;overflow:hidden;min-width:34px}
.timebar .fill{height:100%;border-radius:3px;background:#8B99AB}
.lv-hot .fill{background:var(--hot)}.lv-hot .t{color:var(--hot);font-weight:600}
.lv-warm .fill{background:var(--warm)}.lv-warm .t{color:var(--warm)}
.lv-calm .fill{background:var(--calm)}.lv-calm .t{color:var(--calm)}
.lv-cold .fill{background:#8B99AB}.lv-cold .t{color:var(--muted)}
.lv-norm .fill{background:#8B99AB}.lv-norm .t{color:var(--muted)}
.timebar.mini .t{width:70px}

/* ================= таблицы ================= */
.panel{background:var(--card);border-radius:var(--r);box-shadow:var(--sh);overflow:hidden}
.toolbar{padding:14px 20px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  border-bottom:1px solid var(--line-2)}
.toolbar .grow{flex:1;min-width:120px}
.field{
  padding:8px 12px;border:1px solid var(--line);border-radius:9px;background:#FBFCFE;
  font-size:var(--fs-b);color:var(--text);min-width:150px;
}
.field:focus{background:#fff;border-color:#B7C1D0;outline:none;box-shadow:0 0 0 3px rgba(71,68,173,.11)}
select.field{cursor:pointer}
.chips{display:flex;gap:6px;flex-wrap:wrap}
.chip{
  font-size:var(--fs-c);font-weight:500;letter-spacing:.02em;
  padding:6px 11px;border:1px solid var(--line);border-radius:20px;color:var(--muted);
}
.chip:hover{border-color:#B7C1D0;color:var(--text)}
.chip[aria-pressed="true"]{background:var(--ink);border-color:var(--ink);color:#fff}
.found{font-size:var(--fs-c);color:var(--faint);margin-left:auto;
  font-variant-numeric:tabular-nums}

table{width:100%;border-collapse:collapse}
thead th{
  font-size:var(--fs-c);font-weight:600;letter-spacing:.075em;text-transform:uppercase;
  color:var(--faint);text-align:left;padding:12px 20px;
  border-bottom:1px solid var(--line-2);white-space:nowrap;background:#FBFCFD;
}
thead th.sortable{cursor:pointer;user-select:none}
thead th.sortable:hover{color:var(--text-2)}
thead th .arrow{opacity:.35;margin-left:5px}
thead th[aria-sort] .arrow{opacity:1;color:var(--indigo)}
tbody tr{border-bottom:1px solid var(--line-2);cursor:pointer}
tbody tr:last-child{border-bottom:0}
tbody tr:hover{background:#F7F9FC}
tbody tr.crit td:first-child{box-shadow:inset 3px 0 0 var(--hot)}
td{padding:15px 20px;vertical-align:middle;line-height:1.55}
.g-name{display:flex;align-items:center;gap:10px;font-weight:500}
.kam{white-space:nowrap;color:var(--text-2)}
.kam.none{color:var(--muted);font-style:italic}
.topic{color:var(--text-2)}
.cell-n{color:var(--text-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.cap{font-size:var(--fs-c);color:var(--faint)}
.timecell{width:224px}
.tnone{padding:38px 20px;text-align:center;color:var(--muted)}

/* ================= сотрудники ================= */
.people{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-bottom:14px}
.person{background:var(--card);border-radius:var(--r);box-shadow:var(--sh);padding:20px 22px 22px}
.person h3{margin:0 0 2px;font-size:var(--fs-h);font-weight:600;letter-spacing:-.015em}
.person .role{font-size:var(--fs-c);color:var(--muted);margin-bottom:18px}
.pmetrics{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:18px}
.pmetric .k{font-size:var(--fs-c);color:var(--muted);display:block;margin-bottom:3px}
.pmetric .v{font-size:var(--fs-h);font-weight:600;letter-spacing:-.015em;
  font-variant-numeric:tabular-nums}
.ticks{display:flex;gap:2px;flex-wrap:wrap}
.ticks i{width:4px;height:15px;border-radius:1px;background:#E1E7EE;display:block}
.ticks i.on{background:var(--calm)}
.ticks i.today{background:var(--indigo)}
.tickcap{font-size:var(--fs-c);color:var(--muted);margin-top:11px}
.tickcap .lg{color:var(--faint);display:block;margin-bottom:7px;letter-spacing:.05em;
  text-transform:uppercase;font-weight:600}
.tickcap .lg i{display:inline-block;width:7px;height:7px;border-radius:2px;
  margin:0 5px 0 13px;vertical-align:1px}
.tickcap .lg i:first-child{margin-left:0}

@media (max-width:1240px){
  .ov-top{grid-template-columns:1fr}
  .counters{flex-direction:row}
  .counter{flex-direction:column;align-items:flex-start;gap:8px}
  .cards{grid-template-columns:1fr}
}
@media (max-width:1080px){
  .counters{flex-wrap:wrap}
  .counter{min-width:180px}
  .people{grid-template-columns:1fr}
  .hide-s{display:none}
}
@media (max-width:860px){
  .arow{flex-direction:column;align-items:flex-start;gap:6px}
  .page,.topbar{padding-left:16px;padding-right:16px}
  .clock{display:none}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important;
  scroll-behavior:auto!important}}

/* ================= графики ================= */
/* Своей вёрстки в макете под них нет — графиков там не было. Всё
   собрано из тех же токенов: карточка .panel, отступы и цвета общие. */
.charts{display:flex;flex-direction:column;gap:14px}
.chart-panel{padding:0 0 14px}
.chart-panel .card-head{padding:15px 20px 2px}
.chart-note{padding:0 20px 12px;font-size:var(--fs-c);color:var(--muted);
  line-height:1.5;max-width:70ch}
.chart-warn{margin:0 20px 10px;padding:7px 11px;border-radius:8px;
  background:#FEF9EC;border:1px solid #F0E0BC;color:var(--warm);
  font-size:var(--fs-c)}
.chart-body{padding:0 20px}
/* Высота задана инлайном, ширина тянется: масштаб по осям разный,
   поэтому внутри SVG нет ни текста, ни масштабируемой обводки. */
.chart{display:block;width:100%}
.chart-axis{stroke:var(--line);stroke-width:1}
.chart-bar{fill:var(--indigo)}
.chart-line{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
.chart-ticks{display:grid;margin-top:7px;font-size:var(--fs-c);
  color:var(--faint);font-variant-numeric:tabular-nums}
.chart-ticks span{text-align:center;line-height:1.35;overflow:hidden}
.chart-ticks b{display:block;font-weight:600;color:var(--text-2)}
.chart-scale{margin-top:8px;font-size:var(--fs-c);color:var(--faint)}
.chart-legend{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:10px;
  font-size:var(--fs-c);color:var(--text-2)}
.chart-key{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.chart-key i{width:9px;height:9px;border-radius:2px;flex-shrink:0}
.chart-key b{font-weight:600;font-variant-numeric:tabular-nums}
.chart-empty{padding:26px 20px;text-align:center;color:var(--muted)}
@media (max-width:860px){
  .chart-ticks{font-size:10px}
}

/* Недостоверная неделя: под наблюдением была меньшая часть нынешних
   групп (THIN_WEEK_SHARE в kpi/trends.py). Столбик приглушён, а вместо
   числа стоит «мало данных» — ноль там читался бы как «проблем не было»,
   хотя означает «почти ничего не видели». */
.chart-bar.thin{fill:#D5DCE5}
.chart-ticks b.thin{font-weight:500;color:var(--faint);letter-spacing:-.01em}

/* Компактный вариант на обзоре: подпись уходит в шапку одной строкой,
   отдельной строки шкалы у столбиков нет — числа и так под каждым. */
.chart-panel.compact .card-head{padding:14px 20px 10px;flex-wrap:wrap}
.chart-panel.compact .card-head .cap{flex:1;min-width:0}
.chart-panel.compact .card-head .cnt{margin-left:auto}

/* ================= приоритет групп ================= */
/* .prio из макета — база бейджа; варианты добавлены под уровни.
   «Обычный» бейджа не имеет вовсе: он идёт блёклым текстом (.cap), иначе
   сто шестьдесят одинаковых бейджей перебивают те несколько, ради которых
   колонка и заведена. */
.prio-key{color:#8A2331;border-color:#F0C9CF;background:#FDF3F4}
.prio-inactive{color:var(--muted);border-color:var(--line);background:#F6F8FA}
/* Whitelabel — вывод правила по названию, не хранимое значение. Цвет тот
   же, что у бейджа префикса .pfx-WL, чтобы связь читалась глазом. */
.prio-wl{color:#3D5A80;border-color:#C6D2E0;background:#F2F6FA}

/* Уровень «обычный» в ячейке выбора рисуется бейджем наравне с остальными:
   там ячейка обязана выглядеть как один кликабельный элемент, а блёклый
   текст читался бы как «поле пустое». В СПИСКАХ он по-прежнему без бейджа —
   это разные задачи, см. _priority_tag и _priority_cell в web/render.py. */
.prio-normal{color:var(--text-2);border-color:var(--line);background:#F7F9FC}

/* Выбор приоритета: одна ячейка с текущим уровнем, по клику — список из
   трёх. Без JS, на <details>/<summary>: CSP пускает скрипты только со
   своего домена и telegram.org, и городить nonce ради выпадашки незачем,
   а так она работает и при полностью отключённых скриптах.

   Классов .chip здесь намеренно НЕТ. Первая версия переиспользовала .chip
   из макета и переопределяла ему только background — при равной
   специфичности с .chip[aria-pressed="true"] оставался чужой color:#fff,
   и текущий уровень выходил белым текстом на белом фоне. Свои классы
   ни с чем не конкурируют. */
.priopick{position:relative;display:inline-block}
.priopick summary{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  list-style:none;user-select:none;border-radius:6px;
}
.priopick summary::-webkit-details-marker{display:none}
.priopick summary:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(71,68,173,.18)}
.priopick .caret{width:9px;height:9px;flex-shrink:0;color:var(--faint);
  transition:transform .12s}
.priopick[open] .caret{transform:rotate(180deg)}

/* Список раскрывается В ПОТОКЕ, а не поверх строки. Причина простая:
   .panel стоит overflow:hidden ради скруглённых углов, и всплывающий
   список у нижних строк таблицы обрезался бы. Строка при этом растёт
   только одна — details объединены атрибутом name, и открытый список
   закрывает предыдущий. */
.priomenu{display:flex;flex-direction:column;gap:2px;margin-top:8px;
  padding:5px;border:1px solid var(--line);border-radius:9px;
  background:var(--card);box-shadow:var(--sh);min-width:168px}
.priomenu button{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  width:100%;padding:5px 6px;border:0;border-radius:6px;background:transparent;
  font:inherit;font-size:var(--fs-c);color:var(--text-2);cursor:pointer;
  text-align:left;
}
.priomenu button:hover{background:#F2F5F9}
.priomenu button:focus-visible{outline:none;box-shadow:0 0 0 2px rgba(71,68,173,.28)}
.priomenu .tick{color:var(--indigo);font-weight:600;flex-shrink:0}
/* Текущий уровень остаётся в списке и помечен галочкой — как в статусах
   Notion. Прятать его нельзя: список то из двух, то из трёх пунктов
   читается как разный список. Повторный выбор сервер отбрасывает без
   записи в журнал. */
.priomenu button[aria-current="true"]{background:#F3F3FC}
.priocell{width:210px}

/* Кнопка «Показать» в панели поиска. .chip в макете — ссылка, у <button>
   свои умолчания браузера; aria-pressed здесь нет, так что конфликта, из-за
   которого пропадал текст уровня, тоже нет. */
.toolbar button.chip{font:inherit;font-size:var(--fs-c);font-weight:500;
  background:transparent;cursor:pointer}

/* Подтверждение записи. Зелёная рамка, а не жёлтая .chart-warn: это не
   предупреждение, а «сохранено». */
.notice{margin:0 0 14px;padding:9px 13px;border-radius:9px;
  background:#EFF8F6;border:1px solid #BFE0DB;color:var(--calm);
  font-size:var(--fs-b)}

/* ================= страница настроек ================= */
/* Своих классов здесь больше, чем хотелось бы, и это сознательно: за
   переиспользование классов макета с частичным переопределением свойств
   уже платили — .prioset .chip и .chip[aria-pressed="true"] имели равную
   специфичность, и текущий уровень выходил белым текстом на белом фоне.
   .setbtn и .dangerbtn ни с чем не конкурируют. */

.setgroup{margin:0}

/* ── заголовок раздела ── */
/* Своя полоса, а не .card-head из макета. Там заголовок 16px/600, а
   название настройки 14px/600 — при прокрутке «Дайджест и отчёты» и «Час
   дайджеста» читались как один уровень, и границу разделов приходилось
   искать чтением.
   Признаков сразу три, чтобы раздел считывался боковым зрением: размер,
   заливка с нижней границей и цветная черта слева. Черта — тот же приём,
   что у блока «Требует решения» на обзоре (.alerts::before), но индиговая:
   это разделитель, а не тревога. */
.sethead{position:relative;padding:17px 20px 15px;background:#F4F7FB;
  border-bottom:1px solid var(--line)}
.sethead::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--indigo)}
.sethead h2{margin:0;font-size:19px;font-weight:650;letter-spacing:-.02em;
  color:var(--text)}
.setnote{margin:5px 0 0;font-size:var(--fs-c);color:var(--muted);
  line-height:1.5;max-width:70ch}
/* Разделы стоят чуть просторнее, чем прочие блоки страницы (.page даёт
   14px): при быстрой прокрутке зазор работает вместе с полосой. */
.setgroup+.setgroup{margin-top:8px}
/* Три колонки: объяснение, текущее значение, поле ввода. Объяснению
   отдаётся всё оставшееся место — оно здесь и есть содержание страницы. */
.setgroup td{vertical-align:top;padding-top:16px;padding-bottom:16px}
.setgroup td.setnow{white-space:nowrap;color:var(--text-2);
  font-variant-numeric:tabular-nums}
.setgroup th:nth-child(2),.setgroup td:nth-child(2){width:150px}
.setgroup th:nth-child(3),.setgroup td:nth-child(3){width:300px}

/* Разделитель заметнее, чем в остальных таблицах: там строка — это одна
   короткая запись, здесь — настройка с объяснением, и на --line-2 восемь
   таких в разделе сливались в одно полотно. Строка тут ничего не открывает
   целиком (открывает <summary>), поэтому и курсор обычный. */
.setgroup tbody tr{border-bottom:1px solid var(--line);cursor:default}
.setgroup tbody tr:last-child{border-bottom:0}
.setgroup tbody tr:hover{background:transparent}

/* ── свёрнутое объяснение ── */
/* В строке остаётся название и одна фраза о том, что настройка делает.
   Последствия — под катом: пять уровней текста в каждой строке превращали
   раздел в полотно, и его переставали читать целиком, вместе с теми
   объяснениями, ради которых страница и делалась.
   details/summary, как на выборе приоритета: CSP пускает скрипты только со
   своего домена и telegram.org. */
.setinfo summary{list-style:none;cursor:pointer;border-radius:8px;
  display:block;max-width:60ch}
.setinfo summary::-webkit-details-marker{display:none}
.setinfo summary:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(71,68,173,.18)}
.setline{display:flex;align-items:center;flex-wrap:wrap;gap:8px}
.setname{font-weight:600;color:var(--text)}
.setwhat{display:block;margin-top:3px;font-size:var(--fs-b);color:var(--text-2)}
.qmark{width:13px;height:13px;flex-shrink:0;color:var(--faint);
  transition:color .12s}
.setinfo summary:hover .qmark{color:var(--indigo)}
.setinfo[open] .qmark{color:var(--indigo)}
.setmore{margin-top:9px;padding:10px 12px;border-radius:9px;
  background:#F7F9FC;border:1px solid var(--line-2);max-width:60ch}
.setmore p{margin:0;font-size:var(--fs-c);color:var(--text-2);line-height:1.6}
.setmore p+p{margin-top:7px}
.setmore .setwait-full{color:var(--warm)}

/* Пометка опасной настройки. Была красной «таблеткой» — и оказалась ею у
   двенадцати строк из тридцати трёх: пометка, стоящая у трети списка,
   читается как фон, а не как предупреждение. Теперь приглушённый значок со
   словом, без заливки и рамки. Красный на странице остался ровно в одном
   месте — на кнопке «Применить» в подтверждении. */
.risky-tag{display:inline-flex;align-items:center;gap:4px;
  color:var(--warm);font-size:var(--fs-c);font-weight:500;white-space:nowrap}
.risky-tag svg{width:12px;height:12px;flex-shrink:0}

/* «Подхватится в 07:55» — короткой пометкой в строке, полной фразой внутри
   ката. Совсем убрать нельзя: именно она отвечает на «поменял час, ничего
   не произошло». */
.setwait{color:var(--faint);font-size:var(--fs-c);white-space:nowrap}

.setedit{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.setedit .field{flex:1;min-width:110px}
/* Диапазон допустимых значений постоянно не показывается — он нужен ровно
   тогда, когда человек ошибся. Живёт в placeholder и title, а при отказе
   печатается здесь. */
.setedit .fielderr{flex-basis:100%;line-height:1.4;font-size:var(--fs-c);
  color:var(--hot)}
.setedit .field.bad{border-color:#E6A6B0;background:#FDF7F8}
.setedit .field.bad:focus{border-color:#D22F45;box-shadow:0 0 0 3px rgba(210,47,69,.14)}
.setbtn{
  display:inline-flex;align-items:center;padding:7px 12px;border-radius:9px;
  border:1px solid var(--line);background:transparent;color:var(--text-2);
  font:inherit;font-size:var(--fs-c);font-weight:500;cursor:pointer;
  text-decoration:none;
}
.setbtn:hover{border-color:#B7C1D0;color:var(--text)}
.setbtn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(71,68,173,.18)}

/* ── подтверждение опасной правки ── */
.confirmbox{padding-bottom:18px}
.confirmbox .atext{padding:0 20px;margin:0 0 4px}
/* Перечисление последствий — самое важное на странице, поэтому обычным
   размером тела, а не подписью. */
.impact{margin:10px 20px 16px;padding-left:20px;color:var(--text-2);
  font-size:var(--fs-b);line-height:1.6}
.impact li{margin:4px 0}
.confirm-actions{display:flex;align-items:center;gap:10px;padding:0 20px}
.dangerbtn{
  display:inline-flex;align-items:center;padding:8px 16px;border-radius:9px;
  border:1px solid #B8253A;background:var(--hot);color:#fff;
  font:inherit;font-size:var(--fs-c);font-weight:600;cursor:pointer;
}
.dangerbtn:hover{background:#B8253A}
.dangerbtn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(210,47,69,.28)}

@media (max-width:860px){
  .setgroup th:nth-child(2),.setgroup td:nth-child(2),
  .setgroup th:nth-child(3),.setgroup td:nth-child(3){width:auto}
  .setinfo summary,.setmore{max-width:none}
}

/* Вводный блок страницы настроек. .chart-note сверстан как подпись ПОД
   заголовком карточки, и без своего отступа текст упирается в верхний край
   панели: заголовка здесь нет. */
.setintro .chart-note{padding:14px 20px}

/* ── Карточка группы (/group/{id}) ── */
/* Ссылка на карточку группы поверх .g-name — своего hover-цвета у обычного
   <a> внутри таблицы нет (a{color:inherit} сбрасывает всё), а у .crow он
   уже есть через .crow:hover .cname. */
.g-name a:hover{color:var(--indigo)}

.groupinfo .card-head{padding-bottom:4px}
.ginfo-badges{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:2px 20px 10px}

/* Текст состояния группы — свой контейнер, а не переиспользованный .atext:
   тот сверстан как .arow .atext / .confirmbox .atext, то есть завязан на
   родителя, которого здесь нет, и голый class="atext" не получил бы вообще
   никакого стиля (см. ловушку с .chip в CLAUDE.md — те же грабли). */
.groupbody{padding:2px 20px 16px}
.groupbody p{margin:0 0 8px;font-size:var(--fs-b);line-height:1.55;color:var(--text)}
.groupbody p:last-child{margin-bottom:0}
.groupbody p.cap{line-height:1.5}

/* Кнопки «Снять с контроля» и «Вернуть в контроль» с пояснением рядом.
   .setbtn взят целиком, без переопределения свойств: за частичное
   переопределение класса макета уже платили (.prioset .chip — белый текст
   на белом фоне). Свой класс только на раскладку строки. */
.muteform{display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  padding:4px 20px 16px}
.muteform .cap{flex:1;min-width:220px;line-height:1.45}

.msglist{padding:4px 20px 16px;display:flex;flex-direction:column;gap:2px}
.msgline{padding:8px 0;border-bottom:1px solid var(--line-2)}
.msgline:last-child{border-bottom:0}
/* Сообщение-основание вывода (Red Flag или group_dialog_state.basis_message_id) —
   подсвечено, чтобы результат можно было проверить взглядом (п. 7 CLAUDE.md). */
.msgline.basis{background:var(--indigo-bg);border-radius:8px;padding:8px 10px;
  margin:0 -10px}
.msg-meta{display:flex;align-items:baseline;gap:8px;margin-bottom:2px}
.msg-time{font-size:var(--fs-c);color:var(--faint);font-variant-numeric:tabular-nums;
  white-space:nowrap}
/* Сторона — наша (KAM, сотрудник из whitelist) или клиентская. Разными
   насыщенностью и цветом, а не подписью рядом с именем: имя само по себе
   («Саида» и «Maksim») не говорит, кто есть кто, а легенда сверху не
   нужна, если стороны видно с первого взгляда. */
.msg-sender{font-size:var(--fs-c)}
.msg-sender.us{font-weight:700;color:var(--text)}
.msg-sender.client{font-weight:500;color:var(--calm)}
.msg-text{font-size:var(--fs-b);line-height:1.55;color:var(--text);white-space:pre-wrap;
  overflow-wrap:break-word}
.msg-reply{font-size:var(--fs-c);color:var(--muted);border-left:2px solid var(--line);
  padding-left:8px;margin:2px 0 4px}

/* Назначение ответственного на странице «Группы». Выбор KAM в строке — тот
   же свой компонент, что выбор приоритета (.priopick / .priomenu), целиком и
   без переопределений. Ниже — только то, чего у него нет. */
.kamcell .kamnote{display:block;margin-top:3px}
td.kam .kamnote{display:block;margin-top:3px}
.selcell{width:34px;text-align:center}
.selcell input{width:16px;height:16px;cursor:pointer;accent-color:var(--indigo)}
/* Панель массового назначения — отдельная строка под поиском. Галочки в
   строках таблицы привязаны к этой форме атрибутом form=: вложенных форм не
   бывает, а JS здесь нет. */
.bulkbar{padding:10px 20px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  border-bottom:1px solid var(--line-2);background:#FAFBFD}
.bulklabel{font-size:var(--fs-c);color:var(--muted)}

/* Статус личных подсказок на «Сотрудниках». Свой класс, а не .ctime.warn из
   макета: частичное переопределение чужих классов уже давало белый текст на
   белом (см. ловушку про .chip в CLAUDE.md). */
.dmwarn{color:var(--warm)}

/* Баннер сбоя API Anthropic — сверху каждой страницы, красным. Свой блок,
   не переопределение чужих классов (см. ловушку про .chip). */
.api-banner{
  background:var(--hot);color:#fff;padding:10px 32px;font-size:var(--fs-b);
  font-weight:500;line-height:1.45;
}
.api-banner div+div{margin-top:4px}
.usage-cards{grid-template-columns:repeat(2,1fr)}
.usage-note{padding:0 4px;line-height:1.5}
@media (max-width:760px){
  .api-banner{padding:10px 16px}
  .usage-cards{grid-template-columns:1fr}
}
