/* Фирменный стиль «Точки Сборки» — тот, что заказчик видел в КП.
 *
 * Шрифты лежат файлами в `static/fonts/`, а не берутся из сети. Довода два, и
 * оба несущие. Первый: страница показывает персональные данные, и запрос за
 * шрифтом на чужой домен сообщал бы этому домену, кто и когда открыл карточку
 * клиента, — ровно поэтому htmx тоже положен файлом. Второй: система стоит на
 * сервере заказчика и обязана работать без интернета.
 *
 * Начертаний ровно три: Inter Regular и Semibold для текста, JetBrains Mono
 * Regular для чисел. Больше не берём — каждое лишнее весит и не используется.
 *
 * Подмножеств три на начертание, и `latin-ext` здесь не роскошь: знак рубля
 * (U+20BD) лежит именно в нём. Без него «1 200 ₽» отрисовалось бы двумя
 * шрифтами сразу — числа фирменным, рубль системным.
 *
 * `font-display: swap` — текст виден сразу системным шрифтом и подменяется,
 * когда файл доедет. Иначе при холодном кэше страница на мгновение пуста, и
 * это читается как «не загрузилось».
 */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/inter-latin-400-normal.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+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/inter-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/inter-cyrillic-400-normal.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/inter-latin-600-normal.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+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/inter-latin-ext-600-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/inter-cyrillic-600-normal.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-latin-400-normal.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+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-cyrillic-400-normal.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

:root {
  --fon: #f6f6f8;
  --kartochka: #fff;
  --sinii: #111a4a;
  --seryi: #7c7f88;
  --razdelitel: #e3e4e8;
  --akcent: #ec652b;
  --dengi: #167e6c;
  --radius: 8px;
  /* Запасной стек полный и по системам: если файл не доехал (или доехал
   * не весь — подмножества грузятся по мере надобности), страница
   * остаётся читаемой везде, а не только на машине разработчика. */
  --tekst: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
  --chisla: 'JetBrains Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo,
    Consolas, 'Liberation Mono', 'Courier New', monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fon);
  color: var(--sinii);
  font-family: var(--tekst);
  font-size: 15px;
  line-height: 1.5;
}

a { color: var(--sinii); text-decoration: none; }
a:hover { text-decoration: underline; }

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

.shapka {
  background: var(--kartochka);
  border-bottom: 1px solid var(--razdelitel);
  padding: 0 24px;
  display: flex;
  align-items: center;
  gap: 28px;
  height: 56px;
}

.shapka .znak { font-weight: 600; letter-spacing: .12em; font-size: 14px; }
.shapka nav { display: flex; gap: 22px; flex: 1; }
.shapka nav a { color: var(--seryi); font-size: 14px; }
.shapka nav a.zdes { color: var(--sinii); font-weight: 600; }
.shapka .kto { color: var(--seryi); font-size: 13px; }

/* --- сетка ---------------------------------------------------------------- */

main { max-width: 1080px; margin: 0 auto; padding: 28px 24px 64px; }

h1 { font-size: 22px; margin: 0 0 4px; font-weight: 600; }
h2 { font-size: 15px; margin: 0 0 12px; font-weight: 600; }
.podpis { color: var(--seryi); font-size: 13px; margin: 0 0 22px; }

.karta {
  background: var(--kartochka);
  border: 1px solid var(--razdelitel);
  border-radius: var(--radius);
  padding: 18px 20px;
  margin-bottom: 16px;
}

.dvumya { display: grid; grid-template-columns: 1.4fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 820px) { .dvumya { grid-template-columns: 1fr; } }

/* --- строки списков ------------------------------------------------------- */

.stroka {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--razdelitel);
}
.stroka:last-child { border-bottom: none; }
.stroka .glavnoe { flex: 1; }
.stroka .sboku { color: var(--seryi); font-size: 13px; text-align: right; }

.chislo { font-family: var(--chisla); font-variant-numeric: tabular-nums; }
.tiho { color: var(--seryi); }
.dengi { color: var(--dengi); font-family: var(--chisla); }
.pusto { color: var(--seryi); padding: 18px 0; }

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

.metka {
  display: inline-block;
  font-size: 12px;
  padding: 1px 8px;
  border-radius: 20px;
  border: 1px solid var(--razdelitel);
  color: var(--seryi);
}
.metka.svobodno { color: var(--dengi); border-color: #bfe0d8; }
/* Приглушённый оттенок акцента, а не сам акцент. Оранжевым красится действие,
 * и ровно одно на экран; состояние, покрашенное тем же цветом, съедает акцент —
 * при полном клубе экран недели становился оранжевым целиком. */
.metka.net-mest { color: #a8461a; border-color: #e6d3c9; background: #fbf3ef; }
.metka.otmeneno { text-decoration: line-through; }
.zacherknuto { text-decoration: line-through; color: var(--seryi); }

/* --- поля и кнопки -------------------------------------------------------- */

input[type=text], input[type=password], input[type=search], input[type=date] {
  font: inherit;
  padding: 9px 12px;
  border: 1px solid var(--razdelitel);
  border-radius: var(--radius);
  background: var(--kartochka);
  color: var(--sinii);
  width: 100%;
}
input:focus { outline: 2px solid var(--sinii); outline-offset: -1px; }

button {
  font: inherit;
  font-size: 14px;
  padding: 8px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--razdelitel);
  background: var(--kartochka);
  color: var(--sinii);
  cursor: pointer;
}
button:hover { border-color: var(--seryi); }

/* Акцент — один на экран. Оранжевым красится то действие, ради которого экран
 * открыли, и только оно: второй оранжевой кнопкой акцент перестаёт быть
 * акцентом и превращается в шум. */
button.glavnaya {
  background: var(--akcent);
  border-color: var(--akcent);
  color: #fff;
  font-weight: 600;
}
button.glavnaya:hover { filter: brightness(1.06); }
button.tihaya { color: var(--seryi); border-color: transparent; padding: 4px 8px; }
button.tihaya:hover { color: var(--sinii); border-color: var(--razdelitel); }
button[disabled] { color: var(--seryi); cursor: default; background: var(--fon); }

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

.vhod { max-width: 340px; margin: 96px auto; }
.vhod .karta { padding: 26px 24px; }
.vhod label { display: block; font-size: 13px; color: var(--seryi); margin: 14px 0 5px; }
.vhod button { width: 100%; margin-top: 20px; }

/* --- формы ввода ---------------------------------------------------------- */

/* Полоса чтения у формы уже, чем у списка: строка ввода во всю ширину экрана
 * читается как поле поиска, а не как «сюда вписывают фамилию». */
.forma { max-width: 460px; }
.forma label { display: block; font-size: 13px; color: var(--seryi); margin: 16px 0 5px; }
.forma label:first-of-type { margin-top: 0; }
.forma input { width: 100%; }
/* Подсказка под полем — часть поля, а не абзац текста после него. */
.forma .tiho { font-size: 12px; margin: 6px 0 0; }
.forma button { margin-top: 22px; }
.forma .otmena { margin-left: 14px; color: var(--seryi); font-size: 14px; }

/* Действие над разделом: ссылка, ведущая на форму, а не пункт списка. */
.deystviya { margin: 0 0 16px; }
a.knopkoy {
  display: inline-block;
  padding: 7px 14px;
  border: 1px solid var(--razdelitel);
  border-radius: var(--radius);
  background: var(--kartochka);
  font-size: 14px;
}
a.knopkoy:hover { border-color: var(--seryi); text-decoration: none; }

/* Отмена записи и снятие отметки стоят рядом с «Пришёл» и обязаны читаться
 * как второстепенные: главное действие экрана одно. */
.ryadom { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.ryadom + .ryadom { margin-top: 6px; }
/* Выбор причины в строке списка — узкий: он не поле ввода, а список из
 * нескольких слов, и во всю ширину строки читается как главное на ней. */
.ryadom select {
  max-width: 180px;
  padding: 4px 6px;
  border: 1px solid var(--razdelitel);
  border-radius: var(--radius);
  background: var(--kartochka);
  font: inherit;
  font-size: 13px;
  color: inherit;
}

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

.beda {
  border: 1px solid #f7cdb9;
  background: #fdf3ee;
  color: var(--sinii);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 16px;
  font-size: 14px;
}
.beda .nomer { color: var(--seryi); font-family: var(--chisla); font-size: 12px; }

.den { margin-top: 22px; }
.den h2 { color: var(--seryi); font-weight: 600; text-transform: uppercase;
          letter-spacing: .06em; font-size: 12px; }
/* Сегодняшний день выделен, потому что расписание открывают ради него.
 * Без этого перелистнувший на две недели вперёд не видел, где он находится. */
.den.segodnya h2 { color: var(--sinii); }
.den .pusto { padding: 4px 0 0; }

/* Переключатель недели — орган управления, а не подпись под заголовком. */
.perelistat { display: flex; align-items: center; gap: 16px; margin: 0 0 8px; }
.perelistat a { padding: 6px 12px; border: 1px solid var(--razdelitel);
                border-radius: var(--radius); background: var(--kartochka); }
.perelistat a:hover { border-color: var(--seryi); text-decoration: none; }

/* Страница отказа и сбоя: одна мысль по центру полосы чтения. */
.odna-mysl { max-width: 460px; margin: 48px auto; }
.nomer-zaprosa { color: var(--seryi); font-size: 13px; }

/* Принятое действие. Зелёным, а не тем же цветом, что беда: администратор
 * принимает заявки подряд, и различать «принято» и «не вышло» он должен
 * периферийным зрением, не вчитываясь. */
.prinyato {
  border: 1px solid #bfe0d8;
  background: #f1f8f6;
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 16px;
  font-size: 14px;
}

/* Выпадающий список в форме — тех же размеров, что поля ввода рядом. Без этого
 * он садится на строку иначе, и форма читается как собранная из двух разных. */
.forma select {
  width: 100%;
  font: inherit;
  padding: 8px 10px;
  border: 1px solid var(--razdelitel);
  border-radius: var(--radius);
  background: var(--kartochka);
  color: var(--sinii);
}
.forma select:focus { outline: 2px solid var(--sinii); outline-offset: -1px; }
/* Заголовок блока внутри формы: разделяет «кто», «что просят» и «откуда
 * узнали». Разделение несущее — см. шапку `apps/web/zayavki.py`. */
.forma h2 { margin: 0 0 10px; }
.forma h2.vtoraya {
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--razdelitel);
}

/* --- переписка ------------------------------------------------------------ */

/* Метка источника — первое, что читают в ленте: она отвечает «куда отвечать».
 * Поэтому она стоит перед именем и набрана моноширинным: коды каналов
 * сравнивают глазами, пробегая список сверху вниз. */
.metka.istochnik {
  font-family: var(--chisla);
  font-size: 11px;
  letter-spacing: .02em;
}

/* Счётчик непрочитанного. Акцентным, а не серым: это единственное число в
 * ленте, по которому решают, чем заняться следующим. */
.neprochitano {
  display: inline-block;
  min-width: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: var(--akcent);
  color: #fff;
  font-size: 12px;
  text-align: center;
}

.poyasnenie.razbor { color: #a8461a; }

/* Ссылка рядом с кнопкой действия: ведёт в соседний экран, а не выполняет
 * действие, и потому не спорит с оранжевой кнопкой за внимание. */
.tihaya-ssylka { color: var(--seryi); font-size: 13px; margin-left: 14px; }

.soobshchenie { padding: 10px 0; border-bottom: 1px solid var(--razdelitel); }
.soobshchenie:last-child { border-bottom: none; }
.soobshchenie .sboku { display: block; color: var(--seryi); font-size: 12px; }
/* Перенос по словам обязателен: в сообщении бывает ссылка без пробелов, и без
 * этого она растягивает половину страницы, ломая сетку. */
.soobshchenie .tekst { margin: 3px 0 0; overflow-wrap: anywhere; }
/* Своё и чужое различаются отступом, а не цветом: цветом здесь уже размечены
 * деньги и отказы, и пятый смысл у цвета читаться перестаёт. */
.soobshchenie.nashe { padding-left: 28px; }
.soobshchenie.nashe .tekst { color: var(--seryi); }

/* --- отчёты --------------------------------------------------------------- */

/* Выбор периода — орган управления страницей, поэтому в строку и над картами. */
.period {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 20px;
  flex-wrap: wrap;
}
.period label { color: var(--seryi); font-size: 13px; }
.period button { margin: 0; }
/* Ширину полю задаём здесь: общее правило полей ставит `width: 100%`, и в
 * строке выбора периода два таких поля занимают по целой строке каждое —
 * форма из трёх элементов разваливается на три этажа. Проверено глазами на
 * живой базе, а не по разметке. */
.period input[type=date] { width: auto; min-width: 170px; }

.tablica { width: 100%; border-collapse: collapse; font-size: 14px; }
.tablica th {
  text-align: left;
  font-weight: 600;
  font-size: 12px;
  color: var(--seryi);
  text-transform: uppercase;
  letter-spacing: .05em;
  padding: 0 10px 8px 0;
  border-bottom: 1px solid var(--razdelitel);
  white-space: nowrap;
}
.tablica td { padding: 9px 10px 9px 0; border-bottom: 1px solid var(--razdelitel); }
.tablica tbody tr:last-child td { border-bottom: none; }
/* Числа выровнены по правому краю и набраны моноширинным: столбец, в котором
 * разряды не стоят друг под другом, сравнивать глазами нельзя, а отчёт ровно
 * для этого и открывают. */
/* Отступ слева, а не обнулённый справа. Обнулённый прижимал число к
 * следующему столбцу вплотную, и на экране каналов «ОТКАЗОВ» слиплось с
 * «ПОСЛЕДНЕЕ ВХОДЯЩЕЕ», а 7 — с датой. В отчётах это не всплывало: там
 * числовой столбец всегда последний. Найдено живой пробой. */
.tablica .k-chislu { text-align: right; padding-left: 18px; white-space: nowrap; }
.tablica tfoot td {
  padding-top: 10px;
  border-top: 1px solid var(--razdelitel);
  font-weight: 600;
}
/* Служебная строка воронки объясняет себя прямо в таблице: «без заявки» без
 * пояснения читается как пропуск в данных, а это ответ. */
.poyasnenie { display: block; color: var(--seryi); font-size: 12px; }
h2.vtoraya { margin-top: 26px; }

/* Возвращаемость — три числа, а не таблица: строк у неё не бывает. */
.chisla-vryad { display: flex; gap: 40px; flex-wrap: wrap; }
.odno-chislo { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.odno-chislo .velichina { font-size: 26px; line-height: 1.2; }

/* Обрезание предела — не «тихая» подпись: обрезанная таблица занижает числа,
 * по которым принимают решение, и выглядит при этом полной. */
.obrezano {
  margin: 14px 0 0;
  font-size: 13px;
  color: #a8461a;
}

@media (max-width: 620px) {
  /* Шапка без переноса давала горизонтальную прокрутку на всех экранах сразу:
   * «КЛАН» + два пункта меню + логин + «Выйти» в 375px не помещаются. */
  .shapka { height: auto; flex-wrap: wrap; gap: 14px; padding: 10px 16px; }
  .shapka nav { flex: 1 0 100%; gap: 16px; }
  main { padding: 20px 16px 48px; }
  /* Имя и метка в одну строку на узком экране сминались в лапшу. */
  .stroka { flex-wrap: wrap; }
  .stroka .sboku { text-align: left; }
  .perelistat { flex-wrap: wrap; gap: 10px; }
  /* Таблицы отчётов шире 375px по построению — семь столбцов чисел. Прокрутка
   * внутри карты, а не всей страницы: иначе уезжает и шапка, и соседний
   * раздел, и найти в таком виде нужный столбец нельзя. */
  .karta { overflow-x: auto; }
  .chisla-vryad { gap: 22px; }
}

/* === Окно 2: заявки, воронка, задачи, люди, сотрудники, настройки ========= */
/* Фильтры окна заявок — в ряд, на узком экране переносятся. */
.zay-filtry { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.zay-filtry label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--seryi); }
.zay-filtry select, .zay-filtry input[type=search] { min-width: 140px; }
/* Таблица шире узкого экрана — прокрутка внутри карты, а не всей страницы. */
.zay-tablica { overflow-x: auto; }
/* Воронка: колонки в ряд с прокруткой внутри доски. Колонка узкая, но не
 * сжимается до нечитаемого: на 390px видна одна с краем следующей. */
.zay-voronka { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px; }
/* На широком экране доска выходит за общую ширину страницы: шесть колонок
 * в 1100px не читаются. Колонки делят ширину поровну, но не уже 200px; пустая —
 * узкая, ей нечего показывать. Не влезло (узкий экран) — прокрутка доски. */
main:has(.zay-voronka) { max-width: none; }
.zay-kolonka {
  flex: 1 1 0;
  min-width: 200px;
  background: var(--kartochka);
  border: 1px solid var(--razdelitel);
  border-radius: var(--radius);
  padding: 12px;
}
.zay-kolonka h2 { font-size: 14px; margin: 0 0 10px; }
.zay-kolonka.zay-pustaya { flex: 0 0 130px; min-width: 130px; }
.zay-prokrutka { display: none; }
@media (max-width: 1320px) { .zay-prokrutka { display: block; } }
.zay-karta {
  border: 1px solid var(--razdelitel);
  border-radius: var(--radius);
  padding: 8px 10px;
  margin-bottom: 8px;
}
.zay-dalshe { display: inline-block; margin: 6px 6px 0 0; }
/* Срок шага заявки (16.10): просроченный — красным и словами «просрочено на …». */
.zay-karta > span { display: block; }
.zay-srok { font-size: 13px; color: var(--seryi); }
.zay-prosrocheno { font-size: 13px; font-weight: 600; color: var(--oshibka, #b42318); }
.zay-karta.zay-karta-prosrochena { border-left: 3px solid var(--oshibka, #b42318); }
/* Перетаскивание по воронке (`static/voronka.js`): куда можно бросить —
 * пунктирной рамкой, а не только цветом. */
.zay-karta[draggable="true"] { cursor: grab; }
.zay-mozhno { outline: 2px dashed var(--akcent, #4a7fc1); outline-offset: 2px; }
@media (max-width: 620px), (pointer: coarse) { .zay-podskazka { display: none; } }
.zay-perehod { margin-bottom: 14px; }
/* Просроченная задача — полосой слева, а не красным текстом: срок и метка
 * «просрочена» уже говорят словами, полоса лишь ловит глаз в длинном списке. */
.zay-prosrochena { border-left: 3px solid #e6d3c9; padding-left: 8px; }
.zay-zadacha { margin-top: 16px; }
/* Чипы меток на списке людей переносятся; выбранная — залитой. */
.zay-metki { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.zay-metki a.metka { text-decoration: none; }
.metka.zay-vybrana { background: var(--sinii); border-color: var(--sinii); color: #fff; }
/* Настройки: выключенная учётка бледнее, действия над учёткой — в ряд. */
.nas-vyklyuchen { opacity: .6; }
.nas-deystvie { display: inline-flex; gap: 6px; align-items: center; margin: 4px 0 0 6px; }
.nas-deystvie select { max-width: 180px; }
/* Выданный пароль — крупно и с разрядкой: его диктуют и переписывают руками. */
.nas-parol { font-size: 20px; letter-spacing: .08em; user-select: all; }
.nas-prava { display: flex; flex-wrap: wrap; gap: 6px; }
/* Правка строки справочника на месте: поля в ряд, на узком экране переносятся. */
.nas-pravka { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.nas-pravka input[type=text] { width: auto; min-width: 0; flex: 1 1 160px; }
.nas-pravka input.nas-chislo { flex: 0 0 72px; }

/* ===== Окно 4: Сегодня, лояльность, рассылки, переписка, выгрузки ===== */

/* То, что требует действия сегодня: неотмеченные визиты, просроченные задачи.
 * Цвет тот же, что у обрезания выборки: оба сигнала — «здесь не всё в порядке». */
.seg-gorit { color: #a8461a; font-weight: 600; }

/* Вкладки лояльности: скидки, сертификаты, отзывы — каждая по своему праву. */
/* Вкладки раздела — одним видом везде: отчёты, лояльность, отборы абонементов.
 * Выбранная — обведена тёмным; цель нажатия — не меньше 36px. */
.vkladki, .loy-vkladki { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 16px; }
.vkladki a, .loy-vkladki a {
  display: inline-flex; align-items: center; min-height: 36px;
  padding: 5px 14px; border: 1px solid var(--razdelitel); border-radius: 999px;
  color: var(--seryi); font-size: 14px; text-decoration: none;
}
.vkladki a:hover, .loy-vkladki a:hover { border-color: var(--seryi); }
.vkladki a.zdes, .loy-vkladki a.zdes { color: var(--sinii); border-color: var(--sinii); font-weight: 600; }
/* Ответ на просьбу об отзыве — в одну строку с кнопкой, на узком экране переносится. */
.loy-otvet { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
/* Текст куска корпуса — как есть, с переносами строк источника. */
.korpus-tekst { white-space: pre-wrap; }
/* Печатная форма согласия: текст редакции как есть, с переносами строк.
 * При печати убираются шапка и ссылки — на бумаге только согласие. */
.soglasie-pechat { white-space: pre-wrap; font-family: inherit; font-size: 15px; line-height: 1.5; }
@media print {
  .shapka, .soglasie-ne-pechatat { display: none; }
  main { padding: 0; }
}

/* ===== Окно 1: календарь расписания ===== */

/* Положение блоков — классами, а не `style="…"`: политика содержимого
 * запрещает встроенные стили. Строка сетки — четверть часа высотой 18px (час —
 * 72px: в часовом блоке помещаются время, название, тип и зал — при 48px
 * строки наползали друг на друга, 16.10); номера `kal-r*`/`kal-h*` покрывают сутки (96 строк), `kal-x*`/`kal-w*` —
 * двенадцать долей колонки. Пределы совпадают с `apps/web/kalendar.py`, это
 * сторожит тест. */
/* Цвета — общими переменными вида (`vid.css`, записка окна 6) с прежним
 * значением запасным: без `vid.css` календарь выглядит как раньше, а не
 * бесцветно. */
.kal-upravlenie { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px;
                  margin: 12px 0 14px; }
.kal-upravlenie .perelistat { margin: 0; position: relative; }
.kal-period { font-weight: 600; cursor: pointer; border-bottom: 1px dashed var(--seryi); }
.kal-vidy { display: flex; border: none; box-shadow: var(--ten, none); border-radius: var(--radius-karta, var(--radius));
            overflow: hidden; background: var(--kartochka); }
.kal-vidy a { padding: 6px 12px; font-size: 14px; }
.kal-vidy a + a { border-left: 1px solid var(--razdelitel); }
.kal-vidy a.vybran { background: var(--akcent); color: #fff; }

/* Фильтры — три выпадающих списка в строку (как в Яндексе), а не чипы: чипы
 * занимали полэкрана, на телефоне — десять строк до первой клетки сетки.
 * Выбранный фильтр отмечен рамкой акцента: сразу видно, что сетка сужена. */
.kal-filtry { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; flex: 1 0 100%; }
.kal-filtry select { font: inherit; font-size: 14px; min-height: 32px; padding: 0 10px;
                     border: 1px solid var(--razdelitel); border-radius: var(--radius);
                     background: var(--kartochka); color: var(--sinii); max-width: 220px; }
.kal-filtry select.vybran { border-color: var(--akcent); color: var(--akcent-tekst, var(--akcent)); }
.kal-data-pole { width: auto; font: inherit; padding: 4px 8px; border: 1px solid var(--razdelitel);
                 border-radius: var(--radius); background: var(--kartochka); color: var(--sinii); }

/* Со скриптом (`static/kalendar.js` ставит `kal-js` на страницу) кнопка
 * «Показать» не нужна — форма уходит сама, — а поле даты остаётся в документе,
 * но невидимым под заголовком периода: `showPicker()` открывает выбор только у
 * отрисованного поля, поэтому `display: none` здесь нельзя. */
.kal-js .kal-bez-js { display: none; }
.kal-js .kal-data-pole { position: absolute; right: 0; bottom: 0; width: 1px; height: 1px;
                         opacity: 0; pointer-events: none; }

.kal-telo { display: flex; gap: 16px; align-items: flex-start; }
.kal-oblast { flex: 1; min-width: 0; overflow-x: auto; }
.kal-panel { width: 380px; flex: none; background: var(--kartochka);
             border: none; box-shadow: var(--ten, 0 0 0 1px var(--razdelitel));
             border-radius: var(--radius-karta, var(--radius)); padding: 14px 16px; }
/* Липкая и со своей прокруткой: в группе двенадцать детей, и без этого
 * список уводил панель вниз, а сетка с выбранным занятием уезжала вверх. */
.kal-panel { position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto; }
.kal-panel:empty { display: none; }
.kal-panel .dvumya { grid-template-columns: 1fr; }
.kal-panel .karta { padding: 12px 0; border: none; margin: 0; }
/* В панели шириной 380px имя и три кнопки в одну строку не встают: кнопки
 * уходят под имя, а не сминают его в столбик по слогу. */
.kal-panel .stroka { flex-wrap: wrap; }
.kal-panel .stroka .glavnoe { flex: 1 0 100%; }
.kal-panel .stroka .sboku { text-align: left; }
.kal-panel .ryadom { justify-content: flex-start; flex-wrap: wrap; }
.kal-panel-shapka { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }

/* Сетка дня и недели: колонка шкалы и колонки дней (или залов). */
/* Число колонок — классом `kal-kolonok-N` (дни недели или залы плюс «Выезд»):
 * шапки встают первой строкой, тела — второй, обычным потоком. */
.kal-setka { display: grid; min-width: 100%; }
.kal-kolonok-1{grid-template-columns:52px repeat(1,minmax(110px,1fr))} .kal-kolonok-2{grid-template-columns:52px repeat(2,minmax(110px,1fr))} .kal-kolonok-3{grid-template-columns:52px repeat(3,minmax(110px,1fr))}
.kal-kolonok-4{grid-template-columns:52px repeat(4,minmax(110px,1fr))} .kal-kolonok-5{grid-template-columns:52px repeat(5,minmax(110px,1fr))} .kal-kolonok-6{grid-template-columns:52px repeat(6,minmax(110px,1fr))}
.kal-kolonok-7{grid-template-columns:52px repeat(7,minmax(110px,1fr))} .kal-kolonok-8{grid-template-columns:52px repeat(8,minmax(110px,1fr))} .kal-kolonok-9{grid-template-columns:52px repeat(9,minmax(110px,1fr))}
.kal-kolonok-10{grid-template-columns:52px repeat(10,minmax(110px,1fr))} .kal-kolonok-11{grid-template-columns:52px repeat(11,minmax(110px,1fr))} .kal-kolonok-12{grid-template-columns:52px repeat(12,minmax(110px,1fr))}
.kal-shapka-dnya { font-size: 12px; font-weight: 600; text-transform: uppercase;
                   letter-spacing: .06em; color: var(--seryi); padding: 4px 6px; text-align: center; }
.kal-shapka-dnya.segodnya, .kal-shapka-dnya.segodnya a { color: var(--kal-segodnya, var(--akcent)); }
.kal-shkala, .kal-kolonka { display: grid; grid-auto-rows: 18px; grid-template-columns: repeat(12, 1fr); }
.kal-metka-chasa { grid-column: 1 / -1; font-size: 11px; color: var(--seryi);
                   font-family: var(--chisla); margin-top: -8px; padding-right: 6px; text-align: right; }
.kal-kolonka { border-left: 1px solid var(--razdelitel); background: var(--kartochka); }
.kal-kolonka.segodnya { background: var(--kal-segodnya-fon, #fdf6f2); }
.kal-yacheyka { grid-column: 1 / -1; border-top: 1px solid var(--kal-liniya-chasa, var(--razdelitel)); }
.kal-yacheyka.polchasa { border-top: 1px dashed var(--kal-liniya-polchasa, #eeeff2); }
a.kal-yacheyka:hover { background: var(--navedenie, #f1f3f8); text-decoration: none; }

/* Формы занятия: числа и время тех же размеров, что текстовые поля. */
.kal-forma input[type=number], .kal-forma input[type=time] {
  font: inherit; padding: 9px 12px; border: 1px solid var(--razdelitel);
  border-radius: var(--radius); background: var(--kartochka); color: var(--sinii); width: 100%;
}
.kal-forma fieldset { border: none; padding: 0; margin: 14px 0 0; display: flex;
                      flex-wrap: wrap; gap: 8px 16px; align-items: center; }
.kal-forma legend { font-size: 13px; color: var(--seryi); padding: 0; margin-bottom: 4px;
                    float: left; width: 100%; }
.kal-forma .kal-vybor { display: inline-flex; gap: 6px; align-items: center; margin: 0;
                        font-size: 14px; color: var(--sinii); }
.kal-forma .kal-vybor input { width: auto; }
.kal-forma fieldset input[type=date], .kal-forma fieldset input[type=number] { width: auto; }
.kal-ryad { display: grid; grid-template-columns: 1.4fr 1fr 0.8fr; gap: 10px; }
/* Точнее, чем `.forma label:first-of-type`: в ряду каждое поле — первое в своей
 * ячейке, и общее правило снимало им отступ. */
.forma .kal-ryad label { margin-top: 16px; }

.kal-blok { position: relative; z-index: 1; margin: 1px 2px; padding: 2px 5px; overflow: hidden;
            border-radius: 4px; border-left: 4px solid transparent;
            color: var(--kal-tekst-bloka, var(--sinii));
            font-size: 12px; line-height: 1.3; display: flex; flex-direction: column; }
a.kal-blok:hover { text-decoration: none; filter: brightness(.97); }
.kal-blok .kal-stroka1 { display: flex; justify-content: space-between; gap: 4px; overflow: hidden; }
.kal-blok .kal-nazvanie { font-weight: 600; }
.kal-blok .kal-nazvanie, .kal-blok .kal-mesto { white-space: nowrap; overflow: hidden;
                                               text-overflow: ellipsis; }
.kal-blok .kal-vremya, .kal-blok .kal-mesta { font-size: 11px; white-space: nowrap; }
/* Праздник и мероприятие — штриховкой и пунктирной рамкой: это бронь зала под
 * событие, а не регулярная группа, и администратор различает их не вчитываясь. */
.kal-blok.kal-sobytie { background-image: repeating-linear-gradient(135deg,
    transparent 0 6px, rgba(17, 26, 74, .05) 6px 9px);
    outline: 1px dashed rgba(17, 26, 74, .35); outline-offset: -1px; }
/* Отменённое — зачёркнуто и бледно, но читаемо: серый #5a5e67 на #f1f1f3 даёт
 * контраст выше 5:1. Прозрачностью бледнить нельзя — она роняет контраст. */
.kal-blok.kal-otmeneno { background: #f1f1f3; border-left-color: #b9bcc3; color: #5a5e67;
                         text-decoration: line-through; }
.kal-vyezd { display: inline-block; font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
             padding: 0 4px; border: 1px solid currentColor; border-radius: 3px; }

/* Линия «сейчас»: красная, поверх блоков, смещена внутри строки на минуты. */
.kal-seychas { grid-column: 1 / -1; grid-row-end: span 1; height: 2px;
               background: var(--kal-seychas, #d7263d);
               position: relative; z-index: 2; align-self: start; pointer-events: none; }

.kal-seychas.kal-skryto { display: none; }

/* Месяц: семь колонок, клетка — день. */
.kal-mesyac { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
              border-left: 1px solid var(--razdelitel); border-top: 1px solid var(--razdelitel); }
.kal-mesyac .kal-shapka-dnya { border-right: 1px solid var(--razdelitel);
                               border-bottom: 1px solid var(--razdelitel); }
.kal-kletka { min-height: 96px; padding: 4px; background: var(--kartochka);
              border-right: 1px solid var(--razdelitel); border-bottom: 1px solid var(--razdelitel);
              display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kal-kletka.chuzhoy { background: var(--fon); }
.kal-kletka.segodnya .kal-chislo-dnya { color: #fff; background: var(--akcent); border-radius: 10px; }
.kal-chislo-dnya { align-self: flex-start; font-size: 12px; font-family: var(--chisla); padding: 0 6px; }
.kal-kletka .kal-blok { flex-direction: row; gap: 4px; margin: 0; white-space: nowrap; }
/* В клетке месяца строка — время и название; тип словами съедал её, и от
 * названия оставалась одна буква. Тип здесь говорит заливка, а словами — подсказка. */
.kal-kletka .kal-blok .kal-tip { display: none; }
.kal-kletka .kal-blok .kal-nazvanie { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Время в клетке не сжимается: узкая колонка резала «10:00» до «10:0». */
.kal-kletka .kal-blok .kal-stroka1 { flex: none; }
.kal-eshche { font-size: 12px; color: var(--seryi); }

/* «Моё расписание» педагога: день списком. Блоки на всю ширину и крупнее, чем
 * на сетке: список читают с телефона, и тянуться к 12px там не нужно. */
.kal-spisok { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.kal-spisok .kal-blok { margin: 0; padding: 10px 12px; font-size: 14px; }
.kal-spisok .kal-blok .kal-vremya, .kal-spisok .kal-blok .kal-mesta { font-size: 13px; }
.kal-spisok .kal-blok .kal-mesto { white-space: normal; }

.kal-r1{grid-row-start:1} .kal-r2{grid-row-start:2} .kal-r3{grid-row-start:3} .kal-r4{grid-row-start:4} .kal-r5{grid-row-start:5} .kal-r6{grid-row-start:6}
.kal-r7{grid-row-start:7} .kal-r8{grid-row-start:8} .kal-r9{grid-row-start:9} .kal-r10{grid-row-start:10} .kal-r11{grid-row-start:11} .kal-r12{grid-row-start:12}
.kal-r13{grid-row-start:13} .kal-r14{grid-row-start:14} .kal-r15{grid-row-start:15} .kal-r16{grid-row-start:16} .kal-r17{grid-row-start:17} .kal-r18{grid-row-start:18}
.kal-r19{grid-row-start:19} .kal-r20{grid-row-start:20} .kal-r21{grid-row-start:21} .kal-r22{grid-row-start:22} .kal-r23{grid-row-start:23} .kal-r24{grid-row-start:24}
.kal-r25{grid-row-start:25} .kal-r26{grid-row-start:26} .kal-r27{grid-row-start:27} .kal-r28{grid-row-start:28} .kal-r29{grid-row-start:29} .kal-r30{grid-row-start:30}
.kal-r31{grid-row-start:31} .kal-r32{grid-row-start:32} .kal-r33{grid-row-start:33} .kal-r34{grid-row-start:34} .kal-r35{grid-row-start:35} .kal-r36{grid-row-start:36}
.kal-r37{grid-row-start:37} .kal-r38{grid-row-start:38} .kal-r39{grid-row-start:39} .kal-r40{grid-row-start:40} .kal-r41{grid-row-start:41} .kal-r42{grid-row-start:42}
.kal-r43{grid-row-start:43} .kal-r44{grid-row-start:44} .kal-r45{grid-row-start:45} .kal-r46{grid-row-start:46} .kal-r47{grid-row-start:47} .kal-r48{grid-row-start:48}
.kal-r49{grid-row-start:49} .kal-r50{grid-row-start:50} .kal-r51{grid-row-start:51} .kal-r52{grid-row-start:52} .kal-r53{grid-row-start:53} .kal-r54{grid-row-start:54}
.kal-r55{grid-row-start:55} .kal-r56{grid-row-start:56} .kal-r57{grid-row-start:57} .kal-r58{grid-row-start:58} .kal-r59{grid-row-start:59} .kal-r60{grid-row-start:60}
.kal-r61{grid-row-start:61} .kal-r62{grid-row-start:62} .kal-r63{grid-row-start:63} .kal-r64{grid-row-start:64} .kal-r65{grid-row-start:65} .kal-r66{grid-row-start:66}
.kal-r67{grid-row-start:67} .kal-r68{grid-row-start:68} .kal-r69{grid-row-start:69} .kal-r70{grid-row-start:70} .kal-r71{grid-row-start:71} .kal-r72{grid-row-start:72}
.kal-r73{grid-row-start:73} .kal-r74{grid-row-start:74} .kal-r75{grid-row-start:75} .kal-r76{grid-row-start:76} .kal-r77{grid-row-start:77} .kal-r78{grid-row-start:78}
.kal-r79{grid-row-start:79} .kal-r80{grid-row-start:80} .kal-r81{grid-row-start:81} .kal-r82{grid-row-start:82} .kal-r83{grid-row-start:83} .kal-r84{grid-row-start:84}
.kal-r85{grid-row-start:85} .kal-r86{grid-row-start:86} .kal-r87{grid-row-start:87} .kal-r88{grid-row-start:88} .kal-r89{grid-row-start:89} .kal-r90{grid-row-start:90}
.kal-r91{grid-row-start:91} .kal-r92{grid-row-start:92} .kal-r93{grid-row-start:93} .kal-r94{grid-row-start:94} .kal-r95{grid-row-start:95} .kal-r96{grid-row-start:96}
.kal-h1{grid-row-end:span 1} .kal-h2{grid-row-end:span 2} .kal-h3{grid-row-end:span 3} .kal-h4{grid-row-end:span 4} .kal-h5{grid-row-end:span 5} .kal-h6{grid-row-end:span 6}
.kal-h7{grid-row-end:span 7} .kal-h8{grid-row-end:span 8} .kal-h9{grid-row-end:span 9} .kal-h10{grid-row-end:span 10} .kal-h11{grid-row-end:span 11} .kal-h12{grid-row-end:span 12}
.kal-h13{grid-row-end:span 13} .kal-h14{grid-row-end:span 14} .kal-h15{grid-row-end:span 15} .kal-h16{grid-row-end:span 16} .kal-h17{grid-row-end:span 17} .kal-h18{grid-row-end:span 18}
.kal-h19{grid-row-end:span 19} .kal-h20{grid-row-end:span 20} .kal-h21{grid-row-end:span 21} .kal-h22{grid-row-end:span 22} .kal-h23{grid-row-end:span 23} .kal-h24{grid-row-end:span 24}
.kal-h25{grid-row-end:span 25} .kal-h26{grid-row-end:span 26} .kal-h27{grid-row-end:span 27} .kal-h28{grid-row-end:span 28} .kal-h29{grid-row-end:span 29} .kal-h30{grid-row-end:span 30}
.kal-h31{grid-row-end:span 31} .kal-h32{grid-row-end:span 32} .kal-h33{grid-row-end:span 33} .kal-h34{grid-row-end:span 34} .kal-h35{grid-row-end:span 35} .kal-h36{grid-row-end:span 36}
.kal-h37{grid-row-end:span 37} .kal-h38{grid-row-end:span 38} .kal-h39{grid-row-end:span 39} .kal-h40{grid-row-end:span 40} .kal-h41{grid-row-end:span 41} .kal-h42{grid-row-end:span 42}
.kal-h43{grid-row-end:span 43} .kal-h44{grid-row-end:span 44} .kal-h45{grid-row-end:span 45} .kal-h46{grid-row-end:span 46} .kal-h47{grid-row-end:span 47} .kal-h48{grid-row-end:span 48}
.kal-h49{grid-row-end:span 49} .kal-h50{grid-row-end:span 50} .kal-h51{grid-row-end:span 51} .kal-h52{grid-row-end:span 52} .kal-h53{grid-row-end:span 53} .kal-h54{grid-row-end:span 54}
.kal-h55{grid-row-end:span 55} .kal-h56{grid-row-end:span 56} .kal-h57{grid-row-end:span 57} .kal-h58{grid-row-end:span 58} .kal-h59{grid-row-end:span 59} .kal-h60{grid-row-end:span 60}
.kal-h61{grid-row-end:span 61} .kal-h62{grid-row-end:span 62} .kal-h63{grid-row-end:span 63} .kal-h64{grid-row-end:span 64} .kal-h65{grid-row-end:span 65} .kal-h66{grid-row-end:span 66}
.kal-h67{grid-row-end:span 67} .kal-h68{grid-row-end:span 68} .kal-h69{grid-row-end:span 69} .kal-h70{grid-row-end:span 70} .kal-h71{grid-row-end:span 71} .kal-h72{grid-row-end:span 72}
.kal-h73{grid-row-end:span 73} .kal-h74{grid-row-end:span 74} .kal-h75{grid-row-end:span 75} .kal-h76{grid-row-end:span 76} .kal-h77{grid-row-end:span 77} .kal-h78{grid-row-end:span 78}
.kal-h79{grid-row-end:span 79} .kal-h80{grid-row-end:span 80} .kal-h81{grid-row-end:span 81} .kal-h82{grid-row-end:span 82} .kal-h83{grid-row-end:span 83} .kal-h84{grid-row-end:span 84}
.kal-h85{grid-row-end:span 85} .kal-h86{grid-row-end:span 86} .kal-h87{grid-row-end:span 87} .kal-h88{grid-row-end:span 88} .kal-h89{grid-row-end:span 89} .kal-h90{grid-row-end:span 90}
.kal-h91{grid-row-end:span 91} .kal-h92{grid-row-end:span 92} .kal-h93{grid-row-end:span 93} .kal-h94{grid-row-end:span 94} .kal-h95{grid-row-end:span 95} .kal-h96{grid-row-end:span 96}
.kal-x1{grid-column-start:1} .kal-x2{grid-column-start:2} .kal-x3{grid-column-start:3} .kal-x4{grid-column-start:4} .kal-x5{grid-column-start:5} .kal-x6{grid-column-start:6}
.kal-x7{grid-column-start:7} .kal-x8{grid-column-start:8} .kal-x9{grid-column-start:9} .kal-x10{grid-column-start:10} .kal-x11{grid-column-start:11} .kal-x12{grid-column-start:12}
.kal-w2{grid-column-end:span 2} .kal-w3{grid-column-end:span 3} .kal-w4{grid-column-end:span 4} .kal-w6{grid-column-end:span 6} .kal-w12{grid-column-end:span 12}
.kal-o0{margin-top:0px} .kal-o1{margin-top:1.2px} .kal-o2{margin-top:2.4px} .kal-o3{margin-top:3.6px} .kal-o4{margin-top:4.8px}
.kal-o5{margin-top:6px} .kal-o6{margin-top:7.2px} .kal-o7{margin-top:8.4px} .kal-o8{margin-top:9.6px} .kal-o9{margin-top:10.8px}
.kal-o10{margin-top:12px} .kal-o11{margin-top:13.2px} .kal-o12{margin-top:14.4px} .kal-o13{margin-top:15.6px} .kal-o14{margin-top:16.8px}
/* Палитра календаря (решение 16.10): двенадцать светлых заливок, текст блока тёмный
 * (`--kal-tekst-bloka` на любой из них даёт контраст выше 7:1). Заливка по типу — `kal-t*`, по залу —
 * `kal-zf*`; полоса слева по залу — `kal-z*`, по типу — `kal-ts*`. Полосы объявлены ниже
 * заливок и потому перекрывают их цвет края: класс полосы задаёт край, класс заливки — фон. */
.kal-t0,.kal-zf0{background:var(--napravlenie-1,#e6f0fb);border-left-color:var(--napravlenie-1-kraj,#4a7fc1)}
.kal-t1,.kal-zf1{background:var(--napravlenie-2,#e7f5ee);border-left-color:var(--napravlenie-2-kraj,#3f9a6e)}
.kal-t2,.kal-zf2{background:var(--napravlenie-3,#fdf0e3);border-left-color:var(--napravlenie-3-kraj,#d08a3c)}
.kal-t3,.kal-zf3{background:var(--napravlenie-4,#f3ebfa);border-left-color:var(--napravlenie-4-kraj,#8a5cc0)}
.kal-t4,.kal-zf4{background:var(--napravlenie-5,#fbe9ee);border-left-color:var(--napravlenie-5-kraj,#c4566f)}
.kal-t5,.kal-zf5{background:var(--napravlenie-6,#e5f4f6);border-left-color:var(--napravlenie-6-kraj,#3a9aa8)}
.kal-t6,.kal-zf6{background:var(--napravlenie-7,#f6f3dd);border-left-color:var(--napravlenie-7-kraj,#a89a2e)}
.kal-t7,.kal-zf7{background:var(--napravlenie-8,#eceff3);border-left-color:var(--napravlenie-8-kraj,#6b7b8f)}
.kal-t8,.kal-zf8{background:var(--napravlenie-9,#f9ece6);border-left-color:var(--napravlenie-9-kraj,#b9674a)}
.kal-t9,.kal-zf9{background:var(--napravlenie-10,#e9f0e1);border-left-color:var(--napravlenie-10-kraj,#6d914a)}
.kal-t10,.kal-zf10{background:var(--napravlenie-11,#fff3cf);border-left-color:var(--napravlenie-11-kraj,#c08f00)}
.kal-t11,.kal-zf11{background:var(--napravlenie-12,#e9eafb);border-left-color:var(--napravlenie-12-kraj,#5b63c9)}
.kal-z0,.kal-ts0{border-left-color:var(--napravlenie-1-kraj,#4a7fc1)}
.kal-z1,.kal-ts1{border-left-color:var(--napravlenie-2-kraj,#3f9a6e)}
.kal-z2,.kal-ts2{border-left-color:var(--napravlenie-3-kraj,#d08a3c)}
.kal-z3,.kal-ts3{border-left-color:var(--napravlenie-4-kraj,#8a5cc0)}
.kal-z4,.kal-ts4{border-left-color:var(--napravlenie-5-kraj,#c4566f)}
.kal-z5,.kal-ts5{border-left-color:var(--napravlenie-6-kraj,#3a9aa8)}
.kal-z6,.kal-ts6{border-left-color:var(--napravlenie-7-kraj,#a89a2e)}
.kal-z7,.kal-ts7{border-left-color:var(--napravlenie-8-kraj,#6b7b8f)}
.kal-z8,.kal-ts8{border-left-color:var(--napravlenie-9-kraj,#b9674a)}
.kal-z9,.kal-ts9{border-left-color:var(--napravlenie-10-kraj,#6d914a)}
.kal-z10,.kal-ts10{border-left-color:var(--napravlenie-11-kraj,#c08f00)}
.kal-z11,.kal-ts11{border-left-color:var(--napravlenie-12-kraj,#5b63c9)}
.kal-t-net{background:#f4f5f7;border-left-color:#9aa0aa}
/* Тип события словами на блоке: цвет не единственный носитель смысла. */
.kal-blok .kal-tip { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
                     opacity: .8; }
/* Короткий блок (до 45 минут — три строки сетки) вмещает только время и
 * название: тип и зал в нём обрезались посреди буквы. Они остаются в подсказке
 * (`title`) и в панели занятия, а цвет и полоса говорят о типе и зале и так. */
.kal-blok.kal-h1 .kal-tip, .kal-blok.kal-h2 .kal-tip, .kal-blok.kal-h3 .kal-tip,
.kal-blok.kal-h1 .kal-mesto, .kal-blok.kal-h2 .kal-mesto, .kal-blok.kal-h3 .kal-mesto { display: none; }
.kal-blok.kal-h1 { padding-top: 0; padding-bottom: 0; }
/* Узкая дорожка (занятия идут рядом) — только начало: «17:30–18:30» в ней
 * обрезалось на середине цифры, а конец виден по нижнему краю блока. */
.kal-blok.kal-w2 .kal-do, .kal-blok.kal-w3 .kal-do, .kal-blok.kal-w4 .kal-do,
.kal-blok.kal-w6 .kal-do { display: none; }
.kal-legenda { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center;
               margin: 0 0 12px; font-size: 13px; color: var(--sinii); }
/* Кнопки вставки подстановки в шаблон сообщения. Видны только со скриптом
 * (`static/shablony.js` ставит `vstavki-js`): без него кнопка ничего не делает,
 * а подстановка набирается руками по перечню рядом. */
.vstavki { display: none; gap: 6px; flex-wrap: wrap; margin: 6px 0; }
.vstavki-js .vstavki { display: flex; }
/* Метка непрочитанного у пункта меню «Переписка». На выбранном пункте фон уже
 * акцентный — метка выворачивается, иначе её не видно. */
.neprochitano-menyu { margin-left: 6px; }
.shapka nav a.zdes .neprochitano-menyu { background: #fff; color: var(--akcent); }
.kal-raskraska a { padding: 2px 8px; border-radius: 10px; }
.kal-raskraska a.vybran { background: var(--fon); font-weight: 600; }
.kal-legenda-punkt { display: inline-flex; gap: 6px; align-items: center; }
.kal-legenda-znak { display: inline-block; width: 16px; height: 16px; border-radius: 4px;
                    border-left: 4px solid transparent; }
/* Выбор цвета в настройках: радиокнопки образцами палитры. Кнопка видна —
 * без неё выбор не делается с клавиатуры, а образец без подписи не читает диктор. */
.cvet-vybor { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; border: none; padding: 0; }
.cvet-vybor label { display: inline-flex; align-items: center; gap: 2px; margin: 0; cursor: pointer; }
.cvet-obrazec { display: inline-block; width: 22px; height: 22px; border-radius: 4px;
                border-left: 6px solid transparent; }
.cvet-vybor input:checked + .cvet-obrazec { outline: 2px solid var(--sinii); outline-offset: 1px; }

@media (max-width: 620px) {
  /* Панель на узком экране — лист снизу поверх сетки: сбоку ей нет места. */
  .kal-panel { position: fixed; left: 0; right: 0; bottom: 0; width: auto; max-height: 75vh;
               overflow-y: auto; z-index: 10; border-radius: var(--radius) var(--radius) 0 0;
               box-shadow: 0 -4px 18px rgba(17, 26, 74, .15); }
  .kal-kletka { min-height: 64px; }
  .kal-kletka .kal-blok .kal-nazvanie { display: none; }
}

/* === окно 3: абонементы, оплаты, деньги (.abn-…, .dng-…) ================== */

/* Отборы списка — чипами в строку; на узком экране переносятся, а не
 * уезжают вбок. */
.abn-otbory { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.abn-otbor {
  padding: 5px 12px;
  border: 1px solid var(--razdelitel);
  border-radius: 999px;
  color: var(--seryi);
  font-size: 13px;
}
.abn-otbor:hover { border-color: var(--seryi); text-decoration: none; }
.abn-otbor.zdes { color: var(--sinii); border-color: var(--sinii); font-weight: 600; }
.abn-otmena { margin-left: 14px; color: var(--seryi); font-size: 14px; }
/* Направления вида — галочками столбиком: их единицы, и выпадающий список с
 * множественным выбором на телефоне не нажимается. */
.abn-napravleniya { border: none; padding: 0; margin: 16px 0 0; }
.abn-napravleniya legend { font-size: 13px; color: var(--seryi); padding: 0; margin: 0 0 6px; }
.forma .abn-galochka { display: flex; align-items: center; gap: 8px; margin: 6px 0; color: inherit;
                       font-size: 14px; }
.forma .abn-galochka input { width: auto; }
/* Остаток лицевого счёта — главное число страницы. */
.dng-ostatok { font-size: 26px; line-height: 1.2; margin: 0 0 12px; }
.dng-knopka { margin: 12px 0 4px; }
.dng-skidka { border: 1px solid var(--razdelitel); border-radius: var(--radius); padding: 10px 14px;
              margin: 0 0 12px; }
.dng-skidka legend { font-size: 13px; color: var(--seryi); padding: 0 4px; }
/* Три формы денег в ряд, на узком экране — столбиком. */
.dng-formy { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
.dng-formy .forma { max-width: none; }
.dng-razbor { padding: 0 0 10px; border-bottom: 1px solid var(--razdelitel); }
.dng-razbor .ryadom { justify-content: flex-start; flex-wrap: wrap; }
.dng-zakrepit { justify-content: flex-start; margin-top: 10px; flex-wrap: wrap; }
.abn-dni { width: 64px; padding: 4px 6px; }

/* === окно D: график смен (.grf-…), 16.10 ===================================
 * Месяц по дням, как сетка месяца календаря; на телефоне — столбик дней без
 * чужих дней по краям. Непокрытые часы клуба — заметной плашкой со словами
 * «никого», а не одним цветом. */
.grf-perelistat { display: flex; gap: 12px; align-items: center; margin: 0 0 12px; }
.grf-mesyac { font-weight: 600; }
.grf-setka { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
             border-left: 1px solid var(--razdelitel); border-top: 1px solid var(--razdelitel);
             margin-bottom: 16px; }
.grf-shapka { font-size: 12px; color: var(--seryi); padding: 4px 6px;
              border-right: 1px solid var(--razdelitel); border-bottom: 1px solid var(--razdelitel); }
.grf-den { min-height: 96px; padding: 4px; background: var(--kartochka); min-width: 0;
           border-right: 1px solid var(--razdelitel); border-bottom: 1px solid var(--razdelitel);
           display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
.grf-den.grf-chuzhoy { background: var(--fon); }
.grf-den.grf-segodnya .grf-chislo { font-weight: 700; }
.grf-chislo { font-size: 12px; color: var(--seryi); }
.grf-smena { display: flex; flex-wrap: wrap; gap: 0 6px; align-items: center; padding: 2px 4px;
             border-radius: 4px; background: var(--napravlenie-1, #e6f0fb);
             color: var(--kal-tekst-bloka, var(--sinii)); }
.grf-smena.grf-starshiy { border-left: 3px solid var(--napravlenie-1-kraj, #4a7fc1); }
.grf-udalit { display: inline; margin-left: auto; }
.grf-udalit button { padding: 0 6px; }
.grf-dyra { padding: 2px 4px; border-radius: 4px; font-weight: 600;
            background: var(--oshibka-fon, #fdf0ef); color: var(--oshibka, #b42318); }
.grf-ryad { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 620px) {
  .grf-setka { grid-template-columns: 1fr; }
  .grf-shapka, .grf-den.grf-chuzhoy { display: none; }
  .grf-den { min-height: 0; }
}

/* Карточка при наведении на занятие (`static/kalendar.js`). Белая, с полосой
 * цвета блока: скрипт переносит классы палитры с блока, и их цвет полосы
 * действует, а заливку перекрывает белый фон ниже по каскаду. */
.kal-vsplyv { position: absolute; z-index: 30; width: 300px; max-width: calc(100vw - 16px);
              padding: 10px 12px; border-radius: 8px; border-left-style: solid; border-left-width: 6px;
              background: #fff; color: var(--kal-tekst-bloka, var(--sinii));
              box-shadow: 0 6px 24px rgba(17, 26, 74, .18), 0 0 0 1px rgba(17, 26, 74, .06);
              display: flex; flex-direction: column; gap: 4px; font-size: 13px; line-height: 1.35;
              pointer-events: none; }
.kal-vsplyv[hidden] { display: none; }
.kal-vsplyv.kal-otmeneno { text-decoration: none; }
.kal-vsplyv-zagolovok { font-size: 15px; font-weight: 700; }
.kal-vsplyv-tip { font-size: 12px; opacity: .8; margin-bottom: 4px; }
.kal-vsplyv-stroka { display: grid; grid-template-columns: 64px 1fr; gap: 8px; }
.kal-vsplyv-stroka > span:first-child { color: var(--seryi); font-size: 12px; }
.kal-vsplyv-podskazka { margin-top: 4px; font-size: 12px; color: var(--seryi); }
.kal-vsplyv-dannye { display: none; }

/* Блок Г: педагог вне своей доступности — пунктирная рамка, не запрет. */
.kal-blok.kal-vne-dostupnosti { outline: 2px dashed #a8461a; outline-offset: -2px; }

/* Блок Г: QR ссылки входа и Telegram — не шире экрана телефона. */
.qr-kartinka svg { width: 220px; max-width: 100%; height: auto; background: #fff; }

/* --- блок Д · кэшбэк (T5) --- */
.bns-flag { display: inline-flex; gap: 6px; align-items: center; margin: 6px 14px 0 0; }
.forma .bns-flag input { width: auto; }
.bns-itog { font-size: 18px; margin: 8px 0; }

/* Блок В: кнопки строк справочника статей не переносятся по слогам. */
.ras-knopka { white-space: nowrap; flex-shrink: 0; }

/* Отбор над списком — одной строкой полей с подписями сверху, кнопка в конце
 * строки. Один вид на всех экранах: журнал, люди, отчёты. На телефоне поля
 * переносятся строками и растягиваются на всю ширину. */
.otbor, .zhr-otbor { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-end; }
.otbor label, .zhr-otbor label { display: flex; flex-direction: column; font-size: 13px; gap: 4px;
                                 color: var(--seryi); margin: 0; }
.otbor select, .otbor input { width: auto; min-width: 150px; }
@media (max-width: 620px) {
  .otbor label, .zhr-otbor label { flex: 1 1 100%; }
  .otbor select, .otbor input { width: 100%; }
}
/* Отбор, который нужен не всякий раз, свёрнут в строку-заголовок: список —
 * главное на экране, и форма не должна сталкивать его вниз. */
/* «ещё» в отборе журнала — во всю строку под основными полями. */
.zhr-eshche { flex-basis: 100%; }
.zhr-eshche[open] { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-end; }
.zhr-eshche > summary { cursor: pointer; color: var(--seryi); font-size: 13px; min-height: 32px;
                        display: flex; align-items: center; flex-basis: 100%; }
details.otbor-svernut > summary {
  cursor: pointer; min-height: 40px; display: flex; align-items: center;
  color: var(--sinii); font-size: 14px; list-style: none;
}
details.otbor-svernut > summary::-webkit-details-marker { display: none; }
details.otbor-svernut > summary::before { content: "▸"; margin-right: 8px; color: var(--seryi); }
details.otbor-svernut[open] > summary::before { content: "▾"; }
details.otbor-svernut[open] > summary { margin-bottom: 12px; }
.karta.otbor-svernut { padding-top: 6px; padding-bottom: 6px; }
.karta.otbor-svernut[open] { padding-bottom: 18px; }
/* Чипы меток на телефоне — под палец. */
@media (max-width: 620px), (pointer: coarse) {
  .zay-metki .metka { display: inline-flex; align-items: center; min-height: 36px; padding: 6px 12px; }
}
