/* Фирменный стиль «Точки Сборки» — тот, что заказчик видел в КП.
 *
 * Шрифты лежат файлами в `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; }
}
