/* ============ Базові стилі ============ */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --c-bg: #f3f5f9;
  --c-surface: #ffffff;
  --c-border: #e2e6ee;
  --c-text: #1e2533;
  --c-text-soft: #6b7487;
  --c-primary: #3b5bdb;
  --c-primary-soft: #e7ecfd;
  --c-green: #2f9e44;
  --c-green-soft: #e6f6ea;
  --c-orange: #fd7e14;
  --c-orange-soft: #fdeee4;
  /* маркери важливості питань: критично / терміново / важливо —
     червоний, оранжевий, жовтий. Три теплі щаблі, і між ними лишається
     помітний крок по тону; але сам рівень несе кількість стрілок, колір
     лише підсилює, щоб маркер читався і без розрізнення відтінків */
  --c-red: #e03131;
  /* темніший червоний — під жучка «виправлення помилки». Свій відтінок, а не
     --c-red, бо жучок стоїть упритул до маркера «критично»: однаковий колір
     злив би два різні за змістом значки в одну пляму */
  --c-red-dark: #a61e1e;
  /* світле тло червоного — під гілку «Додати звіти», у яку звіт не додати */
  --c-red-soft: #fdecec;
  --c-yellow: #fab005;
  /* світле тло того самого жовтого — під смугу «дивлюсь чужим акаунтом»:
     сам --c-yellow під текстом не читається */
  --c-yellow-soft: #fff4d6;
  --c-purple: #7048e8;
  --c-purple-soft: #efe9fd;
  /* стовпчики активності: сірий світліший за --c-text-soft. Графік стоїть
     у кожному рядку таблиці й читається як фон, а не як дані до читання —
     тож він має бути тихішим за будь-який текст поруч */
  --c-act: #b4bbc9;
  /* стовпчики «Статистики»: світло-синій від --c-primary. Світлий він не
     для тиші, як --c-act, а навпаки — заради того, що на ньому стоїть:
     унизу кожного стовпчика темною цифрою написані години, і тло під ними
     мусить лишатися світлішим за текст */
  --c-stat: #c3cef7;
  /* переробка: години понад дванадцяту. Той самий синій, але на кілька
     щаблів темніший — понаднормове не окремий колір із власним значенням,
     а той самий стовпчик, у якого закінчилася клітинка. Темніший рівно
     настільки, щоб межа між ним і --c-stat читалася з відстані рядка */
  --c-stat-over: #7e93e3;
  --radius: 12px;
  --shadow: 0 1px 3px rgba(20, 30, 60, 0.08), 0 4px 16px rgba(20, 30, 60, 0.06);
  /* висота підвалу — і червоної смуги таймера, що лягає рівно на нього */
  --footer-h: 54px;
}

body {
  font-family: "Segoe UI", Roboto, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.45;
  color: var(--c-text);
  background: var(--c-bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

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

/* ============ Іконки ============ */
/* Геометрія всіх іконок лежить у спрайті на початку <body>, а в місці
   використання стоїть <svg class="icon"><use href="#i-…"></svg>.
   Символи не несуть жодного атрибута fill / stroke — фарбування цілком тут:
   так іконку перекрашує правило її блока (.msg--new заливає бульбашку,
   .prio--critical робить маркер червоним), а currentColor скрізь бере колір
   свого блока. Розміри лишаються при блоках — у їхніх власних правилах */
.sprite {
  display: none;
}
.icon {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* маркери терміновості й типу, каретка сортування і хрестик у плитці файла:
   лінія товща, бо самі іконки дрібні — 11–14px */
.icon--bold {
  stroke-width: 3;
}
/* три крапки «дій з повідомленням» — суцільні кружечки, без обведення */
.icon--solid {
  fill: currentColor;
  stroke: none;
}

/* ============ Шапка ============ */
.topbar {
  display: flex;
  align-items: center;
  gap: 32px;
  padding: 0 28px;
  height: 60px;
  background: var(--c-surface);
  border-bottom: 1px solid var(--c-border);
  position: sticky;
  top: 0;
  z-index: 10;
}

.topbar__logo {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.5px;
}
.topbar__logo span {
  color: var(--c-primary);
}

.burger {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  font: inherit;
  font-weight: 600;
  color: var(--c-text);
  cursor: pointer;
}
.burger__icon {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 18px;
}
.burger__icon span {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: var(--c-text-soft);
}
.burger[aria-expanded="true"] {
  border-color: var(--c-primary);
  color: var(--c-primary);
}
.burger[aria-expanded="true"] .burger__icon span {
  background: var(--c-primary);
}

.topbar__nav {
  display: flex;
  gap: 4px;
  flex: 1;
}

.topbar__link {
  padding: 8px 14px;
  border-radius: 8px;
  color: var(--c-text-soft);
  font-weight: 500;
}
.topbar__link:hover {
  background: var(--c-bg);
  text-decoration: none;
  color: var(--c-text);
}
.topbar__link--active {
  background: var(--c-primary-soft);
  color: var(--c-primary);
}

.topbar__user {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
}
.user-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.user-btn:hover .topbar__user-name,
.user-btn[aria-expanded="true"] .topbar__user-name {
  color: var(--c-text);
}
.topbar__user-name {
  color: var(--c-text-soft);
  font-weight: 500;
}
.topbar__avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--c-primary);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Меню профілю */
.user-menu {
  position: absolute;
  top: calc(100% + 16px);
  right: 0;
  z-index: 20;
  min-width: 200px;
  padding: 8px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 10px;
  box-shadow: var(--shadow);
}
.user-menu[hidden] {
  display: none;
}

.user-menu__langs {
  display: flex;
  gap: 4px;
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--c-border);
}
.lang {
  flex: 1;
  padding: 6px 0;
  border: 1px solid var(--c-border);
  border-radius: 7px;
  background: var(--c-surface);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
  cursor: pointer;
}
.lang:hover {
  border-color: var(--c-primary);
  color: var(--c-primary);
}
.lang--active {
  background: var(--c-primary-soft);
  border-color: var(--c-primary);
  color: var(--c-primary);
}

/* Позначка мови, якою писати клієнтові (templates/partials/lang_mark).
   Той самий вигляд, що в активної мови вище, — і навмисно: у меню це «мова,
   на якій ми зараз», біля поля вводу — «мова, якою тут пишуть». Кнопкою вона
   не є, тож ні рамки під курсором, ні курсора-пальця в неї немає */
.lang-mark {
  flex: none;
  padding: 6px 8px;
  border: 1px solid var(--c-primary);
  border-radius: 7px;
  background: var(--c-primary-soft);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  color: var(--c-primary);
  cursor: default;
}

/* Пункт меню: посилання «Профіль» і кнопка «Вийти» (вона кнопка, бо вихід
   іде формою POST). Тому тут і скидання кнопкових умовчань — рамки, тла,
   шрифту й центрування: обидва пункти мусять виглядати однаково */
.user-menu__item {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 7px;
  background: none;
  font: inherit;
  font-weight: 500;
  text-align: left;
  color: var(--c-text);
  cursor: pointer;
}
.user-menu__item:hover {
  background: var(--c-bg);
  text-decoration: none;
}
/* Пункти зі значком праворуч — «Вийти» і «Адмінка» (її бачить лише адмін).
   Значок притиснуто до правого краю, тож підпис лишається на одній лінії з
   «Профілем», у якого значка немає */
.user-menu__item--exit,
.user-menu__item--admin {
  display: flex;
  align-items: center;
}
.user-menu__item--exit svg,
.user-menu__item--admin svg {
  width: 16px;
  height: 16px;
  margin-left: auto;
  flex-shrink: 0;
  color: var(--c-text-soft);
}
.user-menu__item--exit:hover svg,
.user-menu__item--admin:hover svg {
  color: inherit;
}

/* ============ Сторінка ============ */
.page {
  flex: 1;
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 20px 28px 48px;
}

.page__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.page__title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 22px;
  font-weight: 700;
}

/* «Плюс» біля заголовка списку — кнопка: проект заводять у попапі, і йти
   за нею нікуди. Через це тут стоїть скидання рамки й шрифту, якого
   посиланню не треба було */
.page__add {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: none;
  border-radius: 50%;
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-family: inherit;
  font-size: 26px;
  font-weight: 400;
  line-height: 1;
  padding-bottom: 3px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.page__add:hover {
  background: var(--c-primary);
  color: #fff;
  text-decoration: none;
}

/* підказка «Додати проект» */
.page__add::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--c-text);
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  padding: 5px 9px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.page__add:hover::after {
  opacity: 1;
}

.page__actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.page__filters {
  display: flex;
  gap: 12px;
}

/* Галочка у рядку фільтрів («Лише свої» у «Звітах») — та сама, що
   «Показувати» в «Команді», тільки в рядку з селектом: вирівняна по його
   середині, підпис не переноситься */
.filter-check {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}
.filter-check__box {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  accent-color: var(--c-primary);
  cursor: pointer;
}

.filter-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text-soft);
  cursor: pointer;
}
.filter-btn svg {
  width: 18px;
  height: 18px;
}
.filter-btn:hover,
.filter-btn[aria-expanded="true"] {
  border-color: var(--c-primary);
  color: var(--c-primary);
}

/* Поле пошуку з лупою */
.search {
  position: relative;
  display: flex;
}
.input--search {
  padding-right: 40px;
}
/* type="search" малює свій хрестик очищення — а в нас на тому самому місці
   стоїть власна кнопка .search__clear, і поки поле не порожнє, хрестиків
   ставало два. Прибираємо браузерний, лишається наш */
.input--search::-webkit-search-cancel-button,
.input--search::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
}
.search__btn {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.search__btn svg {
  width: 17px;
  height: 17px;
}
.search__btn:hover {
  background: var(--c-primary-soft);
  color: var(--c-primary);
}

/* Лупа й хрестик — дві кнопки в правому краю поля. Лупа віддає форму
   фільтрів (пошук іде перезавантаженням сторінки), тож вона стоїть завжди й
   тримається самого краю, як кнопка сабміту на інших сторінках. Хрестик
   гасить набране й стає ліворуч від неї — лише поки в полі щось є */
.search__icon,
.search__clear {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.search__icon svg,
.search__clear svg {
  width: 17px;
  height: 17px;
}
.search__icon:hover,
.search__clear:hover {
  background: var(--c-primary-soft);
  color: var(--c-primary);
}
.search__clear {
  display: none;
  right: 34px;
  /* під вибраним із підказки хрестик — посилання (веде на цю ж сторінку без
     вибору), тож підкресленість із нього знімаємо: виглядати він має так
     само, як кнопка поруч із полем */
  text-decoration: none;
}
/* :placeholder-shown = поле порожнє. Вибір із підказки теж лягає в поле,
   тож хрестик так само з'являється й під вибраним значенням; під обидві
   кнопки поле відступає праворуч удвічі */
.search:has(.input--search:not(:placeholder-shown)) .search__clear {
  display: flex;
}
.search:has(.input--search:not(:placeholder-shown)) .input--search {
  padding-right: 70px;
}
/* Під вибраним із підказки поля немає зовсім: сервер малює на його місці
   блок із назвою запису. Лупа теж зникає — шукати нема чого, — і лишається
   сам хрестик, яким із вибору виходять; він стає на її місце, до краю */
.search:has(.search__pick) .search__clear {
  display: flex;
  right: 4px;
}

/* Підказка пошуку — випадає під полем і накриває шапку таблиці, тож
   z-index вищий за неї. Рядок один на всі види: ліворуч головне (назва
   проекту або ім'я), праворуч уточнення (адреса сайту або роль) */
.suggest {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 20;
  /* від ширини поля і ширше, якщо рядки того просять: правий край стоїть
     на місці, а список росте вліво — так довга назва з адресою поруч
     не тиснеться в багатокрапку на рівному місці */
  min-width: 100%;
  width: max-content;
  max-width: 360px;
  max-height: 320px;
  overflow-y: auto;
  padding: 4px;
  list-style: none;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 10px;
  box-shadow: var(--shadow);
}
/* Рядок підказки — посилання: вибір веде на цю ж сторінку з увімкненим
   фільтром, тож ним керує браузер, а не JS. Виглядає він усе одно як рядок
   списку, не як лінк, — звідси власний колір і знята підкресленість */
.suggest__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 7px 10px;
  border: none;
  border-radius: 6px;
  background: none;
  font: inherit;
  text-align: left;
  text-decoration: none;
  color: var(--c-text);
  cursor: pointer;
}
.suggest__item:hover,
.suggest__item:focus {
  background: var(--c-bg);
  outline: none;
  text-decoration: none;
}
.suggest__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
.suggest__meta {
  flex-shrink: 0;
  font-size: 12px;
  color: var(--c-text-soft);
}
/* Відповідь на пошук без збігів — на місці рядків списку. Не кнопка й не
   вибір, тож і вигляд неклікабельний: приглушений текст по центру, як у
   порожніх списків на сторінках */
.suggest__empty {
  padding: 12px 10px;
  text-align: center;
  color: var(--c-text-soft);
}

/* Вибране значення стає на місце поля пошуку — та сама коробка на те саме
   місце, щоб нічого в рядку не сіпнулось. Поля під ним немає: вибір лежить
   в адресі (`?type=…&id=…`), а у формі його несуть приховані поля */
.search__pick {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 260px;
  /* праворуч лишаємо місце під хрестик — він спільний для поля й вибору */
  padding: 0 38px 0 14px;
  border: 1px solid var(--c-primary);
  border-radius: 8px;
  background: var(--c-surface);
}
/* «Те саме місце» — це ще й та сама висота, і задана вона має бути явно:
   поле міряє себе паддінгами й рядком тексту, коробка вибору — своїм
   вмістом, і сходились вони лише випадково. Розійшлись на пару пікселів —
   і при виборі підказки смикається вся сторінка під рядком */
.input--search,
.search__pick {
  height: 36px;
}
.search__pick-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
/* уточнення тримається правого краю коробки, як і в самій підказці: там
   пара «назва ліворуч — уточнення праворуч», і вибір має виглядати так
   само, а не тягнутися хвостом за короткою назвою */
.search__pick-meta {
  flex-shrink: 0;
  margin-left: auto;
  font-size: 12px;
  color: var(--c-text-soft);
}

.input {
  padding: 9px 14px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  font-size: 14px;
  background: var(--c-surface);
  color: var(--c-text);
  outline: none;
}
.input:focus {
  border-color: var(--c-primary);
}
.input--search {
  width: 260px;
}

/* Усі селекти сайту — фільтри в шапках розділів і поля стану в питанні.
   Системну стрілку прибрано: браузер притискає її до правого краю поля, і на
   фіксованій ширині вона відривалася від підпису на півполя. Своя стрілка —
   та сама каретка, що в спрайті, — стоїть на відстані звичайного паддінга від
   тексту, а ширину селект більше не задає числом: --sel-w у нього ставить JS
   по вибраному пункту, тож між підписом і стрілкою лишається рівно паддінг.
   Поки скрипт не відпрацював (і якщо його немає), працює auto — селект міряє
   себе по найдовшому пункту сам, як стояв «Етап» в «Операційці».
   Колір стрілки вписаний числом: у фоні currentColor не працює, а тема одна */
select.input {
  appearance: none;
  width: var(--sel-w, auto);
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7487' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px;
  cursor: pointer;
}

/* Період сховано за іконкою календаря: відрізок вибирають у випадайці, а в
   рядку фільтрів лишається одна кнопка. Поки відрізок вибрано, кнопка
   світиться — інакше по згорнутому фільтру не видно, що він діє */
.calendar {
  position: relative;
  display: flex;
}
.calendar__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text-soft);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.calendar__btn svg {
  width: 18px;
  height: 18px;
}
.calendar__btn:hover,
.calendar__btn[aria-expanded="true"] {
  border-color: var(--c-primary);
  color: var(--c-primary);
}
.calendar__btn--on {
  background: var(--c-primary-soft);
  border-color: var(--c-primary);
  color: var(--c-primary);
}

/* Випадайка тримається лівого краю кнопки й накриває шапку таблиці, тож
   z-index той самий, що й у підказки пошуку. Відрізки стовпчиком: список
   читається краще за смугу кнопок, і «Кастом» стає в один ряд із пресетами */
.calendar__pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: max-content;
  padding: 8px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 10px;
  box-shadow: var(--shadow);
}
.calendar__pop[hidden] {
  display: none;
}
.calendar__opt {
  padding: 7px 10px;
  border: none;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: 13px;
  text-align: left;
  white-space: nowrap;
  color: var(--c-text);
  cursor: pointer;
}
.calendar__opt:hover,
.calendar__opt:focus-visible {
  background: var(--c-bg);
  outline: none;
}
.calendar__opt[aria-pressed="true"] {
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-weight: 600;
}

/* Дата від — дата до. Поля стоять у самому рядку фільтрів, перед календарем,
   і показуються лише після вибору відрізка */
.dates {
  display: flex;
  align-items: center;
  gap: 6px;
}
.dates[hidden] {
  display: none;
}
.input--date {
  width: 140px;
  padding: 8px 10px;
  cursor: pointer;
}
.dates__sep {
  color: var(--c-text-soft);
}

.btn {
  padding: 9px 16px;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.btn--primary {
  background: var(--c-primary);
  color: #fff;
}
.btn--primary:hover {
  background: #3352c9;
}
.btn--ghost {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  color: var(--c-text-soft);
}
.btn--ghost:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* ============ Проект ============ */
.project {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 14px;
}

.project__header {
  display: flex;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-border);
}

.project__name {
  display: flex;
  align-items: center;
  /* впритул до назви: коли вона обрізана трикрапкою, ширший проміжок
     читався як зайва діра перед іконкою сайту */
  gap: 4px;
  width: 220px;
  flex-shrink: 0;
  min-width: 0;
  font-size: 16px;
  font-weight: 700;
}
/* довга назва не переноситься на другий рядок, а обрізається трикрапкою.
   overflow вішаємо тільки на саму назву: на .project__link він би обрізав
   тултіп, що стирчить із нього вгору. Селектор не про <a>, бо на «Фінансах»
   назва буває й <span> — рефереру картка нікуди не веде */
.project__name > :not(.project__link) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.project__link {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  color: var(--c-text-soft);
}
.project__link svg {
  width: 15px;
  height: 15px;
}
.project__link:hover {
  color: var(--c-primary);
}
.project__link::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 7px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--c-text);
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  padding: 4px 8px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.project__link:hover::after {
  opacity: 1;
}

.project__name a {
  color: var(--c-text);
}
.project__name a:hover {
  color: var(--c-primary);
  text-decoration: underline;
}

.project__client {
  width: 178px;
  flex-shrink: 0;
}

/* Клієнт */
.client {
  display: flex;
  align-items: center;
  gap: 10px;
}
.client__avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.client__avatar--teal  { background: #0c8599; }
.client__avatar--pink  { background: #c2255c; }
.client__avatar--brown { background: #846358; }
.client__name {
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* «Адмін» замість імені. Імені в адміна немає — він не людина в списку, а
   бік розрахунків, — тож і підписаний тихіше за справжні імена поруч:
   у відправнику й одержувачу на «Платежах», в авторі повідомлення в гілці */
.admin {
  color: var(--c-text-soft);
}

.project__issues {
  width: 160px;
  flex-shrink: 0;
  white-space: nowrap;
}

.project__summary {
  display: flex;
  align-items: center;
  /* той самий зазор, що між датою та іконкою архіву в .upd — інакше дата
     проекту стоїть на 6px лівіше за дати гілок під нею */
  gap: 8px;
  margin-left: 14px;
}

/* Підсумок по проекту — одна сума на роль: адмін і клієнт бачать борг
   клієнта, виконавець — свою суму, реферер — свою частку. Яку саме вивести,
   вирішує PHP ($seeClient / $seeProjectPay / $seeProjectRefpay) — у розмітку
   потрапляє тільки одна з трьох. Усі стоять на одному місці й притиснуті
   до правого краю. Числа пишемо без пробілів
   (1093USD+16500UAH): у шапці мало місця */
.project__due,
.project__pay,
.project__refpay {
  margin-left: auto;
  text-align: right;
  text-transform: uppercase;
  font-size: 14px;
  font-weight: 700;
  color: var(--c-text);
}

/* Валюта в шапці проекту. Свій клас, не .cur-tag: той на десктопі
   схований, бо в таблиці валюта живе окремою колонкою */
.project__cur {
  margin-left: 1px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* Каретка згортання — спільна для проекта в списку, місяця на «Платежах» й
   виконавця в «Команді»: групи різні, а кнопка в них одна й та сама */
.project__toggle,
.month__toggle,
.member__toggle {
  transition: transform 0.15s, background 0.15s;
  width: 32px;
  height: 32px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text-soft);
  font-size: 14px;
  cursor: pointer;
}
.project__toggle:hover,
.month__toggle:hover,
.member__toggle:hover {
  background: var(--c-bg);
}

/* Згорнута група */
.project--collapsed .project__toggle,
.month--collapsed .month__toggle,
.member--collapsed .member__toggle {
  transform: rotate(-90deg);
}


.project--collapsed .project__branches {
  display: none;
}

/* Активність проекту — сума годин по всіх його гілках за ті самі 30 днів,
   що малює графік гілки. Стоїть у колонці «Активність» і в згорнутому
   проекті, і в розгорнутому: підсумок над графіками читається як їхня
   сума. Число рахує JS із data-hours */
.project__act {
  width: 270px;
  /* колонка «Активність» іде без бічних паддінгів, а блоки шапки живуть
     усередині паддінгів .project__header — тож без цих -12px число стояло б
     на 12px правіше за назву колонки та за самі стовпчики під ним */
  margin-left: -12px;
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--c-text-soft);
}

/* Найсвіжіше оновлення по гілках — видно і згорнутим, і розгорнутим */
.project__upd {
  white-space: nowrap;
  font-size: 13px;
  color: var(--c-text-soft);
}

/* Підсумок під усіма проектами */
.totals {
  width: max-content;
  max-width: 100%;
  margin-left: auto;
  padding: 12px 16px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.totals__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
}
.totals__row + .totals__row {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--c-border);
}
.totals__label {
  font-size: 12px;
  font-weight: 500;
  color: var(--c-text-soft);
}
.totals__value {
  font-size: 16px;
  font-weight: 600;
  text-transform: uppercase;
  white-space: nowrap;
}
.totals__value--client {
  font-weight: 700;
}
.totals__value--ref {
  font-weight: 500;
  color: var(--c-text-soft);
}
/* Надходження — зеленим, той самий колір напрямку, що й у підсумку місяця та
   в рядках «Платежів». У підсумку по проекту він і замінює слово ролі в
   підписі: зелене — те, що прийшло від клієнта, темне — те, що пішло
   виконавцю */
.totals__row--in .totals__value {
  color: var(--c-green);
}
/* Баланс за рік на «Платежах» — той самий синій, що й у підсумку місяця */
.totals__row--balance .totals__value {
  font-weight: 700;
  color: var(--c-primary);
}
/* Виправлення помилок за рік — той самий бордовий, що в шапці місяця */
.totals__row--fix .totals__value {
  color: var(--c-red-dark);
}

/* Спільна шапка таблиці над списком проектів */
.branches-head {
  margin: 0 1px 4px;
}
.branches-head .branches,
.branches-head .branches th {
  background: transparent;
}
.branches-head .branches th {
  border-bottom: none;
}

/* «Згорнути / розгорнути» — по правому краю, під кареткою проекту */
.branches th.branches__col-upd {
  text-align: right;
}

.toggle-all {
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  color: var(--c-primary);
  cursor: pointer;
}
.toggle-all:hover {
  text-decoration: underline;
}

/* Обидві назви кнопки лежать у розмітці — видно ту, що відповідає стану:
   згорнутим групам «Розгорнути», розгорнутим «Згорнути». JS перемикає
   тільки aria-expanded, тексту в ньому нема */
.toggle-all__collapse,
.toggle-all[aria-expanded='true'] .toggle-all__expand {
  display: none;
}
.toggle-all[aria-expanded='true'] .toggle-all__collapse {
  display: inline;
}

/* ============ Таблиця задач ============ */
.project__branches {
  overflow-x: auto;
  /* overflow-x робить і вертикаль скрол-контейнером, тож даємо запас зверху,
     щоб тултіпи кружечків першого рядка не обрізались */
  margin-top: -32px;
  padding-top: 32px;
  border-radius: 0 0 var(--radius) var(--radius);
}

.branches {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  min-width: 1044px;
}

.branches__col-name   { width: 220px; }
.branches__col-worker { width: 178px; }
.branches__col-issues { width: auto; min-width: 160px; }
.branches__col-rate   { width: 84px; }
.branches__col-time   { width: 64px; }
.branches__col-done   { width: 88px; }
.branches__col-paid   { width: 88px; }
.branches__col-pay    { width: 90px; }
.branches__col-cur    { width: 56px; }
/* Поле оплати — тільки на payment-add.php, остання колонка замість
   «Оновлено». Ширина під шестизначну суму з валютою при ній: «12 000 UAH»
   у полі стоїть без роздільника, але місце тримаємо під найдовше */
.branches__col-sum    { width: 132px; }
/* 30 діб по 9px — рівно стільки, скільки малює графік активності */
.branches__col-activity { width: 270px; }
/* Коментар адміна — тільки в «Команді», і там колонка гумова (див. секцію
   розділу): 260 їй за мінімум, а надлишок сторінки вона ділить із назвою */
.branches__col-note   { width: 260px; }
.branches__col-upd    { width: 104px; }

/* «Фінанси» — своя сітка колонок: «Оплачено» є тільки тут, «Питання» тут
   немає зовсім. Гумовою була саме колонка питань, тож зайву ширину тепер
   забирає «Клієнт/Виконавець», а решта тримає свої пікселі:
   972 = назва 220 + виконавець 178 + ставка 84 + час 64 + зроблено 88
       + оплачено 88 + до оплати 90 + валюта 56 + оновлено 104.
   Таблиця однакова для всіх ролей: ховати колонки за роллю більше нема кому,
   PHP просто не виводить у клітинки чужі рядки.

   Та сама сітка — у «Звітах» проекту: там ті самі гілки з тими самими
   колонками, тільки вибрані по одному проекту, тож і ширини мають збігатися.
   Решта правил нижче лишається за «Фінансами»: вони про шапку проекту, а в
   проекті таблиця стоїть сама */
@media (min-width: 1101px) {
  :is(.page-finance, .page-project-branches, .page-payment-add, .page-referrals) .branches {
    min-width: 972px;
  }
  :is(.page-finance, .page-project-branches, .page-payment-add, .page-referrals) .branches__col-worker {
    width: auto;
    min-width: 178px;
  }
  /* «Внести оплату» — та сама сітка, тільки замість «Оновлено» (104) стоїть
     колонка полів (132): 1000 = 972 − 104 + 132 */
  .page-payment-add .branches {
    min-width: 1000px;
  }
  /* У «Звітах» проекту в колонці назви стоять ще й дві дії над гілкою —
     замок і олівець, — і самій назві від 220px лишилося б 160: «Розробка
     дизайну» в них уже не влазить. Віддаємо колонці рівно ту ширину, яку
     забрали значки; бере вона її в гумового «Виконавця», а не в грошових
     колонок, — і на стільки ж росте мінімум таблиці */
  .page-project-branches .branches {
    min-width: 1028px;
  }
  .page-project-branches .branches__col-name {
    width: 276px;
  }
  /* На «Фінансах» назви проектів і гілок довші за 220px частіше, ніж у
     списку проектів, а «Клієнт/Виконавець» тут гумовий і місця в нього
     з надлишком: віддаємо назві ще 120px за його рахунок. Шапка проекту
     повторює сітку, тож і її назва росте на стільки ж; мінімум таблиці —
     теж, бо мінімум виконавця (178) лишається: 1092 = 972 + 120.

     «Реферальні» — та сама таблиця з тими самими назвами, тільки по одній
     стороні, тож і колонка назви в них та сама: інакше однакові гілки на
     двох сторінках обрізалися б по-різному */
  :is(.page-finance, .page-referrals) .branches {
    min-width: 1092px;
  }
  :is(.page-finance, .page-referrals) .branches__col-name,
  :is(.page-finance, .page-referrals) .project__name {
    width: 340px;
  }
  /* шапка проекту повторює ту саму сітку, тож і тут розтягується клієнт.
     Те саме — на «Реферальних»: сітка колонок у них із «Фінансами» спільна,
     тож і шапка проекту стоїть однаково */
  :is(.page-finance, .page-referrals) .project__client {
    width: auto;
    flex: 1;
  }
  /* Сума в шапці кінчається там само, де значення колонки «Валюта», а дата
     з кареткою стає на «Оновлено». Паддінг повторює паддінг клітинки —
     інакше сума стояла б на 12px правіше за колонку під нею */
  :is(.page-finance, .page-referrals) :is(.project__due, .project__pay, .project__refpay) {
    padding-right: 12px;
  }
  :is(.page-finance, .page-referrals) .project__summary {
    width: 92px; /* оновлено 104 − 12 правого паддінга шапки */
    margin-left: 0;
    justify-content: flex-end;
  }
}

/* Список проектів грошей не показує зовсім — усі суми живуть на «Фінансах».
   Замість п'яти грошових колонок тут одна «Активність», тож таблиця вужча:
   932 = назва 220 + виконавець 178 + питання 160 + активність 270 + оновлено 104.
   Префікс body лишився з часів, коли нижче стояла секція ролей і її
   селектор треба було перебити; тепер він просто нікому не заважає.

   «Активність» і «Оновлено» тримають свої пікселі (графіку потрібні рівно
   його 270px), а всю решту ширини три текстові колонки ділять порівну —
   для цього їм досить width: auto: у table-layout: fixed колонки без
   ширини ділять залишок нарівно. Інакше весь надлишок забирали б
   «Питання» і між кружечками та графіком зяяла б діра */
@media (min-width: 1101px) {
  body.page-projects .branches {
    min-width: 932px;
  }
  body.page-projects :is(
    .branches__col-name,
    .branches__col-worker,
    .branches__col-issues
  ) {
    width: auto;
  }

  /* у шапці проекту не лишилось сум, які тримали правий край, — тепер це
     робить сама дата з кареткою, як у ролей без грошей */
  body.page-projects .project__summary {
    width: auto;
    margin-left: auto;
  }
  /* Блоки шапки повторюють сітку таблиці, тож ділять ширину так само на три.
     Але живуть вони всередині паддінгів .project__header, тобто їхні 100%
     на 24px вужчі за таблицю — звідси 350 замість 374 (270 + 104) */
  body.page-projects :is(
    .project__name,
    .project__client,
    .project__issues
  ) {
    width: calc((100% - 350px) / 3);
  }
}

/* «До оплати» з валютою — ключова пара колонок, підсвічуємо спільною смугою.
   Фон вішаємо на клітинки, а не на <col>: фон рядка при ховері малюється
   поверх колонкового і смуга б зникала. Тільки десктоп — на мобільному
   таблиця розкладається в картки */
@media (min-width: 1101px) {
  .branches th.branches__col-pay,
  .branches th.branches__col-cur,
  .branches td.branches__pay,
  .branches td.branches__cur {
    background: var(--c-bg);
  }
}

/* грошові колонки — по правому краю */
.branches th.branches__col-rate,
.branches th.branches__col-time,
.branches th.branches__col-done,
.branches th.branches__col-paid,
.branches th.branches__col-pay,
.branches th.branches__col-cur,
.branches__rate,
.branches__time,
.branches__done,
.branches__paid,
.branches__pay,
.branches__cur {
  text-align: right;
}

.branches th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--c-text-soft);
  padding: 8px 12px;
  background: #fafbfd;
  border-bottom: 1px solid var(--c-border);
  white-space: nowrap;
}

.branches td {
  padding: 6px 12px;
  border-bottom: 1px solid var(--c-border);
  vertical-align: middle;
}

.branches__row:hover {
  background: #f8faff;
}

/* номер гілки стоїть у тій самій комірці, що й назва */
.branches__num {
  margin-right: 6px;
  font-weight: 700;
  color: var(--c-text-soft);
}

.branches__title {
  font-weight: 600;
}

/* Виконавець */
.worker {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
.worker__avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
/* Кольори аватарок — по одному на людину, щоб рядки команди не двоїлися.
   Перші чотири ті самі, що були; решта прийшла зі «Статистики», де людей
   уже десяток. Три з них (teal, pink, brown) стоять тими самими значеннями,
   що в клієнтів і в авторів повідомлень: палітра в проекті одна */
.worker__avatar--green  { background: #37b24d; }
.worker__avatar--purple { background: #7048e8; }
.worker__avatar--blue   { background: #1c7ed6; }
.worker__avatar--orange { background: #f76707; }
.worker__avatar--teal   { background: #0c8599; }
.worker__avatar--pink   { background: #c2255c; }
.worker__avatar--brown  { background: #846358; }
.worker__avatar--red    { background: #c92a2a; }
.worker__avatar--lime   { background: #5c940d; }
.worker__avatar--gray   { background: #495057; }
.worker__name {
  font-weight: 500;
}
/* Гілка без виконавця: у колонці риска замість пари «аватарка + ім'я».
   Буває це з першого дня проекту — гілку заводять і тоді, коли робити її
   ще нікому, — і після того, як виконавця зняли в попапі правки */
.worker__none {
  color: var(--c-text-soft);
}

/* Реферер — під виконавцем, без аватарки */
.referrer {
  /* вирівнюємо під ім'я виконавця: аватар 28px + gap 10px */
  padding-left: 38px;
  font-size: 12px;
  color: var(--c-text-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Значок «Внести оплату» біля імені в рядку гілки на «Фінансах» — картка,
   що веде на payment-add.php. Стоїть він тільки в адміна (PHP), і тільки
   там, де є кому платити: у клієнта, у виконавця й у реферера.

   Кегль і колір ті самі, що в стрілки на сайт проекту біля його назви:
   значок при імені — це дія над рядком, а не частина самого імені, і
   заявляти про себе більше за неї йому нема за чим. Від'ємне поле
   підтягує його до імені: 10px зазору .worker під нього завеликі —
   на такій відстані значок читався б як окремий стовпчик */
.pay-add {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  margin-left: -4px;
  color: var(--c-text-soft);
}
.pay-add svg {
  width: 15px;
  height: 15px;
}
.pay-add:hover {
  color: var(--c-primary);
}
/* у реферера рядок текстовий, тож значок сідає на базову лінію імені */
.pay-add--ref {
  margin-left: 4px;
  vertical-align: -3px;
}
/* Тултіп той самий, що в стрілки на сайт: росте вгору від центра значка */
.pay-add::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 7px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--c-text);
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  padding: 4px 8px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.pay-add:hover::after {
  opacity: 1;
}

/* Ставка (клієнт зверху, виконавець знизу) */
.branches__rate {
  white-space: nowrap;
}
.rate__row,
.time__row,
.done__row,
.paid__row,
.pay__row,
.cur__row {
  line-height: 1.3;
}

/* третє значення — реферер */
.rate__row.rate__row--ref,
.time__row.time__row--ref,
.done__row.done__row--ref,
.paid__row.paid__row--ref,
.pay__row.pay__row--ref,
.cur__row.cur__row--ref {
  font-size: 12px;
  font-weight: 500;
  color: var(--c-text-soft);
}
.pay__row--ref .pay__due {
  font-weight: 500;
  color: var(--c-text-soft);
}

/* клієнт зверху — жирним, виконавець знизу — тим самим темним, але легшим */
.rate__row {
  font-weight: 600;
  color: var(--c-text);
}
.rate__row--client {
  font-weight: 700;
}
/* «/год» належить лише погодинній ставці: у фіксованої в колонці стоїть сума
   за всю гілку, у помісячної — за місяць, і година до них не має стосунку
   (SCHEMA.md §2). Тому підпис приходить розміткою з ViewModel, а не ::after
   на кожному рядку — там, де оплата не погодинна, його просто немає. */
.rate__unit {
  font-size: 11px;
  font-weight: 400;
  color: var(--c-text-soft);
}

/* Питання (issues) — кольорові кружечки з тултіпом */
.branches__issues {
  white-space: nowrap;
}
.dot {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  margin-right: 4px;
  background: var(--dot);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  cursor: default;
}
/* Ширина фіксована, щоб кружечок лишався колом за будь-якого числа: замість
   розтягування в пігулку стискаємо самі цифри. Довжину мітки дає розмітка
   (від 100 там уже «99+»), бо CSS не вміє рахувати символи */
.dot--len2 {
  font-size: 11px;
  letter-spacing: -0.3px;
}
.dot--len3 {
  font-size: 9px;
  letter-spacing: -0.4px;
}
/* колір кружечка тримає змінна, а не сам background: у шапці проекту ті
   самі кружечки стають контурними, і колір їм потрібен уже на рамку */
.dot--processing { --dot: #4dabf7; } /* нове */
.dot--work       { --dot: #fab005; } /* в роботі */
.dot--wait       { --dot: #f76707; } /* в очікуванні */
.dot--check      { --dot: #a61e4d; } /* потребує перевірки */
.dot--done       { --dot: #2f9e44; } /* готово */

/* Кружечки в шапці групи — контурні: те саме коло, але порожнє, з
   кольоровою рамкою і звичайною цифрою. Так підсумок по групі видно як
   підсумок і він не сперечається із залитими кружечками гілок під ним.
   Однаково в проекті зі списку і у виконавця в «Команді» */
.project__issues .dot,
.member__issues .dot {
  background: var(--c-surface);
  border-color: var(--dot);
  color: var(--c-text);
}

/* тултіп при ховері */
.dot::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--c-text);
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  padding: 4px 8px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.dot::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--c-text);
  margin-bottom: -4px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.dot:hover::after,
.dot:hover::before {
  opacity: 1;
}

/* Активність — стовпчиковий графік відпрацьованих годин за добу за останні
   30 днів. Ширина колонки — рівно під графік (270px = 30 діб по 9px), тож
   клітинка йде без бічних паддінгів: графік стає в неї цілком, а не в залишок.
   Самі стовпчики малює JS зі списку годин у data-hours — розмітка тримає
   тільки числа, рівно так їх віддасть бекенд */
.branches__activity {
  position: relative;
  padding-left: 0;
  padding-right: 0;
}
.branches th.branches__col-activity {
  padding-left: 0;
  padding-right: 0;
}
/* Висота графіка стала — 28px у будь-якому рядку, хоч би яким високим той
   був: інакше стовпчики в різних рядках міряли б години різною міркою і
   порівняти їх очима стало б неможливо. Тому графік лежить абсолютно,
   по центру клітинки, і висоту рядка не міряє собою зовсім */
.act {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 28px;
  transform: translateY(-50%);
  display: flex;
  align-items: flex-end;
  gap: 2px;
}
/* 10 годин на добу — вся висота графіка; довший день впирається в стелю.
   Доба без роботи лишає ледь помітну риску на базовій лінії.
   На десктопі 30 стовпчиків стають у свої 270px із запасом, а от у мобільній
   картці графіку буває тісніше — там стовпчики стискаються, до 2px */
.act__bar {
  flex: 0 1 7px;
  width: 7px;
  min-width: 2px;
  height: calc(var(--h) / 10 * 100%);
  min-height: 1px;
  max-height: 100%;
  border-radius: 2px 2px 0 0;
  background: var(--c-act);
}

/* Час (клієнт зверху, виконавець знизу) */
.branches__time {
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.time__row {
  color: var(--c-text);
}
.time__row--client {
  font-weight: 700;
}

/* До оплати (клієнт зверху, виконавець знизу) */
.branches__pay {
  white-space: nowrap;
}
.pay__row {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 4px;
}
.pay__due {
  font-weight: 600;
  color: var(--c-text);
}
.pay__row--client .pay__due {
  font-weight: 700;
}
.pay__due--zero {
  color: var(--c-green);
}

/* Підсумковий рядок */
.branches__total td {
  background: #fafbfd;
  font-weight: 700;
  border-bottom: none;
  padding: 12px 16px;
}
.branches__total td:first-child {
  text-align: right;
  color: var(--c-text-soft);
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.4px;
}

/* ============ Попапи-меню ============ */
/* Меню з однаковим виглядом: терміновість питання (.prio-menu) у списку,
   дії з повідомленням (.msg-menu) і дії з питанням (.issue-menu) у гілці.
   Усі спливають біля натиснутої кнопки, тому position: fixed і координати
   від спільного placeMenu(): рядок таблиці для абсолюта не годиться —
   клітинка назви обрізає вміст по overflow: hidden. Підкладки, на відміну
   від .modal, немає: меню закривається кліком повз, а небезпечні дії —
   видалення повідомлення — і так ходять через попап підтвердження */
.prio-menu,
.msg-menu,
.issue-menu {
  position: fixed;
  z-index: 40;
  min-width: 176px;
  padding: 6px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 10px;
  box-shadow: var(--shadow);
}
.prio-menu[hidden],
.msg-menu[hidden],
.issue-menu[hidden] {
  display: none;
}

.prio-menu__item,
.msg-menu__item,
.issue-menu__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 9px;
  border: 0;
  border-radius: 7px;
  background: none;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--c-text);
  text-align: left;
  cursor: pointer;
}
.prio-menu__item:hover,
.msg-menu__item:hover,
.issue-menu__item:hover {
  background: var(--c-bg);
}
/* поточний рівень підсвічено, як активна мова в меню профілю */
.prio-menu__item[aria-checked="true"] {
  background: var(--c-primary-soft);
  font-weight: 600;
}
/* колір іконки веде .prio--*, спільна з маркером у рядку */
.prio-menu__icon,
.msg-menu__icon,
.issue-menu__icon {
  display: inline-flex;
  flex-shrink: 0;
}
.prio-menu__icon svg,
.msg-menu__icon svg,
.issue-menu__icon svg {
  width: 14px;
  height: 14px;
}
/* у списку «звичайно» — риска замість стрілок, і тут вона на видноті */
.prio-menu__icon.prio--normal {
  opacity: 1;
}

/* у меню повідомлення і в меню питання іконки самі по собі нічого не
   означають — вони лише мітки пунктів, тож притлумлені; колір бере на себе
   сам пункт */
.msg-menu__icon,
.issue-menu__icon {
  color: var(--c-text-soft);
}
/* видалення незворотне — єдиний червоний пункт у всіх меню */
.msg-menu__item--danger,
.msg-menu__item--danger .msg-menu__icon {
  color: var(--c-red);
}
.msg-menu__item--danger:hover {
  background: #fdecec;
}
/* display: flex вище переважив би [hidden] — гасимо схований пункт окремо.
   Попап один на всю гілку, а «Редагувати» з «Видалити» стоять лише у своєму
   повідомленні: пункти ховає й показує issue-menu.js при кожному відкритті */
.msg-menu__item[hidden] {
  display: none;
}

/* Меню питання і меню повідомлення ширші за решту: під діями в них ще й
   довідка, а там у рядку дві колонки — підпис і значення */
.issue-menu,
.msg-menu {
  min-width: 232px;
}
/* Довідка — не дії, а факти: про питання (коли створене й хто завів) і про
   повідомлення (коли написане, коли правлене і в якому стані лишило питання).
   Тому вони під рискою і тихішим кеглем, щоб не читалися як ще пункти меню */
.issue-menu__info,
.msg-menu__info {
  margin-top: 6px;
  padding: 8px 9px 2px;
  border-top: 1px solid var(--c-border);
}
/* Поки під трьома крапками немає дій, у попапі сама довідка — і риска над
   нею відділяла б її ні від чого. Знімаємо разом із відступом: лишається
   рівна рамка навколо самих фактів */
.issue-menu--facts .issue-menu__info,
.msg-menu--facts .msg-menu__info {
  margin-top: 0;
  padding: 3px 3px 0;
  border-top: none;
}
.issue-menu__fact,
.msg-menu__fact {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: 12px;
}
/* display: flex вище переважив би [hidden] — гасимо схований рядок окремо:
   «Відредаговано» показуємо лише в правлених повідомленнях */
.msg-menu__fact[hidden] {
  display: none;
}
.issue-menu__fact + .issue-menu__fact,
.msg-menu__fact + .msg-menu__fact {
  margin-top: 6px;
}
.issue-menu__label,
.msg-menu__label {
  color: var(--c-text-soft);
}
.issue-menu__value,
.msg-menu__value {
  font-weight: 500;
  text-align: right;
}

/* ============ Підтвердження дії ============ */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(30, 37, 51, 0.45);
}
.modal[hidden] {
  display: none;
}

.modal__box {
  width: 100%;
  max-width: 400px;
  padding: 20px;
  background: var(--c-surface);
  border-radius: var(--radius);
  box-shadow: 0 16px 40px rgba(30, 37, 51, 0.25);
}

.modal__title {
  font-size: 17px;
  font-weight: 700;
}

.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

/* Текст під заголовком попапа. У підтвердження його немає — там усе сказано
   заголовком, а що саме підтверджують, видно за спиною попапа. У
   повідомленні навпаки: заголовок один на всі випадки, і причина — це саме
   цей рядок */
.modal__text {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--c-text-soft);
}

/* ============ Форма нового проекту ============ */
/* Попап під «плюсом» у заголовку списку проектів. Коробка широка не заради
   простору: сторона і її ставка (форма оплати, сума, валюта) стоять одним
   рядком, і вужче вони просто не помістяться. Заголовок і кнопки стоять,
   гортається тільки середина — так само, як в описі задачі */
.modal__box--form {
  display: flex;
  flex-direction: column;
  max-width: 820px;
  max-height: 100%;
}

.project-form__head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.project-form__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.project-form__close svg {
  width: 15px;
  height: 15px;
}
.project-form__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

.project-form__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
  /* min-height нулем — інакше коробка-флекс не дасть вмісту стиснутись, і
     замість гортання довга форма просто обрізалась би знизу */
  min-height: 0;
  overflow-y: auto;
  /* поле в фокусі малює рамку в колір, і при overflow вона різалась би по
     краю коробки — тож лишаємо їй місце */
  padding: 2px;
}

.project-form__field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  /* поле в стовпчику не має тиснутись під довгим підписом сусіда */
  min-width: 0;
}
.project-form__field .input {
  width: 100%;
}

.project-form__label {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* Рядок форми. Поля в ньому міряються по нижньому краю, а не тягнуться на
   всю висоту: підпис в одному з них може перейти на другий рядок, і без
   цього поля під підписами роз'їхалися б по вертикалі */
.project-form__row {
  display: grid;
  gap: 10px;
  align-items: end;
}

/* Назва проекту й адреса сайту — дві рівні половини */
.project-form__row--main {
  grid-template-columns: 1fr 1fr;
}

/* Сторона і її ставка: ім'я, форма оплати, сума, валюта. Ім'я ширше за
   решту — у нього лізе і прізвище, і підказка під полем.
   Верхня межа розділяє сторони між собою: три однакові рядки поспіль без
   неї злилися б в одну решітку з дванадцяти полів */
.project-form__row--party {
  grid-template-columns: 1.7fr 1.1fr 0.9fr 1fr;
  padding-top: 12px;
  border-top: 1px solid var(--c-border);
}

/* Сума — число, і читають його по останній цифрі, а не по першій: три
   ставки поспіль вирівнюються розрядами одна під одною лише по правому краю */
.pay-row__sum {
  text-align: right;
}

/* На вузькому екрані коробка стає майже на всю ширину, і чотири поля в рядок
   уже не влазять: ім'я йде окремим рядком, а форма оплати, сума й валюта
   лишаються під ним одним рядком — разом вони читаються як одна ставка, і
   розривати їх по рядках означало б збирати її очима двічі.
   Колонки задані частками, а не auto-fit: за мінімальною шириною поля
   перестрибували б на наступний рядок, а частками вони просто вужчають.
   Валюта найвужча — в ній лежить трибуквений код, ширшою їй бути нема з
   чого; проміжок теж менший, бо між трьома полями він рахується двічі */
@media (max-width: 700px) {
  .project-form__row--main {
    grid-template-columns: 1fr;
  }
  .project-form__row--party {
    grid-template-columns: 1.45fr 1fr 0.9fr;
    column-gap: 8px;
  }
  .project-form__row--party > :first-child {
    grid-column: 1 / -1;
  }
  /* Три поля на ширину телефона — і паддінги в них рахуються шість разів.
     Тут вони вужчі, ніж у решти полів форми: місце віддано підпису, бо
     обрізана «Погодинна» гірша за тісне поле. Ім'я вище лишається
     звичайним — воно стоїть окремим рядком, і тиснути його нема від чого */
  .project-form__row--party .pay-row__type,
  .project-form__row--party .pay-row__sum,
  .project-form__row--party select.input {
    padding-left: 10px;
    padding-right: 10px;
  }
  /* Стрілка селекта підходить ближче до краю разом із паддінгом: на своєму
     звичайному місці вона з'їдала б у підпису третину поля */
  .project-form__row--party select.input {
    padding-right: 22px;
    background-position: right 7px center;
    background-size: 11px;
    text-overflow: ellipsis;
  }
}

/* Поле людини з автопідказкою — клієнт, виконавець, реферер. Коробка та
   сама, що в пошуку (.suggest), тільки випадає на всю ширину поля, а не
   тримається його правого краю: у формі полю нікуди рости вбік */
.combo {
  position: relative;
  display: flex;
}
.combo__list {
  left: 0;
  right: 0;
  width: auto;
  max-width: none;
}
/* Під нижнім полем форми списку вже нема куди впасти — там він падає вгору.
   Бік вибирає project-form.js: він же й міряє, скільки місця лишилось */
.combo--up .combo__list {
  top: auto;
  bottom: calc(100% + 6px);
}

/* Хрестик прибирає вибрану людину — і ім'я з поля, і її id. Стоїть у самому
   полі праворуч, як у пошуку в шапці, тож текст лишає йому місце.
   З'являється тільки під вибором зі списку: набране руками ім'я стирається
   й так, а порожньому полю прибирати нічого */
.combo__clear {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
/* display: flex сам по собі заступив би hidden — ховаємо явно */
.combo__clear[hidden] {
  display: none;
}
.combo__clear svg {
  width: 15px;
  height: 15px;
}
.combo__clear:hover {
  background: var(--c-primary-soft);
  color: var(--c-primary);
}
.combo:has(.combo__clear:not([hidden])) .combo__input {
  padding-right: 36px;
}

/* ============ Підвал ============ */
/* Висота задана явно (--footer-h), а не набирається відступами: смуга
   увімкненого таймера (.timer-bar) лягає рівно на підвал і має накрити його
   без щілини */
.footer {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--footer-h);
  padding: 8px 28px;
  text-align: center;
  color: var(--c-text-soft);
  font-size: 12px;
  border-top: 1px solid var(--c-border);
  background: var(--c-surface);
}

/* Зроблено (час × тариф) */
.branches__done {
  white-space: nowrap;
}
.done__row {
  font-weight: 600;
  color: var(--c-text-soft);
}
.done__row--client {
  font-weight: 700;
}

/* Оплачено — скільки з «Зроблено» вже закрито грошима. Виглядає так само,
   як «Зроблено»: це пара сусідніх колонок, які читають разом */
.branches__paid {
  white-space: nowrap;
}
.paid__row {
  font-weight: 600;
  color: var(--c-text-soft);
}
.paid__row--client {
  font-weight: 700;
}

/* Дата оновлення + перенесення гілки в архів */
.branches__upd {
  white-space: nowrap;
  font-size: 13px;
  color: var(--c-text-soft);
}
/* іконка вирівняна по правому краю — точно під кареткою проекту */
.upd {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

/* Кнопка в кінці рядка списку: архів гілки в «Проектах» і «Приховати» в
   «Команді». Дії різні, місце й розмір однакові — стоять обидві в .upd,
   під кареткою групи, — тож геометрію тримає спільне правило, а свій вигляд
   кожна дописує нижче */
.archive,
.hide {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
/* Порожня розпірка на місці кнопки: і архів гілки, і «Приховати» — дії
   адмінські, решті PHP виводить сюди цей span. Місце має лишатися зайнятим,
   інакше дати рядків з'їжджають на 40px правіше за дату групи, під якою вони
   стоять. Розміри дає саме правило вище, тут лишається зняти наведення */
.archive--void,
.hide--void {
  pointer-events: none;
}
.archive__icon,
.hide__icon {
  width: 16px;
  height: 16px;
}
.archive .archive__icon--from,
.archive--restore .archive__icon--to {
  display: none;
}
.archive--restore .archive__icon--from {
  display: block;
}
.archive:hover,
.hide:hover {
  background: var(--c-bg);
  color: var(--c-primary);
}

/* Гілка вже в архіві — повертаємо її назад */
.archive--restore {
  color: var(--c-green);
}
.archive--restore:hover {
  background: var(--c-green-soft);
  color: var(--c-green);
}

/* Значок архіву без кнопки — у «Звітах» проекту: в архіві гілка чи ні, бачить
   кожна роль, а переносить її туди сам адмін, тож решті PHP виводить на тому
   самому місці span. Значок і колір ті самі, зникає лише відгук на наведення;
   підказка з назвою стану лишається — усе так само, як у замка на початку
   рядка. З .archive--void це різні речі: той порожній і лише тримає місце
   там, де значка немає зовсім */
.archive--static {
  cursor: default;
}
.archive--static:hover {
  background: none;
  color: var(--c-text-soft);
}
.archive--static.archive--restore:hover {
  background: none;
  color: var(--c-green);
}

/* архівна гілка притлумлена */
.branches__row--archived .branches__num,
.branches__row--archived .branches__title {
  color: var(--c-text-soft);
}

/* «Приховати» — перекреслене око; проект уже прихований — звичайне, і воно
   ж каже, що клік поверне його назад. Іконки міняються тим самим прийомом,
   що й у архіву: обидві лежать у кнопці, показує потрібну модифікатор */
.hide .hide__icon--on,
.hide--restore .hide__icon--off {
  display: none;
}
.hide--restore .hide__icon--on {
  display: block;
}
/* Прихований проект лишається в списку, поки стоїть фільтр «Всі» або
   «Приховані», — але притлумленим, як гілка в архіві */
.hide--restore {
  color: var(--c-primary);
}
.branches__row--hidden .branches__title {
  color: var(--c-text-soft);
}

/* Дії над гілкою в першій колонці «Звітів»: замок і олівець.
   Стоять вони перед номером, у лівому краю колонки, — так по всьому списку
   вони складаються в рівний стовпчик, а назви лишаються на одній вертикалі.
   Обгортка флексом, а не інлайном у клітинці: між значками потрібен свій
   проміжок, а не пробіл із розмітки */
.branch {
  display: flex;
  align-items: center;
  gap: 2px;
}
/* назва з номером — один елемент рядка, тож проміжок між ними той самий
   margin у .branches__num, що й був, а не gap обгортки */
.branch__name {
  min-width: 0;
  margin-left: 4px;
}
/* Зірочка основної гілки — одразу за назвою, у рядок із нею. inline-flex, а
   не блок: назва може обірватись багатокрапкою, і значок має лишитись при
   ній, а не поїхати в свій кут. position — під тултіп нижче */
.branch__main {
  position: relative;
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  /* вирівнюємо по тексту, а не по нижньому краю рядка */
  vertical-align: -2px;
  color: var(--c-orange);
}
.branch__main-icon {
  width: 13px;
  height: 13px;
}

/* Тултіп той самий, що в замка й олівця на початку рядка, — тільки росте
   від лівого краю значка: у стовпчику назв праворуч від нього ще пів
   таблиці, і місця вистачає */
.branch__main::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 4px);
  left: -4px;
  background: var(--c-text);
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  padding: 4px 8px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.branch__main:hover::after {
  opacity: 1;
}

/* Замок і олівець — та сама кнопка, що архів у кінці рядка, тільки менша:
   тут їх дві поспіль, і повнорозмірні вони відсунули б назву на 64px */
.lock,
.branch-edit {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  /* негативні поля по вертикалі — щоб пара значків не піднімала рядок:
     висоту в ньому задає аватарка виконавця, а не ці кнопки */
  margin: -4px 0;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.lock__icon,
.branch-edit__icon {
  width: 15px;
  height: 15px;
}
.lock:hover,
.branch-edit:hover {
  background: var(--c-bg);
  color: var(--c-primary);
}

/* Дужка замка: відкрита гілка — відкритий замок. Обидва значки лежать у
   кнопці, потрібний показує модифікатор — той самий прийом, що в архіву */
.lock .lock__icon--closed,
.lock--closed .lock__icon--open {
  display: none;
}
.lock--closed .lock__icon--closed {
  display: block;
}
/* Відкрита гілка — звичайний стан, і колір у неї тихий, як у решти значків
   рядка. Закрита впадає в око оранжевим: закритих у списку одиниці, і саме
   вони — те, що з рядка треба помітити */
.lock--closed {
  color: var(--c-orange);
}
.lock--closed:hover {
  background: var(--c-orange-soft);
  color: var(--c-orange);
}

/* Замок стоїть у кожної ролі — це стан гілки, а не дія над нею, — але
   клікає його тільки адмін: у решти PHP виводить на тому самому місці span
   замість кнопки. Значок у нього той самий, зникає лише відгук на
   наведення — підказка з назвою стану лишається: заради неї на значок і
   наводять. pointer-events тут не годяться саме через неї: без наведення
   не було б і підказки */
.lock--void {
  cursor: default;
}
.lock--void:hover {
  background: none;
  color: var(--c-text-soft);
}
.lock--void.lock--closed:hover {
  color: var(--c-orange);
}

/* Тултіп той самий, що в архіву, тільки росте від лівого краю: кнопки
   стоять на початку рядка, і праворуч підказці нема за що чіплятися */
.lock::after,
.branch-edit::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 2px);
  left: 0;
  background: var(--c-text);
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  padding: 4px 8px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.lock:hover::after,
.branch-edit:hover::after {
  opacity: 1;
}

/* тултіп «В архів» / «Приховати» / «Отримано» / «Позначити прочитаним» */
.archive::after,
.hide::after,
.check::after,
.msg::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 2px);
  right: 0;
  background: var(--c-text);
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  padding: 4px 8px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.archive:hover::after,
.hide:hover::after,
.check:hover::after,
.msg:hover::after {
  opacity: 1;
}

/* Підказка галочки — ліворуч від неї, а не над нею. Рядки оплат лежать у
   .month__rows, а той прокручується по горизонталі — і тому обрізає все, що
   вийшло за його верх: бульбашка над першим рядком місяця ховалася під шапку
   місяця, і замість підказки було видно її обрізаний край. Збоку вона
   лишається в межах свого рядка, тож видно її в будь-якому — і в першому, і
   в місяці з одного рядка. Місця ліворуч вистачає: сусідня колонка — валюта,
   і бульбашка лягає над нею */
.check::after {
  bottom: auto;
  top: 50%;
  right: calc(100% + 2px);
  transform: translateY(-50%);
}

/* Галочка «отримано» в кінці рядка оплати. Кнопка та сама, що замок у гілці:
   значок стоїть у рядку в кожної ролі — це стан оплати, — а клікає його
   тільки адмін, і решті PHP виводить на тому самому місці span.
   Ставимо її по правому краю своєї колонки, під кареткою місяця: коробка в
   неї така сама 32-піксельна, як у каретки, тож обидві стоять однією віссю —
   галочки в рядках і каретка над ними */
.check {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-left: auto;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: none;
  /* непідтверджена оплата — тихіший за будь-який текст сірий, той самий, що
     в стовпчиках активності: галочка тут ще не подія, а порожнє місце під неї */
  color: var(--c-act);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.check__icon {
  width: 15px;
  height: 15px;
}
.check:hover {
  background: var(--c-bg);
  color: var(--c-primary);
}
/* гроші дійшли — зелена, той самий колір, що в надходженнях */
.check--on {
  color: var(--c-green);
}
.check--on:hover {
  background: var(--c-green-soft);
  color: var(--c-green);
}
/* Значок без кнопки — у всіх, крім адміна: стан оплати бачить кожен, а
   міняє його адмін. Зникає лише відгук на наведення, підказка лишається —
   заради неї на значок і наводять; усе так само, як у замка гілки */
.check--void {
  cursor: default;
}
.check--void:hover {
  background: none;
  color: var(--c-act);
}
.check--void.check--on:hover {
  background: none;
  color: var(--c-green);
}

/* Валюта поруч зі значенням — тільки на мобільному */
.cur-tag {
  display: none;
}

/* Валюта */
.branches__cur {
  white-space: nowrap;
}
.cur__row {
  text-transform: uppercase;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text);
}
.cur__row--client {
  font-weight: 700;
}

/* ============ Адаптив ============ */
@media (max-width: 1100px) {
  /* Знизу відступу немає: картки тут лежать на всю ширину, і сірий проміжок
     між останньою з них та білим підвалом читався не як повітря, а як товста
     смуга-роздільник. Тепер картку від підвалу відбиває сама лінія підвалу —
     та сама, що ділить рядки всередині карток */
  .page {
    padding: 16px 0 0;
  }

  /* шапка лишається одним рядком: логотип, бургер, аватар. Меню в неї не
     потрапляє зовсім — воно випадає поверх сторінки */
  .topbar {
    gap: 12px;
    height: auto;
    padding: 10px 14px;
  }
  /* бургер не стискається — решта шапки лишається як є */
  .burger {
    display: flex;
    margin-left: auto;
    flex-shrink: 0;
  }

  /* Меню випадає з-під шапки поверх сторінки, як і меню профілю поруч:
     position: absolute вибиває його з потоку, тож висота шапки не міняється
     і вміст під нею не стрибає. Точка відліку — сама .topbar, вона
     position: sticky. z-index нижчий за .user-menu (20): якщо відкриті
     обидва, випадайка профілю лягає зверху */
  .topbar__nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 15;
    flex-direction: column;
    gap: 2px;
    padding: 8px 14px 12px;
    background: var(--c-surface);
    border-bottom: 1px solid var(--c-border);
    box-shadow: var(--shadow);
  }
  .topbar__nav--open {
    display: flex;
  }
  .topbar__user {
    min-width: 0;
  }

  /* шапка проекту — чотири рядки:
     1) назва + посилання, дата, каретка
     2) клієнт і кружечки праворуч
     3) оплата: клієнт ліворуч, виконавець праворуч
     4) реферер праворуч */
  .project__header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 6px 10px;
    /* перша картка гілки під шапкою має свою верхню межу — разом із межею
       шапки лінія читалась подвійною */
    border-bottom: none;
  }
  .project__name {
    grid-column: 1;
    grid-row: 1;
    width: auto;
    min-width: 0;
  }

  .project__summary {
    grid-column: 2;
    grid-row: 1;
    margin-left: 0;
    justify-self: end;
    align-self: center;
    gap: 12px;
  }

  /* клієнт і кружечки ділять одну клітинку, щоб кружечки не звужували
     колонку назви проекту в першому рядку */
  .project__client {
    grid-column: 1 / -1;
    grid-row: 2;
    width: auto;
    min-width: 0;
    padding-right: 160px;
  }
  .project__issues {
    grid-column: 1 / -1;
    grid-row: 2;
    width: auto;
    margin: 0;
    justify-self: end;
    align-self: center;
    white-space: nowrap;
  }
  /* на «Фінансах» і «Реферальних» кружечків немає, зате в тому ж рядку
     праворуч стоїть сума по проекту — тримаємо місце під неї (найдовша,
     «1093USD+16500UAH», займає 141px), а довше ім'я клієнта обрізається
     трикрапкою */
  :is(.page-finance, .page-referrals) .project__client {
    padding-right: 150px;
  }

  /* сума годин у вузькій шапці стає окремим рядком під клієнтом: у першому
     рядку її нема куди вставити — там назва проекту й дата */
  .project__act {
    grid-column: 1 / -1;
    grid-row: 3;
    width: auto;
    /* у картковій шапці колонок немає — зсув під таблицю тут зайвий */
    margin-left: 0;
  }
  /* число тут стоїть саме по собі, без колонки з підписом, а поруч у шапці
     висить час оновлення — щоб «231:00» не читалося як година, підписуємо.
     Підпис повний, як у заголовку колонки на десктопі: сума не за весь час,
     а за ті самі 30 днів, що малює графік */
  .project__act::before {
    content: 'Активність 30 днів: ';
    font-weight: 500;
  }

  /* сума стоїть у тому ж рядку, що й клієнт, притиснута до правого краю:
     разом вони читаються як одна пара «кому — скільки», а не два окремі
     рядки. Колонки не займає (1 / -1), щоб її ширина не тиснула на назву
     проекту в першому рядку, — місце під неї тримає паддінг клієнта */
  .project__due,
  .project__pay,
  .project__refpay {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: end;
    align-self: center;
    margin-left: 0;
  }
  .topbar__user-name {
    display: none;
  }

  .page__head {
    flex-direction: column;
    align-items: stretch;
    padding: 0 12px;
  }
  .page__actions {
    flex-wrap: wrap;
    gap: 8px;
  }
  .filter-btn {
    display: flex;
  }
  .page__filters {
    display: none;
    order: 3;
    width: 100%;
    flex-direction: column;
    gap: 8px;
  }
  .page__filters--open {
    display: flex;
  }
  .search {
    flex: 1;
    min-width: 0;
  }
  .input--search,
  .search__pick {
    width: 100%;
  }
  /* у стовпчику фільтрів селект іде на всю ширину, а не по своєму пункту:
     інакше поля стояли б драбинкою. Селектор із тегом — щоб побити
     select.input із його --sel-w при рівній специфічності */
  select.input {
    width: 100%;
  }
  /* у розгорнутих фільтрах статус і пошук ідуть на всю ширину, а календар
     лишається кнопкою — інакше він розтягнувся б на колонку і клік по
     порожньому місці праворуч не рахувався б як «повз випадайку» */
  .calendar {
    align-self: flex-start;
  }

  /* Календар і поля дат стоять одним рядком — іконка відкриває вибір
     відрізка, і вибрані дати лишаються поруч із нею, а не окремою смугою
     над кнопкою. Рядок один на всіх: поки дат немає, в ньому сама кнопка.
     Сусід із шириною 100% (статус на «Фінансах») сам переходить на
     наступний рядок. Те саме — у звітах гілки, де в фільтрі, крім дат,
     немає нічого */
  .page-finance .page__filters,
  .page-referrals .page__filters,
  .page-project-reports .page__filters {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .page-finance .calendar,
  .page-referrals .calendar,
  .page-project-reports .calendar {
    align-self: center;
  }
  /* поля дат забирають рештку рядка коло кнопки */
  .page-finance .dates,
  .page-referrals .dates,
  .page-project-reports .dates {
    flex: 1;
    min-width: 0;
  }
  /* з полями дат у рядку кнопка стоїть коло правого краю — випадайка
     тримається її правого боку, інакше вилазить за екран. Поки дат немає,
     кнопка ліворуч і випадайка падає від лівого боку, як і була */
  .page-finance .dates:not([hidden]) ~ .calendar .calendar__pop,
  .page-referrals .dates:not([hidden]) ~ .calendar .calendar__pop,
  .page-project-reports .dates:not([hidden]) ~ .calendar .calendar__pop {
    left: auto;
    right: 0;
  }
  /* поля дат ділять свій рядок нарівно, обабіч тире */
  .input--date {
    width: auto;
    min-width: 0;
    flex: 1;
  }

  .branches-head {
    display: none;
  }

  .page__title {
    padding-right: 0;
  }
  .page__title .toggle-all {
    margin-left: auto;
    font-size: 13px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
  }

  .project {
    border: none;
    border-radius: 0;
    box-shadow: none;
    margin-bottom: 10px;
  }

  /* Підсумок лежить просто на сірому тлі сторінки: картки тут і так без
     рамок, і ще одна біла плашка під ними читалася як зайва картка */
  .totals {
    width: auto;
    margin-left: 0;
    padding: 12px;
    background: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
  }
  .totals__row {
    gap: 12px;
  }

  /* --- таблиця перетворюється на картки --- */
  .project__branches {
    overflow-x: visible;
    margin-top: 0;
    padding: 0;
  }
  .branches {
    display: block;
    min-width: 0;
    table-layout: auto;
  }
  .branches thead {
    display: none;
  }
  .branches tbody {
    display: block;
  }

  /* дві колонки потрібні лише другому рядку картки (кружечки + виконавець),
     решта клітинок розтягується на всю ширину через grid-column: 1 / -1 */
  .branches__row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    padding: 10px 12px;
    border-top: 1px solid var(--c-border);
  }
  .branches__row:hover {
    background: none;
  }

  .branches td {
    display: block;
    border: none;
    padding: 0;
  }

  .branches td.branches__name {
    grid-column: 1 / -1;
    grid-row: 1;
    min-width: 0;
    /* місце під дату та іконку архіву, які лежать у тій самій клітинці */
    padding-right: 92px;
    font-size: 15px;
  }
  /* дата лежить у тій самій клітинці, притиснута праворуч */
  .branches td.branches__upd {
    grid-column: 1 / -1;
    grid-row: 1;
    justify-self: end;
    align-self: start;
    font-size: 12px;
  }
  .upd {
    gap: 4px;
  }
  .archive,
  .hide {
    width: 28px;
    height: 28px;
    margin: -5px -6px -5px 0;
  }

  /* кружечки ліворуч, виконавець одразу за ними. Обидві клітинки тягнемо
     по висоті рядка, щоб їхні нижні межі склалися в одну лінію-роздільник */
  .branches td.branches__issues,
  .branches td.branches__worker {
    grid-row: 2;
    align-self: stretch;
    display: flex;
    align-items: center;
    margin-top: 8px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--c-border);
  }
  /* у списку проектів під цим рядком іде тільки графік активності, і власна
     лінія-роздільник йому ні до чого — рядок і так читається окремо */
  .page-projects .branches :is(td.branches__issues, td.branches__worker) {
    padding-bottom: 0;
    border-bottom: none;
  }
  /* на «Реферальних» ця клітинка порожня, коли реферал читає свої ж рядки:
     ім'я на такій сторінці одне й стоїть у пошуку над списком. Тоді від
     клітинки лишається сама лінія під назвою гілки — власної висоти порожньому
     рядку не треба. В адміна там ім'я реферера, і клітинка живе як усюди */
  .page-referrals .branches td.branches__worker--void {
    margin-top: 0;
    padding-bottom: 0;
  }
  .branches td.branches__issues {
    grid-column: 1;
  }
  .branches td.branches__worker {
    grid-column: 2;
    min-width: 0;
    /* притискаємо до правого краю картки; 4px до кружечків уже дає
       margin-right останнього з них */
    justify-content: flex-end;
    padding-left: 8px;
  }
  /* аватарка праворуч від імені — порядок міняємо, а не розмітку */
  .branches td.branches__worker .worker {
    flex-direction: row-reverse;
  }
  /* у гілці з реферером його ім'я стає другим рядком клітинки під іменем
     виконавця, тож клітинка з рядка перетворюється на стовпчик */
  .page-finance .branches__row--ref td.branches__worker {
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    gap: 2px;
  }
  .worker {
    min-width: 0;
  }
  .worker__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* кожен параметр — свій рядок у три колонки:
     підпис | значення клієнта | значення виконавця */
  .branches td.branches__rate,
  .branches td.branches__time,
  .branches td.branches__done,
  .branches td.branches__paid,
  .branches td.branches__pay {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 88px;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    align-items: baseline;
    gap: 0 10px;
    padding: 6px 0 0;
  }
  /* картка з реферером — четверта колонка під його значення */
  .branches__row--ref td.branches__rate,
  .branches__row--ref td.branches__time,
  .branches__row--ref td.branches__done,
  .branches__row--ref td.branches__paid,
  .branches__row--ref td.branches__pay {
    grid-template-columns: 76px;
    gap: 0 8px;
  }
  /* реферер лишається під іменем виконавця — тільки притиснутий до того ж
     правого краю, що й ім'я, бо аватарка в картці стоїть праворуч */
  .referrer {
    padding-left: 0;
    max-width: 100%;
  }

  .branches td.branches__rate { grid-row: 3; }
  .branches td.branches__time { grid-row: 4; }
  .branches td.branches__done { grid-row: 5; }
  .branches td.branches__paid { grid-row: 6; }
  .branches td.branches__pay  { grid-row: 7; }

  /* активність — окремим рядком картки на всю її ширину. Підпису тут немає:
     стовпчиковий графік ні з чим не сплутаєш, а місце в картці дороге */
  .branches td.branches__activity {
    grid-column: 1 / -1;
    grid-row: 3;
    position: static;
    padding: 10px 0 0;
  }
  /* у картці графік стає звичайним блоком: висота лишається та сама, а от
     ширина вже не фіксовані 270px — стовпчики розтягуються на весь рядок */
  .act {
    position: static;
    transform: none;
  }
  .act__bar {
    flex-grow: 1;
  }

  /* валюта переїхала до самих значень */
  .branches td.branches__cur {
    display: none;
  }
  .cur-tag {
    display: inline;
    margin-left: 4px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--c-text-soft);
  }
  .pay__row .cur-tag {
    margin-left: 0;
  }

  .branches td.branches__rate::before,
  .branches td.branches__time::before,
  .branches td.branches__done::before,
  .branches td.branches__paid::before,
  .branches td.branches__pay::before {
    content: attr(data-label);
    text-align: left;
    font-size: 12px;
    font-weight: 500;
    color: var(--c-text-soft);
  }

  /* пара «клієнт / виконавець» розкладається по двох колонках значень */
  .rate,
  .time,
  .done,
  .paid,
  .pay {
    display: contents;
  }
}

/* Назва гілки — посилання */
a.branches__title {
  color: var(--c-text);
}
a.branches__title:hover {
  color: var(--c-primary);
  text-decoration: underline;
}


/* ============ Сторінка проекту ============ */
/* Назва проекту — це підпис над підменю, а не великий заголовок сторінки:
   кегль менший за типовий .page__title і повітря навколо теж */
.page--project {
  padding-top: 10px;
}
/* Шапка проекту — два рядки: назва з доменом і клієнт у верхньому, розділи
   проекту й фільтри питань у нижньому. Кожен рядок розводить свої два блоки
   по краях. Верхній лінії під собою не має, тож його блоки просто стають
   по центру — це базове вирівнювання рядка */
.project-head {
  margin-bottom: 16px;
}
.project-head__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 24px;
}

/* Роздільник переїхав на самі вкладки (.submenu) й обривається на останній
   з них: під фільтрами та пошуком він нічого не розділяв. Разом із ним пішло
   й вирівнювання по нижньому краю — форму більше не треба піднімати над
   лінією 8-ма пікселями, тож рядок став нижчим, а вкладки підтягнулись угору */
.project-head__row--tools {
  align-items: center;
  padding-top: 6px;
}

.project-head .page__title {
  font-size: 19px;
  margin-bottom: 0;
  /* min-width дає задовгій назві стискатись, а не виштовхувати клієнта
     за правий край */
  min-width: 0;
}

/* Гілка над списком її звітів — той самий рядок «заголовок ліворуч, пошук
   праворуч», що над будь-яким іншим списком. Заголовок тут дрібніший за
   звичайний (22px) і навіть за назву проекту над ним: у цій шапці головне
   проект, а гілка — його частина. Зазор над рядком дає сама шапка проекту,
   тож знизу лишається менше за звичайні 16px — інакше заголовок відходив би
   від свого списку далі, ніж від шапки */
.page__head--branch {
  margin-bottom: 12px;
}
.page__head--branch .page__title {
  font-size: 17px;
}

/* Виконавець у дужках після назви гілки — те саме, що .reports__by робить у
   рядку звіту: ім'я тут другорядне (головне в заголовку — сама гілка), тож
   воно дрібніше, приглушене й не жирне, хоч і стоїть усередині h2 */
.page__title-by {
  margin-left: 6px;
  font-size: 13px;
  font-weight: 400;
  color: var(--c-text-soft);
}

/* Клієнт — праворуч у верхньому рядку шапки. Сум тут немає: гроші проекту
   живуть у своєму розділі, а не в шапці питань.
   min-width дає задовгому імені обрізатись багатокрапкою */
.page__client {
  display: flex;
  min-width: 0;
}
/* Ім'я клієнта в шапці — звичайним текстом: жирним тут іде назва проекту,
   а клієнт стоїть поруч довідкою. У списку проектів навпаки — там
   .client__name лишається жирним, бо він головне в рядку */
.page__client .client__name {
  font-weight: 400;
}

.page__title .project__link {
  align-items: center;
}
.page__title .project__link svg {
  width: 15px;
  height: 15px;
}

/* Домен показуємо текстом — на десктопі місця вистачає.
   На мобільному лишається сама іконка */
.project__domain {
  margin-right: 5px;
  font-size: 13px;
  font-weight: 500;
}

/* Назва проекту — окремим елементом, а не голим текстом у флексі: інакше
   анонімний флекс-елемент не стискається і довга назва вилазить за екран */
.page__title-text {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Поруч видно сам домен — тултіп «Відкрити сайт» стає зайвим */
@media (min-width: 1101px) {
  .page__title .project__link::after {
    content: none;
  }
}

/* Каретка в кінці рядка назви — розкриває клієнта й розділи проекту.
   Тільки мобільна: на десктопі і те, і те стоїть розкритим */
.page__title-more {
  display: none;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  flex-shrink: 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.page__title-more svg {
  width: 16px;
  height: 16px;
  transition: transform 0.15s;
}
.page__title-more[aria-expanded="true"] {
  color: var(--c-primary);
}
.page__title-more[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

/* «Плюс» нового питання — у шапці сайту, перед аватаркою: під ним попап
   #issue-add. Раніше він стояв у рядку фільтрів проекту й був лише там;
   тепер питання заводять з будь-якої сторінки, тож і кнопка одна на весь
   сайт. Розмір під аватарку поруч (36px).
   Залита акцентним, а не м'яким тлом, як «плюси» всередині сторінок: у
   шапці навколо неї самі написи — логотип, меню, ім'я, — і блідим значком
   вона там губилась. Це головна дія сайту, і в шапці вона єдина заливка.
   Значок товщий (.icon--bold) і більший за звичайні 18px: у суцільній
   плашці тонкий хрестик плюса виглядає ще дрібнішим, ніж є.
   Клас лишився той самий — інших «плюсів» на сайті немає */
.add-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: var(--c-primary);
  color: #fff;
  cursor: pointer;
}
.add-btn svg {
  width: 20px;
  height: 20px;
}
.add-btn:hover {
  background: #3352c9;
}

/* Підказка «Додати питання» — та сама, що під «плюсом» проектів: у шапці
   значок стоїть без підпису, і сам собою він каже лише «щось додати».
   Праворуч від неї край вікна, тож підказка не центрується під кнопкою, а
   тримається її правого краю */
.add-btn::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--c-text);
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  padding: 5px 9px;
  border-radius: 6px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  z-index: 5;
}
.add-btn:hover::after {
  opacity: 1;
}

/* Дії «Звітів» проекту — «Додати гілку» і «Додати звіт» — стоять у тому
   самому місці рядка вкладок, що «плюс» на сторінці питань, і виглядають
   так само: акцентний колір на м'якому тлі, той самий розмір і радіус, що в
   .add-btn з .filter-btn. Різниця одна — вони з підписом: «плюс» у проекті
   один і зрозумілий сам собою, а тут дії дві, і значками вони б не
   розрізнялись.
   Кегль дрібніший за 14px кнопок форм: це дія шапки поруч із вкладками, а не
   кнопка, якою форму відправляють */
.branch-add,
.report-add {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 38px;
  flex-shrink: 0;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.branch-add:hover,
.report-add:hover {
  background: var(--c-primary);
  color: #fff;
}
.branch-add svg,
.report-add svg {
  width: 14px;
  height: 14px;
}

/* Підменю проекту: Питання / Звіти / Оплата / Інформація.
   Розбіг між вкладками тримає gap, а не горизонтальний паддінг посилань:
   так перша вкладка починається рівно під назвою проекту, а підкреслення
   активної не вилазить ліворуч за роздільник */
.submenu {
  display: flex;
  gap: 24px;
  flex-shrink: 0;
  /* роздільник шапки — рівно по ширині вкладок. Підкреслення активної
     лягає на нього через margin-bottom: -1px у .submenu__link */
  border-bottom: 1px solid var(--c-border);
}
.submenu__link {
  padding: 10px 0;
  margin-bottom: -1px;
  color: var(--c-text-soft);
  font-weight: 500;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.submenu__link:hover {
  color: var(--c-text);
  text-decoration: none;
}
.submenu__link--active {
  color: var(--c-primary);
  border-bottom-color: var(--c-primary);
  font-weight: 600;
}

/* Те саме підменю, але в шапці сторінки: вкладки розділу стоять у .page__head
   між назвою і фільтрами («Команда» — дашборд і статистика). Заголовок і
   вкладки — одне ціле, тож margin-right тримає їх поруч: без нього
   space-between рознесла б вкладки на середину рядка. Низ вкладок лягає на
   базову лінію заголовка — звідси align-self замість спільного центрування */
.submenu--page {
  margin-right: auto;
  align-self: flex-end;
}

/* ширин у фільтрів гілки й архіву немає навмисно — див. select.input */

/* ============ Повідомлення виконавця ============ */
/* Плашка над списком питань: аватарка, ім'я, текст — усе в один рядок.
   Це оголошення на весь проект («у відпустці з 12.03 по 18.03»), а не
   коментар до питання, тому воно й стоїть над таблицею окремо.
   Тло тепле, а не біле, як у .issues-box: інакше плашка злилася б із
   таблицею під нею і читалася б як її перший рядок */
.notices {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}
/* порожній контейнер лишається в шапці — у нього іконка «показати» повертає
   плашки, — тож ховаємо його атрибутом: display: flex перебиває hidden */
.notices[hidden] {
  display: none;
}
.notice {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 8px 8px 14px;
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  background: var(--c-orange-soft);
  box-shadow: var(--shadow);
}
/* ім'я не тисне текст і не тікає в багатокрапку: пару «аватарка + ім'я»
   лишаємо цілою, а місце віддає текст праворуч */
.notice .worker {
  flex-shrink: 0;
}
/* довге оголошення обривається багатокрапкою — рядок один, і плашка не
   має розповзатися на пів екрана. Повний текст читають у листі про нього */
.notice__text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--c-text);
}
/* хрестик той самий, що в шапках попапів (.legend__close): 30×30 без тла,
   підсвітка на наведенні. Тло тут світле, тому й підсвітка біла — сірий
   --c-bg на теплому тлі плашки виглядав би брудною плямою */
.notice__close {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.notice__close svg {
  width: 15px;
  height: 15px;
}
.notice__close:hover {
  background: var(--c-surface);
  color: var(--c-text);
}

/* На телефоні рядок один лишити не виходить: під ім'ям і хрестиком тексту
   лишається пів слова, і оголошення перетворюється на багатокрапку. Тому
   тут воно переходить під пару «аватарка + ім'я» й читається цілим —
   так само, як на мобільному згортається шапка проекту над цією плашкою.
   order міняє місцями текст і хрестик: у розмітці хрестик останній, і без
   нього він поїхав би на третій рядок, під текст, замість того щоб лишитись
   у першому — там, де його шукають */
@media (max-width: 700px) {
  .notice {
    flex-wrap: wrap;
    align-items: flex-start;
    padding-bottom: 12px;
  }
  .notice .worker {
    margin-right: auto;
  }
  .notice__close {
    order: 1;
    margin-top: -2px;
  }
  .notice__text {
    order: 2;
    flex-basis: 100%;
    white-space: normal;
    overflow: visible;
  }
}

/* ============ Таблиця питань ============ */
/* Плашка під таблицею, яка стоїть на сторінці сама, без згортних груп: біле
   тло, рамка й горизонтальна прокрутка широкої таблиці. `.issues-box` — під
   списком питань, `.table-box` — під гілками і оплатами всередині проекту,
   де таблиця вже не одна на клас (`.branches` і `.pays` у тій самій ролі).
   Там, де таблиця лежить у картці місяця чи проекту, прокрутку бере на себе
   сама картка (`.project__branches`, `.month__rows`), і плашка не потрібна */
.issues-box,
.table-box {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow-x: auto;
}
/* відступ до підсумку під таблицею — той самий, що між картками проектів і
   місяців (.project, .month). У .issues-box його немає: під списком питань
   нічого не стоїть */
.table-box {
  margin-bottom: 14px;
}
/* останній рядок межі не має — її роль грає нижній край плашки. У таблиць,
   які лежать у картках, таке правило своє (`.issues`, `.pays`, `.reports`);
   тут таблиця може бути будь-якою з них, тож питаємо про плашку */
.table-box tr:last-child td {
  border-bottom: none;
}


.issues {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  min-width: 900px;
}

/* Праві колонки затиснуті по вмісту, а не «на око»: колонка «Питання»
   гумова (width: auto) і забирає все, що вони віддадуть. Кожне число —
   це найдовший вміст плюс 24px паддінгів клітинки. Порядок колонок —
   виконавець, статус, оновлено, повідомлення, архів:
   178 = аватарка 28 + 10 + найдовше ім'я 116 + 24
   122 = найширша пігулка «До перевірки» 98 + 24
   132 = ім'я 62 + 8 + найдовша дата «30 кві» 38 + 24
    54 = бульбашка коментарів 30 + 24
    44 = кнопка архіву 32 + 4 зліва + 8 справа
   Разом 526 — решта рядка лишається назві питання.
   Під ім'я закладено 62px замість фактичних 49 у демо-даних: імена в базі
   бувають довші, а зайве обріжеться багатокрапкою (.upd__last).
   Вміст усіх п'яти притиснутий праворуч (правила нижче), тож вони стоять
   щільною групою біля правого краю, а не розповзаються по своїх колонках */
.issues__col-title  { width: auto; }
.issues__col-worker { width: 178px; }
.issues__col-status { width: 122px; }
/* автор останнього коментаря й дата — розкладка спільна з колонкою
   «Оновлено» в списку гілок (.upd) */
.issues__col-upd    { width: 132px; }
.issues__col-msg    { width: 54px; }
/* Кнопка архіву стоїть окремою колонкою без заголовка, а не всередині
   сусідньої: інакше вона була б останньою в клітинці, назва колонки
   вирівнювалась би по ній, а не по вмісту, і заголовок висів би над кнопкою.
   Підпису колонка не має — зате має знак питання легенди: 32px кнопки й
   4 + 8 полів обабіч і складають ці 44px */
.issues__col-archive { width: 44px; }

.issues th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--c-text-soft);
  padding: 10px 12px;
  background: #fafbfd;
  border-bottom: 1px solid var(--c-border);
  white-space: nowrap;
}
.issues th.issues__col-msg {
  text-align: center;
}
.issues th.issues__col-msg svg {
  width: 15px;
  height: 15px;
  vertical-align: middle;
}
/* Усе, що правіше за назву, вирівняне по правому краю своєї колонки — так
   колонки стоять щільною групою біля краю таблиці. Винятки — бульбашка
   коментарів (її колонка вузька, а заголовок у ній сам по собі іконка) і
   статус: обидві по центру */
.issues th.issues__col-worker,
.issues th.issues__col-upd,
.issues td.issues__worker,
.issues td.issues__upd {
  text-align: right;
}
/* Статус — пігулка по центру своєї колонки разом із заголовком: ширина
   пігулок гуляє від «Нове» до «До перевірки», і по правому краю вони
   стрибали б від рядка до рядка; центр тримає їх спільною вертикаллю */
.issues th.issues__col-status,
.issues td.issues__status {
  text-align: center;
}
/* Заголовок колонки виконавця стоїть над іменем, а не над аватаркою:
   правий край заголовка відсунуто рівно на аватарку з її відступом
   (28 + 10 понад 12px паддінга клітинки), тож ім'я лягає під слово
   «Виконавець», а кружечок виходить збоку, у власну вертикаль */
.issues th.issues__col-worker {
  padding-right: 50px;
}
/* Аватарка стоїть праворуч від імені й тримається правого краю колонки —
   так вона потрапляє в ту саму вертикаль, що й аватарки в картках на
   мобільному, і не розриває групу правих колонок зайвим стовпчиком кружечків
   посеред таблиці. row-reverse перевертає й вісь: flex-start у ньому — це
   правий край, тому притискаємо саме до start */
.issues td.issues__worker .worker {
  flex-direction: row-reverse;
  justify-content: flex-start;
}
/* у кнопки архіву власні 34px клікабельної площі, тож паддінг клітинки
   зайвий — з ним колонка роздувалась би вдвічі */
.issues td.issues__archive {
  padding-left: 4px;
  padding-right: 8px;
  text-align: right;
}
/* Знак питання легенди — над кнопками архіву. Поля клітинки ті самі, що в
   рядках під нею, а сама кнопка бере ширину кнопки архіву (32px), тож
   значок стає рівно в її вертикаль — не «десь праворуч», а точно над.
   Вертикальні поля зняті: 22px кнопки нижчі за рядок шапки, і з ними
   заголовок ставав би вищим за решту таблиці ні за що. По висоті значок
   тримає звичайне для клітинки вирівнювання по середині */
.issues th.issues__col-archive {
  padding: 0 8px 0 4px;
}
.issues th.issues__col-archive .states-legend {
  width: 32px;
  margin-left: auto;
}

/* Заголовок-посилання: сортує бекенд, каретка лише показує поточний стан.
   Сортування одностороннє, тож каретка завжди дивиться вниз і повороту на
   180° більше немає — «зворотного» порядку в жодного стовпця не існує.
   Неактивна колонка тримає каретку прозорою — щоб від ховера заголовок
   не сіпався по ширині */
.sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}
.sort:hover {
  color: var(--c-primary);
  text-decoration: none;
}
.sort__icon {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.15s;
}
.sort:hover .sort__icon {
  opacity: 0.5;
}
.sort--active {
  color: var(--c-primary);
}
.sort--active .sort__icon {
  opacity: 1;
}

/* Сортування за терміновістю — самотня каретка в жолобі перед «Питання»,
   рівно над маркерами важливості в рядках. Тексту біля неї немає, тож,
   на відміну від решти заголовків, вона не може бути повністю прозорою:
   інакше клікати не було б по чому */
.issues th.issues__col-title {
  position: relative;
}
/* паддінг збільшує зону кліку до 23px — сама каретка 11px, пальцем і мишею
   по ній не влучиш. left компенсує паддінг, щоб іконка лишалась рівно
   над маркерами в рядках */
.sort--prio {
  position: absolute;
  left: 6px;
  top: 50%;
  transform: translateY(-50%);
  padding: 6px;
}
.sort--prio .sort__icon {
  opacity: 0.4;
}
.sort--prio:hover .sort__icon,
.sort--prio.sort--active .sort__icon {
  opacity: 1;
}

.issues td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-border);
  vertical-align: middle;
}
.issues tr:last-child td {
  border-bottom: none;
}
.issues__row:hover {
  background: #f8faff;
}
.issues__row[hidden] {
  display: none;
}

/* Ліворуч у колонці — жолоб під маркер важливості. Місце зарезервоване в
   усіх рядках, і маркер стоїть у ньому абсолютом: якби іконка була звичайним
   inline-елементом, номери питань із маркером і без нього стояли б на різних
   вертикалях і колонка «рвалася» б. Заголовок колонки посунутий так само.
   Іконка типу питання в цьому жолобі не бере участі — вона живе в потоці
   колонки, див. .kind нижче */
.issues th.issues__col-title,
.issues td.issues__title-cell {
  padding-left: 32px;
}
.issues__title-cell {
  position: relative;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Важливість питання: колір рівня лежить у --prio-bar на самому рядку, а
   малюють його два різні правила — на десктопі смуга висить на першій
   клітинці (у <tr> при border-collapse: collapse немає власного фону й тіні),
   на мобільному, де рядок стає карткою-грідом, — на самому рядку.
   Звичайні питання й чернетки лишаються без --prio-bar, тож смуга в них
   прозора: смуга — знак того, що питання просять уперед черги, а чернетка
   взагалі не в черзі */
.issues__row--critical {
  --prio-bar: var(--c-red);
}
.issues__row--urgent {
  --prio-bar: var(--c-orange);
}
.issues__row--important {
  --prio-bar: var(--c-yellow);
}
.issues__row td:first-child {
  box-shadow: inset 3px 0 0 var(--prio-bar, transparent);
}

/* Іконка в жолобі: три стрілки — «критично», дві — «терміново», одна —
   «важливо». Рівень читається кількістю стрілок, а не лише кольором, —
   інакше маркер нічого не каже тому, хто не розрізняє відтінки червоного.
   Звичайні питання іконки не мають: у списку мають виділятися саме винятки.
   Стоїть поза посиланням, щоб не перефарбовуватись у синє при ховері назви;
   підказка — нативний title, бо клітинка обрізає вміст по overflow: hidden
   і css-тултіп у ній був би зрізаний */
/* Сам маркер — кнопка: клік відкриває попап зі зміною рівня (.prio-menu).
   Паддінг розганяє зону кліку до 26px — сама іконка 14px, пальцем по ній
   не влучиш, — а left його компенсує, щоб іконка лишалась рівно під
   кареткою сортування в заголовку. Той самий прийом, що й у .sort--prio */
.prio {
  position: absolute;
  left: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  padding: 6px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: inherit;
  cursor: pointer;
}
.prio:hover,
.prio[aria-expanded="true"] {
  background: var(--c-bg);
}
.prio svg,
.kind svg {
  width: 14px;
  height: 14px;
}
/* Тип питання: жучок — виправлення помилки. Місця під нього, на відміну від
   важливості, не резервуємо: іконка стоїть у потоці колонки й зсуває назву
   лише в тих рядках, де вона є, — тип читається як частина самої назви, а не
   як окрема колонка. Доробка маркера не має взагалі: у списку мають
   виділятися винятки, а не все підряд.
   Базовий колір нейтральний — його беруть маркери, що не мають власного */
.kind {
  display: inline-flex;
  vertical-align: -2px;
  margin-right: 6px;
  color: var(--c-text-soft);
  cursor: default;
}
/* жучок — темно-червоний і з товстішим обведенням (.icon--bold у розмітці):
   помилка на сайті клієнта важить більше за решту типів, і сірим значком
   у 2px вона губилася серед назв */
.kind--bug {
  color: var(--c-red-dark);
}
/* перекреслене око — звіт, якого клієнт не бачить (тільки «Звіти», тільки
   адміну). Око те саме, що в кнопки «Приховати» на «Команді» (.hide): там
   воно теж означає «є, але не всім видно». Колір базовий, сірий: сама по собі
   це службова помітка про видимість, а не оцінка роботи. Виправлення власної
   помилки під ним фарбується бордовим — див. .reports__row--unpaid нижче */
.kind--hidden {
  color: var(--c-text-soft);
}
/* значок питання, що вже в архіві. Колір той самий, що в кнопки повернення
   в кінці рядка (.archive--restore), — у легенді значок має бути тим самим,
   що й у списку. Свій клас, а не .archive--restore: там на наведення
   вмикається зелена підкладка кнопки, а тут кнопки немає */
.kind--archived {
  color: var(--c-green);
}
/* «звичайна» терміновість і тип «доробка» — це відсутність маркера: issue.js
   вішає на них hidden. Без цього правила його перебиває display вище і
   порожня іконка лишається займати місце в рядку */
.kind[hidden] {
  display: none;
}
.issues__row--archived .kind {
  opacity: 0.45;
}
/* «Чернетка» — олівець, а не стрілка: питання записали, але в чергу ще не
   поставили. Сірий того ж тону, що й «звичайно», бо це не щабель терміновості
   й теплим кольорам поруч не рівня; видно його завжди — тим і відрізняється
   від «звичайно», де маркер проступає лише на ховері */
.prio--draft {
  color: var(--c-text-soft);
}
.prio--critical {
  color: var(--c-red);
}
.prio--urgent {
  color: var(--c-orange);
}
.prio--important {
  color: var(--c-yellow);
}
.prio--normal {
  color: var(--c-text-soft);
}
/* Звичайне питання маркера не має — у списку мають виділятися винятки.
   Кнопка все одно стоїть у жолобі: без неї рівень не було б звідки підняти.
   Проступає рискою на ховері рядка й на фокусі з клавіатури.
   Селектор із рядком, а не голий .prio--normal, — щоб узяти гору над
   притлумленням архівного рядка нижче */
.issues__row .prio--normal {
  opacity: 0;
}
.issues__row:hover .prio--normal,
.prio--normal:focus-visible,
.prio--normal[aria-expanded="true"] {
  opacity: 1;
}
/* архівне питання притлумлене цілком — маркер теж */
.issues__row--archived .prio {
  opacity: 0.45;
}
/* Подвійний номер: гілка.питання (1.47) — гілку колонкою більше не
   показуємо, тож номер лишається єдиною ознакою, з якої вона гілка.
   Живе всередині посилання, тому колір веде за назвою при ховері */
.issues__num {
  margin-right: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
  font-variant-numeric: tabular-nums;
}
.issues__title {
  font-weight: 600;
  color: var(--c-text);
}
.issues__title:hover,
.issues__title:hover .issues__num {
  color: var(--c-primary);
}
/* питання з непрочитаними повідомленнями */
.issues__row--unread .issues__title {
  font-weight: 700;
}
/* архівне питання притлумлене — як архівна гілка */
.issues__row--archived .issues__num,
.issues__row--archived .issues__title {
  color: var(--c-text-soft);
}

/* Статус — кольори ті самі, що в кружечків .dot на списку проектів */
.issues__status {
  white-space: nowrap;
}
/* Усі пігулки колонки однакової ширини — по найширшій «До перевірки» (98,
   рівно вміст клітинки: 122 колонки мінус 12+12 паддінга). Інакше колонка
   читалась би рваним стовпчиком: коротке «Нове» вдвічі вужче за сусідів,
   і центрування тільки розгойдувало б обидва краї. Текст лишається по центру */
.issues__status .status {
  min-width: 98px;
}
.status {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
}
.status--processing { background: #4dabf7; }
.status--work       { background: #fab005; }
.status--wait       { background: #f76707; }
.status--check      { background: #a61e4d; }
.status--done       { background: #2f9e44; }

/* Лічильник повідомлень — бульбашка коментаря з кількістю всередині.
   Число не всередині <svg>, а окремим шаром поверх нього: у svg-тексту
   свій рендер шрифта й керувати кеглем та жирністю з CSS незручно.

   Вона ж і перемикач «прочитано / не прочитано»: залита бульбашка каже, що
   в питанні є непобачене, клік по ній каже зворотне. Тому це кнопка, а не
   span — своєї рамки й фону в неї немає, лише курсор і підказка (тултіп
   спільний, вище) */
.issues__msg {
  text-align: center;
}
.msg {
  position: relative;
  display: inline-flex;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  background: none;
  /* число всередині бере свій кегль саме, а от гарнітуру кнопка інакше взяла
     б системну — і лічильник стояв би не тим шрифтом, що решта рядка */
  font: inherit;
  color: var(--c-text-soft);
  vertical-align: middle;
  cursor: pointer;
  transition: color 0.15s;
}
/* наведення підсвічує бульбашку тим самим кольором, яким вона горить
   непрочитаною: видно, що клік по ній щось робить */
.msg:hover {
  color: var(--c-primary);
}
.msg__icon {
  width: 100%;
  height: 100%;
  /* волосяне обведення: бульбашка тут велика (30px) і поруч із числом
     всередині, тож лінія в 2 одиниці, як у решти іконок, забила б її.
     Заголовок колонки бере ту саму іконку звичайною товщиною */
  stroke-width: 0.75;
}
/* тіло бульбашки в системі координат іконки — від y=3 до y=17, тобто його
   центр на 10/24 висоти. Число центруємо по тілу, а не по всій іконці,
   інакше воно з'їжджає на хвостик: висота 83% дає центр рівно на 41.7% */
.msg__count {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 83%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 10px, а не 11: усередині обведення бульбашки лишається 20px, і на цьому
     кеглі тризначний лічильник (найгірший реальний випадок) вкладається
     з запасом. Від'ємний трекінг додає ще трохи місця саме багатозначним */
  font-size: 10px;
  font-weight: 700;
  letter-spacing: -0.2px;
  line-height: 1;
}

/* є непрочитані — бульбашка заливається, число стає білим. Скільки саме
   непрочитаних, ніде не показуємо: у списку важливий сам факт */
.msg--new {
  color: var(--c-primary);
}
.msg--new .msg__icon {
  fill: currentColor;
}
.msg--new .msg__count {
  color: #fff;
}
/* архівне питання притлумлене цілком — бульбашка теж */
.issues__row--archived .msg {
  opacity: 0.55;
}

/* Хто залишив останній коментар — ім'я і літера прізвища, без аватарки.
   Стоїть у колонці «Оновлено» перед датою, окремої колонки під нього немає.
   min-width: 0 дає задовгому імені обрізатись багатокрапкою, а не тиснути
   дату з кнопкою архіву. На мобільному не виводиться (правило в медіазапиті) */
.upd__last {
  min-width: 0;
  font-size: 13px;
  color: var(--c-text-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* дата з кнопкою архіву — розкладка спільна з гілками (.upd) */
.issues__upd {
  text-align: right;
  font-size: 13px;
  color: var(--c-text-soft);
  white-space: nowrap;
}

.issues__empty {
  padding: 24px;
  text-align: center;
  color: var(--c-text-soft);
}

/* Довантаження списку порціями — смуга на всю ширину картки під таблицею,
   відбита від останнього рядка тією ж лінією, що ділить рядки між собою.
   У прототипі кнопка неробоча: числа показують, скільки питань уже в списку
   з усіх, що підпали під фільтри */
.load-more {
  display: block;
  width: 100%;
  padding: 13px;
  /* the site draws it as a link to the next portion, the prototype as a
     button: an <a> needs the centring a <button> has by itself */
  text-align: center;
  text-decoration: none;
  border: 0;
  border-top: 1px solid var(--c-border);
  background: none;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--c-primary);
  cursor: pointer;
}
.load-more:hover {
  background: var(--c-bg);
}
.load-more__count {
  color: var(--c-text-soft);
  font-weight: 500;
}
/* поки порція вантажиться: abc-response.js вішає .abcr-wait на натиснуте
   посилання й знімає її, коли рядки вже в списку. Другий клік він і сам
   ігнорує, поки клас на місці — тут лишається тільки показати це */
.load-more.abcr-wait {
  color: var(--c-text-soft);
  cursor: progress;
}

/* --- мобільна версія сторінки проекту --- */
@media (max-width: 1100px) {
  .project__domain {
    display: none;
  }

  /* фільтри гілки й архіву на всю ширину ставить спільне правило
     select.input у медіазапиті вище */
  /* два блоки в рядок тут не вміщаються: кожен рядок шапки розкладається
     в стовпчик на всю ширину. Бічні відступи бере на себе сам рядок —
     .page на мобільному йде без них, щоб картки лягали на всю ширину */
  .project-head__row {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 0 12px;
  }
  /* вирівнювання по центру й по низу — десктопна історія (назва з клієнтом
     в один рівень, вкладки на лінії). У стовпчику воно притисло б блоки до
     середини й правого краю, тож повертаємо стандартне stretch. Правила
     адресні: загальне .project-head__row програло б їм у специфічності */
  .project-head__row--title,
  .project-head__row--tools {
    align-items: stretch;
  }
  .project-head__row--title {
    padding-bottom: 10px;
  }
  /* Роздільника тут немає зовсім: вкладки, на яких він висить на десктопі,
     згорнуті під кареткою, а під фільтрами лінія зайва — картки питань і так
     відбиті від шапки власними border-top.
     Разом із лінією пішли й обидва паддінги рядка: вони тримали повітря
     навколо неї, а без неї просто складалися з відступами сусідів у діру —
     10px знизу від назви плюс 10px зверху й ще 16px margin-bottom шапки
     знизу. Тепер зазор над фільтрами дає сама назва, а під ними — шапка */
  .project-head__row--tools {
    padding-top: 0;
    padding-bottom: 0;
  }
  .project-head {
    margin-bottom: 12px;
  }
  .project-head .submenu {
    border-bottom: none;
  }
  /* у стовпчику шапки сторінки вкладки стають окремим рядком на всю
     ширину: притискати їх до правого краю нема до чого — заголовок стоїть
     уже не поруч, а над ними */
  .submenu--page {
    align-self: stretch;
    margin-right: 0;
  }
  .page__title-more {
    display: flex;
  }
  /* клієнт і вкладки згорнуті: у верхньому рядку лишається сама назва
     з кареткою, у нижньому — фільтри. Розкриває їх .project-head--open,
     який вішає app.js */
  .page__client,
  .project-head .submenu {
    display: none;
  }
  .project-head--open .page__client {
    display: flex;
  }
  /* вкладки розходяться на всю ширину рядка — на екрані в 375px вони
     стояли купкою ліворуч, а праворуч лишалася порожня половина */
  .project-head--open .submenu {
    display: flex;
    justify-content: space-between;
    overflow-x: auto;
  }
  /* Підкреслення активної вкладки лягало на роздільник шапки через від'ємний
     margin — тут роздільника немає, а зайвий піксель вилазив за низ .submenu
     й піднімав уздовж її правого краю вертикальну смугу прокрутки. Збоку від
     вкладок вона читалася як незрозумілий бордер */
  .project-head .submenu__link {
    margin-bottom: 0;
  }

  /* overflow тут потрібен був лише під горизонтальну прокрутку широкої
     таблиці — на мобільному вона розкладена в картки й нікуди не їде.
     Разом із прокруткою він зрізав і тултіп «В архів» у першому рядку:
     той іде вгору й вилазив за верхній край картки, під шапку проекту */
  .issues-box,
  .table-box {
    border: none;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
  }

  /* Без рамки плашки низ списку лишався відкритим: рядки-картки мають саму
     лише верхню межу, і після останньої не було нічого, крім сірого тла
     сторінки. Межа знизу — та сама лінія, що між картками, — і закриває
     список. Питаємо про таблицю останньою в плашці: під нею може стояти
     «Показати ще», і тоді лінію під останнім рядком малює вже кнопка
     своїм border-top */
  .table-box > table:last-child tr:last-child {
    border-bottom: 1px solid var(--c-border);
  }
  /* Підсумок стоїть одразу за цією межею: 14px у плашки — відступ між двома
     картками на десктопі, а тут карток немає, і від лінії до чисел лишається
     сам лише верхній паддінг підсумку — той самий, з яким стоїть від своєї
     межі кожен рядок. Питаємо про підсумок за плашкою: там, де під нею
     нічого немає (сторінка доступів), відступ тримає низ сторінки */
  .table-box:has(+ .totals) {
    margin-bottom: 0;
  }

  /* таблиця питань розкладається в картки у два рядки:
     1) номер із назвою, а праворуч кнопка архіву
     2) той самий порядок, що й у колонках десктопа, — виконавець, статус,
        дата й лічильник коментарів */
  .issues {
    display: block;
    min-width: 0;
    table-layout: auto;
  }
  .issues thead {
    display: none;
  }
  .issues tbody {
    display: block;
  }
  /* колонки: виконавець | статус | дата | лічильник із кнопкою архіву.
     Гумова тільки перша: виконавець забирає все, що лишили три вузькі
     сусідки, і сам обрізає задовге ім'я багатокрапкою. Назва питання лягає
     на перші три колонки, кнопка архіву — у четверту, над лічильником.
     Четверта не auto, а minmax: мінімум — ширина кнопки архіву (з чистим
     auto грід роздав би їй частину ширини виконавця, і між лічильником та
     кнопкою зяяла б діра), а вгору вона росте під тризначний лічильник.
     Окремої колонки під лічильник немає навмисне: з нею між датою й
     бульбашкою лишався зайвий жолоб, і дата відпливала від іконки, до
     якої належить */
  .issues__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto minmax(28px, auto);
    gap: 6px 10px;
    padding: 10px 12px;
    border-top: 1px solid var(--c-border);
  }
  .issues__row:hover {
    background: none;
  }
  /* смуга важливості переїжджає з клітинки на саму картку — інакше вона
     стояла б не по краю, а на 12px усередині, від паддінга рядка */
  .issues__row {
    box-shadow: inset 3px 0 0 var(--prio-bar, transparent);
  }
  .issues__row td:first-child {
    box-shadow: none;
  }
  .issues td {
    display: block;
    border: none;
    padding: 0;
  }

  /* номер із назвою в один рядок на чотири перші колонки — праворуч
     лишається сама кнопка архіву. Обрізання успадковане з десктопа
     (nowrap + ellipsis на клітинці), тут лишається тільки min-width: 0,
     без нього грід не дасть їй стиснутись.
     Паддінг клітинок обнулено вище, тож жолоб під маркер важливості
     відміряємо заново від лівого краю картки — сам маркер стає в нього
     своїм left: 0 */
  .issues td.issues__title-cell {
    grid-column: 1 / 4;
    grid-row: 1;
    min-width: 0;
    padding-left: 20px;
    font-size: 15px;
  }
  /* зона кліку росте лише вправо: з від'ємним left її ліву половину
     зрізав би overflow: hidden клітинки */
  .prio {
    left: 0;
    padding-left: 0;
  }
  /* ховера на тачі немає, тож «звичайний» маркер видно завжди — інакше
     кнопка була б невидимою пасткою поруч із назвою */
  .issues__row .prio--normal {
    opacity: 0.35;
  }
  .issues__row .prio--normal[aria-expanded="true"] {
    opacity: 1;
  }
  /* кнопка архіву стоїть сама в першому рядку, навпроти назви */
  .issues td.issues__archive {
    grid-column: 4;
    grid-row: 1;
    justify-self: end;
    align-self: center;
    padding: 0;
  }

  /* Другий рядок повторює порядок десктопних колонок: виконавець, статус,
     дата, лічильник коментарів. Усе вирівняне по центру рядка — у трьох
     різних кеглів (12px дата, 12px лічильник, пігулка статусу) різні
     рядкові бокси, і з align-self: start вони стояли б сходинкою */
  .issues td.issues__worker {
    grid-column: 1;
    grid-row: 2;
    align-self: center;
    min-width: 0;
  }
  /* на десктопі аватарка стоїть праворуч від імені, бо тримається правого
     краю своєї колонки. Тут виконавець відкриває рядок, тож повертаємо
     звичайний порядок — кружечок першим, від лівого краю картки */
  .issues td.issues__worker .worker {
    flex-direction: row;
  }
  /* у картці пігулка вже не колонка таблиці, а значення в ряду з датою:
     фіксована ширина з десктопа тут тільки роздувала б короткі статуси,
     тож повертаємо ширину по тексту й тиснемо до правого краю комірки */
  .issues td.issues__status {
    grid-column: 2;
    grid-row: 2;
    align-self: center;
    text-align: right;
  }
  .issues td.issues__status .status {
    min-width: 0;
  }
  .issues td.issues__upd {
    grid-column: 3;
    grid-row: 2;
    align-self: center;
    font-size: 12px;
  }
  /* лічильник закриває рядок під кнопкою архіву — так його правий край
     стає в ту саму вертикаль, що й кнопка над ним, а від дати його відділяє
     сам жолоб сітки, без порожньої колонки між ними */
  .issues td.issues__msg {
    grid-column: 4;
    grid-row: 2;
    justify-self: end;
    align-self: center;
  }

  /* автор останнього коментаря — тільки десктоп */
  .issues .upd__last {
    display: none;
  }
}

/* ============ Операційка ============ */
/* Список питань тут той самий, що на сторінці проекту, — та сама таблиця
   .issues з усіма її правилами. Своє в розділі лише одне: колонка проекту
   між назвою питання й виконавцем. Тому й секція коротка: описує вона саме
   цю колонку і те, як через неї змінилися ширини */

/* 180px — найдовша назва проекту («Інтернет-магазин одягу», 150px) плюс 24
   паддінгів клітинки і трохи запасу: у базі назви бувають довші, зайве
   обріжеться багатокрапкою */
.issues__col-project { width: 180px; }

/* Таблиця ширшає рівно на цю колонку, тож і мінімум треба перерахувати:
   1080 = проект 180 + виконавець 178 + статус 122 + оновлено 132 +
   повідомлення 54 + архів 44 (разом 710) і 370 назві питання. Менше їй не
   лишати: назва питання довша за назву проекту, а обрізаються обидві */
.page-ops .issues {
  min-width: 1080px;
}

/* У виконавця колонки «Виконавець» немає — у його списку в ній стояло б те
   саме ім'я в кожному рядку. Таблиця вужчає рівно на неї: 902 = 1080 − 178 */
.page-ops .issues--noworker {
  min-width: 902px;
}

/* Проект підписаний тихіше за питання: у рядку головне — саме питання, а
   проект каже, де воно. Ліворуч, а не праворуч, як решта колонок: це друга
   текстова колонка поспіль, і рвати її з назвою по різних краях нема за чим */
.issues td.issues__project {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.issues__project-link {
  font-size: 13px;
  color: var(--c-text-soft);
}
.issues__project-link:hover {
  color: var(--c-primary);
}
/* архівне питання притлумлене цілком — назва проекту теж */
.issues__row--archived .issues__project-link {
  opacity: 0.6;
}

/* --- мобільна версія «Операційки» --- */
@media (max-width: 1100px) {
  /* Таблиця розкладається в картки й нікуди не їде, тож мінімум знімаємо —
     як це робить для всіх .issues правило вище. Повторюємо його тут своїм
     селектором: у спільного специфічності менше, і 1080px лишалися б, а
     разом з ними й горизонтальна прокрутка всієї сторінки */
  .page-ops .issues {
    min-width: 0;
  }

  /* Картка питання дістає третій рядок. Проект стоїть окремим рядком під
     назвою, а не в ряду з виконавцем і статусом: у другому рядку картки й
     так чотири значення, і п'яте — та ще й найдовше — тиснуло б їх усі.
     Під назвою ж він читається як підпис до неї, чим і є */
  .page-ops .issues td.issues__project {
    grid-column: 1 / -1;
    grid-row: 2;
  }
  /* решта другого рядка з'їжджає на третій — порядок у ньому лишається
     десктопним: виконавець, статус, дата, лічильник */
  .page-ops .issues td.issues__worker,
  .page-ops .issues td.issues__status,
  .page-ops .issues td.issues__upd,
  .page-ops .issues td.issues__msg {
    grid-row: 3;
  }
  /* Без виконавця гумова перша колонка лишалася б порожньою, а решта рядка
     тислася до правого краю дірою на пів картки. Тому рядок відкриває
     статус — і не пігулкою по правому краю комірки, як під іменем, а від
     лівого краю картки, на місці виконавця */
  .page-ops .issues--noworker td.issues__status {
    grid-column: 1;
    text-align: left;
  }
}

/* ============ Сторінка питання ============ */
/* Шапка проекту тут та сама, що й у списку питань, тільки назва проекту вже
   не заголовок сторінки, а посилання назад: заголовок — саме питання.
   Клас лишається .page__title, тож розкладка й кегль спільні з project.html */
.page--issue .page__title-text {
  color: inherit;
  /* каретка назад — усередині самого посилання, тож рядок і кегль спільні */
  display: flex;
  align-items: center;
  gap: 6px;
}
.page--issue .page__title-text:hover {
  color: var(--c-primary);
  text-decoration: none;
}

/* Каретка назад перед назвою проекту. Окремого символа «вліво» у спрайті
   немає — беремо ту саму каретку, що й у рядку назви на мобільному, і
   повертаємо її чвертю оберту: «v» стає «<» */
.page__title-back {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  transform: rotate(90deg);
  color: var(--c-text-soft);
}
.page--issue .page__title-text:hover .page__title-back {
  color: inherit;
}

/* Один рядок: терміновість, тип, назва питання, одразу за нею статус із
   виконавцем, а по правому краю — три крапки з діями.
   Розкладка тут не флексова, а звичайний текстовий потік: назва — inline-
   елемент, тож статус із виконавцем ідуть за її останнім словом і самі
   переносяться на новий рядок, коли назва довга. Флекс так не вміє: він або
   тиснув би назву, лишаючи стан на місці, або зносив би її вниз цілим
   елементом разом з іконками стану.
   position + padding-right — під ті самі три крапки: у текстовому потоці вони
   стали б одразу за виконавцем, а не з краю, тож кнопка на абсолюті, а місце
   під неї тримає відступ шапки */
.issue-head {
  position: relative;
  /* під дві кнопки в куті: гілочку пов'язаних питань і три крапки дій */
  padding-right: 74px;
  margin-bottom: 16px;
}

.issue-head__title {
  min-width: 0;
  /* назва в рядку стану — не блок: інакше статус з виконавцем ніколи не
     стали б поруч з нею */
  display: inline;
  /* власного відступу зліва немає: його відміряють іконки стану своїм
     margin-right із .kind */
  font-size: 20px;
  font-weight: 700;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
/* номер «гілка.питання» — той самий формат, що й у списку (.issues__num) */
.issue-head__num {
  margin-right: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--c-text-soft);
  font-variant-numeric: tabular-nums;
}

/* Контейнер стану прозорий: display: contents розпускає терміновість, тип,
   назву, статус і виконавця в один текстовий рядок .issue-head. Обгортка
   лишається в розмітці заради мобільного, де вона знову стає флекс-рядком */
.issue-head__meta {
  display: contents;
}

/* Маркери терміновості й типу стоять на базовій лінії назви, а не на -2px, як
   у рядку списку: там зсув рахований під текст у 14px, а тут поруч назва у
   20px. Збіг точний — іконка має 14px, і рівно стільки ж має велика літера
   назви, тож від базової лінії іконка займає саме її висоту й читається з
   назвою однією лінією */
.issue-head__prio,
.issue-head__kind {
  vertical-align: baseline;
}

/* Статус із виконавцем — одразу за назвою, одним inline-блоком. Обгортка тут
   не косметична: рядок рветься перед нею (у розмітці там пропуск), а всередині
   рвати нема де, тож на новий рядок статус і виконавець їдуть удвох. Без неї
   браузер має право перенести виконавця самого, лишивши статус висіти в кінці
   рядка назви */
.issue-head__state {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
  /* підйом над базовою лінією замість middle: рівняємось по середині великих
     літер назви (базова лінія мінус пів її висоти), а middle брав би за
     орієнтир зріст шрифту самої шапки — плашка з аватаркою сідали б нижче */
  vertical-align: 2px;
}

.issue-head__side {
  display: flex;
  align-items: center;
  margin-left: 10px;
}
.issue-head__side .worker {
  min-width: 0;
}
/* аватарка виконавця в шапці питання зайва: поруч і так стоїть ім'я, а
   кружечок ще й тягнув рядок угору — з ним він був на 8px вищий за саму
   назву. На мобільному те саме: ім'я стоїть поруч і в рядку стану, а без
   кружечка той рядок ще й нижчий */
.issue-head__side .worker__avatar {
  display: none;
}

/* Три крапки — по правому краю рядка назви, а перед ними гілочка пов'язаних
   питань. Кнопка та сама, що й у шапці повідомлення, тільки більша: у рядку
   заголовка дрібна губилася б. Обидві однакові — різняться лише іконкою й
   тим, який край рядка тримають */
.issue-head__tree,
.issue-head__more {
  position: absolute;
  /* кнопка вища за рядок назви (32px проти 27px), тож із top: 0 вона сідала б
     нижче за неї; підйом на різницю ставить її центр на середину назви */
  top: -2px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
/* крапки тримають правий край, гілочка стоїть перед ними — на ширину
   кнопки з дрібним просвітом */
.issue-head__more {
  right: 0;
}
.issue-head__tree {
  right: 34px;
}
.issue-head__tree svg,
.issue-head__more svg {
  width: 16px;
  height: 16px;
}
.issue-head__tree:hover,
.issue-head__tree[aria-expanded="true"],
.issue-head__more:hover,
.issue-head__more[aria-expanded="true"] {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Поле правки назви стоїть на місці самої назви й тим самим кеглем — рядок
   не стрибає, коли назву починають правити. Рамка синя, як у поля правки
   повідомлення: це те саме редагування на місці, тільки в один рядок */
.issue-head__rename {
  width: min(100%, 560px);
  padding: 1px 8px;
  border: 1px solid var(--c-primary);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text);
  font: inherit;
  outline: none;
}

/* архівне питання притлумлене — як архівний рядок у списку */
.issue-head--archived .issue-head__title,
.issue-head--archived .issue-head__num {
  color: var(--c-text-soft);
}
.issue-head--archived .kind {
  opacity: 0.45;
}

/* Переписка — одна картка на всю гілку, повідомлення в ній розділені
   лінією. Окремі картки під кожне повідомлення дали б смугастий список із
   дірками між ними, а читається гілка суцільним текстом.
   Власного відступу знизу картка не має: гілка — останнє на сторінці (форма
   відповіді лежить усередині неї), і до підвалу відбиває нижнє поле .page,
   те саме, що на всіх сторінках. Відступ поверх нього давав зайве повітря */
.thread {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Аватарка ліворуч, усе інше — колонкою праворуч. minmax(0, 1fr) обов'язковий:
   без нього довге слово чи посилання в тексті розсуває грід за межі картки */
.message {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px;
  padding: 16px 20px;
  border-top: 1px solid var(--c-border);
}
.message:first-child {
  border-top: none;
}

/* Кольори ті самі, що в кружечків клієнта й виконавця, — колір закріплений
   за людиною, тож у гілці її видно тим самим, що й у списку питань */
.message__avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: start;
}
/* завантажена аватарка лягає в той самий кружечок замість ініціалів */
.message__avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}
.message__avatar--teal   { background: #0c8599; }
.message__avatar--green  { background: #37b24d; }
.message__avatar--blue   { background: #1c7ed6; }
.message__avatar--purple { background: #7048e8; }
.message__avatar--orange { background: #f76707; }
.message__avatar--pink   { background: #c2255c; }
/* Останні чотири — з палітри виконавців (.worker__avatar--*), тими самими
   значеннями: колір закріплений за людиною, і в гілці пишуть усі, кого видно
   в списках, а там кольорів десять. Сірий дістається ще й авторові, якого в
   `users` більше немає: у нього ні імені, ні ініціалів */
.message__avatar--brown  { background: #846358; }
.message__avatar--red    { background: #c92a2a; }
.message__avatar--lime   { background: #5c940d; }
.message__avatar--gray   { background: #495057; }

/* Ім'я, роль і час в одному рядку; час притиснутий до правого краю
   своїм margin-left. wrap — щоб на вузькому екрані час зіскочив під ім'я */
.message__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-bottom: 6px;
}
/* Повідомленням буває сама лише зміна стану питання — без тексту й вкладень.
   Тоді шапка в тілі остання, і відступ під нею вже нічого не відділяє */
.message__head:last-child {
  margin-bottom: 0;
}
.message__author {
  font-weight: 700;
}
/* «Адмін» у гілці — тим самим чорним, що й справжні імена: поруч із підписом
   тепер стоїть сірий стан питання, і приглушений підпис злився б із ним в
   одну сіру смугу. На «Платежах» .admin лишається тихішим, як і був */
.message__author.admin {
  color: inherit;
}
/* Статус повідомлення — пігулка сіра, без кольорів списку: у гілці вона
   лише каже, у якому стані лишили питання, і не має конкурувати з тим
   статусом, що стоїть у шапці */
.message__status {
  padding: 1px 8px;
  border-radius: 20px;
  background: var(--c-bg);
  font-size: 12px;
  font-weight: 500;
  color: var(--c-text-soft);
}

/* Стан питання на час повідомлення — стрілки терміновості, жучок і статус
   одним блоком одразу за іменем, на місці колишньої ролі автора: з якого
   боку людина, видно з імені й аватарки, а от у якому стані лишили питання
   — ні, і саме про це в гілці питають.
   Маркери стоять без своїх кольорових класів (.prio--*, .kind--*), тож
   беруть сірий від базового .kind: це позначка на полях, а не маркер, що
   має перетягувати увагу з тексту, — колір лишається за шапкою.
   align-self: center — рядок шапки вирівняний по базовій лінії тексту, а
   в блока з іконок своєї базової лінії, по якій його ставити, немає */
.message__state {
  display: inline-flex;
  align-self: center;
  align-items: center;
  flex-shrink: 0;
}
.message__time {
  margin-left: auto;
  font-size: 12px;
  color: var(--c-text-soft);
  white-space: nowrap;
}
/* Слід правки — коротке «ред.» перед часом: у гілці досить бачити, що текст
   міняли, а коли саме — питають рідко, тож точний час лежить у довідці під
   трьома крапками. Мітку ставить бекенд, і лише в правлених повідомленнях:
   сама її наявність і означає, що текст редагували.
   Правий край рядка тримає той, хто в ньому перший з пари: коли мітка є,
   вона й відсуває обох праворуч замість часу */
.message__edited {
  margin-left: auto;
  font-size: 12px;
  color: var(--c-text-soft);
  white-space: nowrap;
  cursor: default;
}
/* «ред.» і час — пара про одне й те саме, тож між ними проміжок менший за
   загальний gap рядка: мітка читається як частина дати, а не як ще один
   напис поруч. Правий край тримає мітка, тому auto знімаємо саме з часу */
.message__edited + .message__time {
  margin-left: -6px;
}

/* Текст повідомлення — один <p> на все, переноси рядків через <br>.
   Ні списків, ні кількох абзаців: користувач набирає звичайний текст у
   textarea, і форматувати його нема кому — бекенд лише міняє переноси
   на <br>, а решту екранує */
.message__text {
  overflow-wrap: anywhere;
}

/* Вкладення — плитки під текстом повідомлення */
.message__files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
  list-style: none;
}
.file {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* плитка не ширша за свій рядок: довге ім'я файла обрізається
     багатокрапкою, а не розсовує форму чи лізе за край картки */
  max-width: 100%;
  min-width: 0;
  padding: 5px 10px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-bg);
  color: var(--c-text);
  font-size: 13px;
  font-weight: 500;
}
/* стискається саме ім'я — розмір і хрестик мають лишитись цілими */
.file__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
a.file:hover {
  border-color: var(--c-primary);
  color: var(--c-primary);
  text-decoration: none;
}
.file svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--c-text-soft);
}
a.file:hover svg {
  color: inherit;
}
.file__size {
  flex-shrink: 0;
  color: var(--c-text-soft);
  font-size: 12px;
  font-weight: 400;
}

/* Межа прочитаного. Лінію тягне ::after, а не border на самому блоці:
   так підпис лишається зліва, а лінія добирає рівно решту ширини.
   Повідомлення під роздільником свою верхню межу гасить — інакше під
   кольоровою лінією йшла б ще одна, сіра */
.thread__new {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 20px;
  border-top: 1px solid var(--c-border);
  color: var(--c-primary);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.thread__new::after {
  content: "";
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: 0.3;
}
.thread__new + .message {
  border-top: none;
}

/* Форма відповіді. Базово це окрема картка під гілкою, а не всередині неї:
   гілку можна дочитати до кінця, і форма не виглядає ще одним повідомленням.
   На issue форма лежить усередині картки гілки — див. .thread
   .compose нижче.
   Розкладка при цьому та сама, що в .message: аватарка збоку, все інше у
   правій колонці. Ширина колонки, проміжок і паддінги картки збігаються з
   повідомленням — тож поле вводу починається рівно там, де починається
   текст переписки вище. Міняєте одне — міняйте обидва */
.compose {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 20px;
}
/* .input тут не годиться: у нього свої паддінги під однорядкові поля.
   resize лишаємо вертикальний — issue.js тягне висоту під текст сам,
   але ручне збільшення нікому не заважає */
.compose__field {
  display: block;
  width: 100%;
  min-height: 88px;
  max-height: 320px;
  padding: 10px 12px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text);
  font: inherit;
  resize: vertical;
  outline: none;
}
.compose__field:focus {
  border-color: var(--c-primary);
}

/* вибрані файли — ті самі плитки, що й у повідомленні, плюс хрестик */
.compose__files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
  list-style: none;
}
.compose__files[hidden] {
  display: none;
}

.compose__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
}
/* Ряд без «Прикріпити файл»: на сайті вкладень у формі поки немає (файли
   лежать у бакеті, і віддавати їх нікому — SCHEMA.md §6), а сама лише кнопка
   при space-between стала б ліворуч. У прототипі вона по правому краю */
.compose__actions--send {
  justify-content: flex-end;
}
/* сам <input type="file"> схований у підписі, тож клік по тексту відкриває
   діалог вибору файлів без жодного JS */
.compose__attach {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--c-text-soft);
  font-weight: 500;
  cursor: pointer;
}
.compose__attach:hover {
  color: var(--c-primary);
}
.compose__attach svg {
  width: 16px;
  height: 16px;
}


/* Форма всередині картки гілки (варіант «опис колонкою»): переписка й
   відповідь тут — один блок, бо повідомлень може не бути зовсім, і дві
   картки поспіль читалися б як дірка між ними. Власної картки форма при
   цьому не має — лишається сама розкладка, а від останнього повідомлення
   її відбиває звичайна риска, така сама, як між повідомленнями.
   Коли гілка порожня, форма стає першою в картці — і риску знімає */
.thread .compose {
  border: none;
  border-top: 1px solid var(--c-border);
  border-radius: 0;
  background: none;
  box-shadow: none;
}
.thread .compose:first-child {
  border-top: none;
}

/* Три крапки — дії з повідомленням. Стоять останніми в рядку шапки, за
   часом: час притиснутий праворуч своїм margin-left, тож кнопка йде
   одразу за ним. order лишає її крайньою й тоді, коли на мобільному час
   зіскакує на власний рядок */
.message__more {
  order: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  margin: -4px -6px -4px 0;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.message__more svg {
  width: 16px;
  height: 16px;
}
.message__more:hover,
.message__more[aria-expanded="true"] {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Редагування — текст замінюється полем прямо на місці повідомлення.
   Саме повідомлення не ховаємо цілком: автор, час і вкладення лишаються
   на видноті, міняється тільки текст */
.message--editing .message__text {
  display: none;
}
.message__editor {
  display: block;
  width: 100%;
  min-height: 80px;
  padding: 10px 12px;
  border: 1px solid var(--c-primary);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text);
  font: inherit;
  resize: vertical;
  outline: none;
}
.message__edit-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
}

/* Аватарка автора — вона ж кнопка завантаження: сам <input type="file">
   схований усередині <label>, тож клік по кружечку відкриває вибір файла
   без жодного JS. Кружечок той самий, що .message__avatar, а поки фото
   немає — червоний фон і фотоапарат усередині: колір відрізняє порожню
   аватарку від справжніх, у яких він закріплений за людиною, а іконка
   каже, чого від кружечка чекати */
/* Ліва колонка форми: аватарка, а під нею позначка мови. Поруч із полем
   позначка забирала б у нього ширину — а колонка й так стоїть порожня на
   всю висоту форми, тож місце для нагадування там уже є, і поле лишається
   на всю ширину.
   Ширину колонці задає сітка .compose (34px), тому позначка тягнеться на
   всі 100% і має рівні паддінги: інакше «EN» і «UK» стояли б різної
   ширини й колонка йшла б хвилею */
.compose__side {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.compose__side .lang-mark {
  padding: 5px 0;
  text-align: center;
}

.compose__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  align-self: start;
  border-radius: 50%;
  overflow: hidden;
  color: #fff;
  cursor: pointer;
}
.compose__avatar--empty {
  background: var(--c-red);
}
.compose__avatar:hover {
  opacity: 0.85;
}
/* Кружечок на сайті поки нічого не відкриває: аватарку нікуди вантажити, тож
   у формі стоять ті самі ініціали, що в гілці. Колір дає .message__avatar--*,
   розкладку (і сітку мобільної версії) лишає за собою .compose__avatar, а
   кегль ініціалів — той самий, що в шапці повідомлення */
.compose__avatar--static {
  font-size: 12px;
  font-weight: 700;
  cursor: default;
}
.compose__avatar--static:hover {
  opacity: 1;
}
.compose__avatar-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.compose__avatar-slot svg {
  width: 17px;
  height: 17px;
}
.compose__avatar-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Ім'я автора над полем — щоб було видно, хто підпишеться під повідомленням:
   адмін часто пише під чужим акаунтом. Стоїть там само, де ім'я в шапці
   повідомлення, і виглядає так само.
   wrap — на вузькому екрані селекти зіскакують під ім'я */
.compose__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-bottom: 8px;
}
.compose__name {
  font-weight: 700;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Стан питання — правий край шапки форми. Вправо блок зносить не своє
   margin-left: auto, а кнопка легенди перед ним: два auto-поля в рядку
   поділили б порожнечу навпіл і лишили б знак питання посеред нього */
.compose__states {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Кнопка, що розкриває селекти стану. Показує її тільки мобільна версія —
   на десктопі селекти стоять розкриті й ховати їх нема за чим.
   Вигляд і поведінка ті самі, що в .filter-btn у списку питань */
.states-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text-soft);
  cursor: pointer;
}
.states-btn svg {
  width: 16px;
  height: 16px;
}
.states-btn:hover,
.states-btn[aria-expanded="true"] {
  border-color: var(--c-primary);
  color: var(--c-primary);
}

/* Знак питання — легенда: що означає кожен маркер терміновості, типу й
   статусу. Кнопок таких три й стоять вони в різних місцях: у шапці форми
   відповіді на сторінці питання і в шапці таблиці питань — у проекті та в
   «Операційці». Тут тільки сама кнопка: без рамки й тла, бо це не ще одне
   поле поруч, а підказка до всіх сусідніх разом. Місце в рядку кожне з
   трьох місць дає своє — див. правила нижче й «Список питань» */
.states-legend,
.notice-reveal {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
/* display: flex вище переважив би [hidden] — гасимо сховану кнопку окремо */
.notice-reveal[hidden] {
  display: none;
}
/* У рядку вкладок кнопка стояла б угорі: .submenu не центрує дітей, а
   вкладки вищі за неї на свої падінги. Центруємо — на лінію тексту вкладок */
.submenu .notice-reveal {
  align-self: center;
}
/* У шапці форми відповіді знак питання стоїть першим із двох значків, тож
   auto-поле зліва — на ньому: воно зносить управо і його самого, і все, що
   за ним, — кнопку стану й самі селекти. Від'ємне поле справа з'їдає різницю
   між gap рядка (12px) і gap блока селектів (8px): на десктопі знак питання
   має стояти від першого селекта рівно так само, як селекти стоять один від
   одного */
.compose__head .states-legend {
  flex: none;
  align-self: center;
  margin-left: auto;
  margin-right: -4px;
}
.states-legend svg,
.notice-reveal svg {
  width: 16px;
  height: 16px;
}
.states-legend:hover,
.notice-reveal:hover {
  color: var(--c-primary);
}

/* Селекти стану — вужчі за решту полів сайту й однакової ширини, заданої
   числом. Спільне select.input міряє поле по вибраному пункту (--sel-w від
   app.js), і тут це виходило боком двічі: три поля разом з'їдали пів шапки,
   лишаючи імені смужку на кілька літер, а на кожній зміні вибору рядок ще
   й перебудовувався — поле стрибало під курсором.
   Ширина одна на всі три: у рядку вони стоять як один блок, і різні
   ширини читалися б як різна вага полів. Влазить найдовший статус
   («До перевірки») — саме за ним сюди й дивляться; «Виправлення помилки»
   в типі довше за будь-яку розумну ширину, тож обрізається трикрапкою —
   у розкритому списку підпис усе одно цілий.
   Кегль на пункт менший — поля стану не головне в шапці форми */
.compose__states select.input {
  width: 112px;
  flex: none;
  padding: 6px 20px 6px 8px;
  font-size: 13px;
  background-position: right 6px center;
  background-size: 11px;
  text-overflow: ellipsis;
}

/* хрестик у плитці вибраного файла — прибрати один файл зі списку.
   У повідомленнях його немає: там вкладення вже надіслані */
.file__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-right: -4px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.file__remove svg {
  width: 11px;
  height: 11px;
}
.file__remove:hover {
  background: var(--c-border);
  color: var(--c-text);
}
/* --- мобільна версія сторінки питання --- */
@media (max-width: 1100px) {
  /* Тут у шапці проекту сам лише рядок назви: вкладок на сторінці питання
     немає, а клієнт згорнутий під кареткою. Відступ під нею складався вдвічі
     — 10px рядка плюс 12px самої шапки, — і між назвою проекту та шапкою
     питання зяяла діра. Лишаємо один: коли каретку розкрито, ті самі 10px
     відбивають клієнта */
  .page--issue .project-head {
    margin-bottom: 0;
  }

  /* тут шапка питання — знову два рядки: назві потрібна вся ширина екрана,
     поруч зі станом від неї лишився б стовпчик у пару слів. Обгортка стану
     стає флекс-рядком з переносом, а назва — окремим рядком під ним */
  .issue-head {
    padding: 0 12px;
  }
  .issue-head__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    row-gap: 10px;
  }
  /* назва в розмітці стоїть перед статусом і виконавцем, тож order зносить її
     під них, а базис на всю ширину змушує рядок перенестися саме перед нею */
  .issue-head__title {
    order: 1;
    flex: 0 0 100%;
    font-size: 16px;
  }
  /* обгортка стану тут зайва: статус і виконавець знову окремі елементи рядка,
     бо стоять вони не поряд — статус зліва, виконавець по правому краю */
  .issue-head__state {
    display: contents;
  }
  /* тут блок іде до правого краю рядка стану — його дає margin-left: auto.
     Але стискатись він мусить: поруч немає назви, яка поступилася б місцем,
     тож задовге ім'я обрізається багатокрапкою */
  .issue-head__side {
    margin-left: auto;
    flex-shrink: 1;
    min-width: 0;
  }
  /* гілочка й три крапки — у потоці, останні в рядку стану: правий край їм
     дає той самий margin-left: auto виконавця. Розмір тут менший — 28px, як
     у решти кнопок мобільних рядків: із 32px рядок стану став би вищим за
     аватарку */
  .issue-head__tree,
  .issue-head__more {
    position: static;
    width: 28px;
    height: 28px;
    margin-left: 14px;
  }
  /* дві кнопки стоять парою: між собою просвіт менший, ніж до імені поруч */
  .issue-head__more {
    margin-left: 2px;
  }

  /* картки на всю ширину — як таблиця питань у .issues-box */
  .thread,
  .compose {
    border-left: none;
    border-right: none;
    border-radius: 0;
    box-shadow: none;
  }
  /* на вузькому екрані гілка й форма — одна суцільна стрічка: відступ між
     ними тут лише крав висоту, а форма й так читається як продовження
     переписки. Межу тримає нижня рамка гілки — власну верхню форма знімає,
     інакше лінія була б подвійною.
     Знизу гілка рамку теж знімає: сірого поля під сторінкою тут немає (див.
     .page), тож її нижня рамка впиралася б у верхню рамку підвалу — і в
     самому кінці сторінки лінія була б у два пікселі. Закриває стрічку
     лінія підвалу, та сама, що ділить рядки всередині карток */
  .thread {
    border-bottom: none;
  }
  .compose {
    border-top: none;
  }
  .message {
    grid-template-columns: 28px minmax(0, 1fr);
    gap: 10px;
    padding: 14px 12px;
  }
  .message__avatar {
    width: 28px;
    height: 28px;
    font-size: 11px;
  }
  /* час лишається в рядку з іменем і по правому краю — як на десктопі:
     власним рядком під іменем він з'їдав висоту кожного повідомлення.
     Переносу тут немає зовсім: на вузькому екрані першими зіскакували
     крапки дій, і рядок шапки ставав удвічі вищим. Замість переносу
     стискається ім'я — воно єдине, що можна обрізати без втрати сенсу */
  .message__head {
    flex-wrap: nowrap;
    gap: 4px 8px;
  }
  .message__author {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .message__edited,
  .message__more {
    flex-shrink: 0;
  }
  /* gap рядка тут менший, тож і мітку правки підтягуємо на стільки ж */
  .message__edited + .message__time {
    margin-left: -4px;
  }

  /* колонка аватарки вужчає разом із повідомленнями — інакше поле вводу
     стане не на одній вертикалі з текстом переписки */
  .compose {
    grid-template-columns: 28px minmax(0, 1fr);
    gap: 10px;
    padding: 14px 12px;
  }
  .compose__avatar {
    width: 28px;
    height: 28px;
  }
  .compose__avatar-slot svg {
    width: 15px;
    height: 15px;
  }
  /* Позначка мови стає рівно в лінію з полем вводу — там, де починають
     набирати текст. У колонці вона стояла просто під аватаркою і на кілька
     пікселів не сходилася з полем, а коли розкривали селекти стану, рядок
     імені виростав і розбіжність ішла в добрий десяток пікселів.
     Тож замість фіксованого проміжку обидві колонки стають однією сіткою:
     display: contents розчиняє обгортки, і аватарка з рядком імені йдуть
     першим рядком, а позначка з полем — другим. Далі скільки б не важив
     рядок імені, позначка тримається верху поля сама.
     Проміжок між рядками тут нульовий: відступи між блоками правої колонки
     задають їхні власні margin (як і було в звичайному потоці), а gap сітки
     додався б до них зверху */
  .compose__side,
  .compose__body {
    display: contents;
  }
  .compose {
    row-gap: 0;
    column-gap: 10px;
  }
  .compose__avatar {
    grid-area: 1 / 1;
  }
  .compose__head {
    grid-area: 1 / 2;
  }
  .compose__side .lang-mark {
    grid-area: 2 / 1;
    align-self: start;
  }
  .compose__field {
    grid-area: 2 / 2;
  }
  /* решта правої колонки — під полем, тим самим стовпцем */
  .compose__files,
  .compose__actions {
    grid-column: 2;
  }
  /* у рядку імені лишаються самі кнопки — знак питання й кнопка стану, —
     а селекти розкриваються під ним на всю ширину: трьом поруч із іменем
     тут не вміститись */
  .states-btn {
    display: flex;
  }
  /* поруч із кнопкою стану знак питання вирівнюється по ній, а не по
     середині рядка, і від'ємне поле справа тут ні до чого: між двома
     іконками стоїть звичайний gap рядка */
  .compose__head .states-legend {
    align-self: auto;
    margin-right: 0;
  }
  .compose__states {
    display: none;
    order: 3;
    width: 100%;
    /* три поля одним рядком: переносити їх нема куди, а вміщаються вони
       рівно втрьох — за це й відповідає nowrap разом із min-width нижче */
    flex-wrap: nowrap;
  }
  .compose__states--open {
    display: flex;
  }
  /* поля стану ділять рядок нарівно, а не стоять фіксованою шириною кожне:
     розкриті, вони мають свій рядок на всю ширину, і лишати посеред нього
     порожнечу нема за чим. min-width: 0 — щоб рядок ділився саме нарівно:
     власна ширина найдовшого пункту інакше не дала б полю стиснутися і
     зіпхнула б сусідів. Підпис, що не вліз, обрізає трикрапка — у
     розкритому списку він усе одно цілий.
     Селектор той самий, що й у десктопній ширині вище, — інакше та ширина
     була б сильнішою і тут */
  .compose__states select.input {
    flex: 1;
    min-width: 0;
    width: auto;
  }
  .thread__new {
    padding-left: 12px;
    padding-right: 12px;
  }
}

/* ============ Опис задачі ============ */
/* Опис — те, що набрали в редакторі: заголовки, списки, малюнки, таблиці.
   На сторінці питання він стоїть колонкою (.page--split): картка й
   типографіка тексту описані тут, а сітку колонок задає обгортка нижче.
   Усередині .brief__body класів немає зовсім: редактор віддає звичайні h2,
   p, ul, table, і стилі до них ведуть саме теги — інакше кожен новий тег у
   редакторі вимагав би правки CSS */
.brief {
  /* смуга ліворуч від тексту опису: разом із полем самої коробки в неї
     стають плюс і ручка блока, коли опис правлять. Удвох вони займають 50px,
     стільки й має бути смуги з полем разом. Текст від неї починається і в
     правці, і в описі — див. .brief__body й правила редактора нижче.
     Смуга потрібна там, де кнопкам нікуди подітися, — у попапі й на
     вузькому екрані. Опис колонкою на десктопі її обнуляє й виносить
     кнопки за картку: див. «Варіант 2» нижче */
  --brief-gutter: 30px;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Заголовок картки: назва, ким і коли оновлений опис, далі кнопки.
   Кнопки різні у двох варіантах — правка з кареткою в колонці, правка з
   хрестиком у попапі, — але місце в рядку в них те саме */
.brief__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--c-border);
}

.brief__title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
}
.brief__title svg {
  width: 17px;
  height: 17px;
  color: var(--c-text-soft);
}

/* «оновив Адмін, 8 трав» — приписка до назви, а не окремий рядок: опис
   правлять рідко, але знати, наскільки він свіжий, треба щоразу.
   margin-right: auto відсуває кнопки до правого краю */
.brief__meta {
  margin-right: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  color: var(--c-text-soft);
}

/* Плашка на час правки — на місці тієї самої приписки. «Оновив тоді-то»
   поки опис у роботі не про те: важить, що його зараз тримає ця людина,
   і саме це видно з першого погляду по оранжевому — тому, яким усюди
   позначено зайняте. Рядок один, довге ім'я обрізається трьома крапками:
   заголовок картки міряний по іконках і розсуватися йому нема куди */
.brief__lock {
  display: none;
  margin-right: auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--c-orange-soft);
  font-size: 12px;
  font-weight: 600;
  color: var(--c-orange);
}
.brief--editing .brief__meta {
  display: none;
}
.brief--editing .brief__lock {
  display: block;
}

/* Кнопки заголовка — ті самі, що й три крапки в повідомленні: прозорі,
   сірі, підсвічуються під курсором. Скріпка серед них — не кнопка, а
   підпис до схованого <input>, тож їй ще й курсор пальцем */
.brief__attach,
.brief__edit,
.brief__toggle,
.brief__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  margin: -4px 0;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.brief__attach svg,
.brief__edit svg,
.brief__toggle svg,
.brief__close svg {
  width: 16px;
  height: 16px;
}
.brief__attach:hover,
.brief__edit:hover,
.brief__toggle:hover,
.brief__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Олівець на час правки ховається — його місце займає «Зберегти». Правило
   потрібне саме таким: display у кнопок заголовка виставлений вище, і
   звичайного hidden йому мало */
.brief__edit[hidden] {
  display: none;
}

/* «Зберегти» стає на місце олівця, поки опис правлять. Кнопка дрібніша за
   звичайну: заголовок картки міряний по іконках, і повновимірна кнопка
   розсунула б його на час правки */
.brief__save {
  flex-shrink: 0;
  margin: -4px 0;
  padding: 5px 12px;
  font-size: 13px;
}
/* каретка потрібна лише там, де опис згортається, — на вузькому екрані.
   У колонці й у попапі згортати нема чого, тож на десктопі її просто немає */
.brief__toggle {
  display: none;
}
/* розгорнутий опис — каретка «вгору», згорнутий — «вниз» */
.brief__toggle svg {
  transform: rotate(180deg);
  transition: transform 0.15s;
}
.brief--closed .brief__toggle svg {
  transform: none;
}

.brief__box {
  padding: 16px 20px 20px;
  /* місце під смугу гортання тримається завжди — там, де коробка взагалі
     гортається, тобто в попапі. Інакше опис ставав би вужчим саме тоді,
     коли доріс до гортання, і текст переносився б по-різному до й після */
  scrollbar-gutter: stable;
}
/* згорнутий опис — сам заголовок картки: коробку ховаємо цілком, разом із
   файлами. Стан тримає клас на картці, як і в решті згорток прототипу */
.brief--closed .brief__box {
  display: none;
}

/* вкладення опису — ті самі плитки, що під повідомленням */
.brief__files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--c-border);
  list-style: none;
}

/* --- Форматований текст опису ---
   Відступ між блоками один на всі теги: кожен наступний відбивається від
   попереднього, а перший стоїть щільно до краю коробки.
   Зліва в тексту своя смуга — під плюс і ручку блока, які редактор ставить
   біля рядка. Смуга однакова й у правці, і в описі: інакше той самий текст
   стояв би в двох режимах по-різному й переносився б не там */
.brief__body {
  padding-left: var(--brief-gutter);
  font-size: 14px;
  line-height: 1.55;
  overflow-wrap: anywhere;
}
.brief__body > * + * {
  margin-top: 12px;
}

/* Заголовки в описі дрібніші за назву питання: усередині картки вони ділять
   текст, а не сперечаються з шапкою сторінки. Відбивка зверху більша за
   звичайну — саме вона й показує, що почався новий розділ опису */
.brief__body h2 {
  font-size: 15px;
  font-weight: 700;
}
.brief__body h3 {
  font-size: 14px;
  font-weight: 700;
}
.brief__body > h2 + *,
.brief__body > h3 + * {
  margin-top: 8px;
}
.brief__body > * + h2 {
  margin-top: 22px;
}
.brief__body > * + h3 {
  margin-top: 18px;
}

.brief__body ul,
.brief__body ol {
  padding-left: 20px;
}
.brief__body li + li {
  margin-top: 4px;
}

/* Малюнок — на всю ширину коробки, у рамці: знімок екрана майже завжди
   світлий, і без рамки він розтікався б по білій картці.
   height: auto обов'язковий: у розмітці редактора в картинки часто стоять
   свої width і height, і без цього малюнок поїхав би пропорціями */
.brief__body img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--c-border);
  border-radius: 8px;
}
.brief__body figcaption {
  margin-top: 6px;
  font-size: 12px;
  color: var(--c-text-soft);
}

/* Прикріплений файл серед тексту — та сама плитка, що під повідомленням,
   тільки окремим рядком: у тексті вона стоїть замість абзацу, а не всередині
   нього. Ширина по вмісту — інакше плитка розтяглася б на всю картку */
.brief__body .file {
  display: flex;
  width: fit-content;
}

/* Розділювач — не лінія на всю ширину, а три крапки посередині: у картці
   опису суцільна риска читалася б як межа блока картки */
.brief__body hr {
  height: 0;
  border: 0;
  text-align: center;
  color: var(--c-text-soft);
  letter-spacing: 8px;
}
.brief__body hr::before {
  content: "•••";
}

/* Код — і рядковий, і блоком. Моноширинний шрифт у прототипі більше ніде не
   потрібен, тож стек описаний просто тут */
.brief__body code {
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--c-bg);
  font-family: Consolas, "SF Mono", Menlo, monospace;
  font-size: 13px;
}
.brief__body pre {
  padding: 12px 14px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-bg);
  /* довгий рядок запиту гортається всередині блока, а не рве картку */
  overflow-x: auto;
}
.brief__body pre code {
  padding: 0;
  background: none;
}

/* Таблиця. display: block робить її власним полем гортання — у вузькій
   колонці таблиця на три стовпчики інакше розсунула б картку. Ширина в
   100% лишається: поки таблиця вміщається, вона стоїть на всю коробку */
.brief__body table {
  display: block;
  width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: 13px;
}
.brief__body th,
.brief__body td {
  padding: 8px 10px;
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--c-border);
}
.brief__body th {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}
.brief__body tr:last-child td {
  border-bottom: 0;
}

/* --- Правка опису: Editor.js ---
   Редактор — єдина стороння річ у прототипі (assets/vendor/editorjs). Свою
   розмітку й свої стилі він приносить сам, тож тут лише два роди правил:
   вписати його коробку в картку опису й підрівняти типографіку блоків до
   тієї, якою опис показаний. Класи з префіксами ce-, cdx- і tc- — його */
/* На час правки картка показує сам редактор: готовий текст ховаємо.
   Плитки файлів лишаються — вони прикріплені до опису однаково, правлять
   його зараз чи ні, і скріпка в заголовку працює в обох станах */
.brief--editing .brief__body {
  display: none;
}
/* Коробка опису гортається сама, і смуга гортання з'їдає в неї частину
   ширини. Там, де в правці гортання немає, те саме поле лишаємо праворуч від
   редактора — інакше текст у ньому був би ширший за той самий текст в описі.
   Скільки саме з'їла смуга, міряє brief-edit.js: у різних браузерів вона
   різна, а подекуди її й немає зовсім */
.brief__edit-box {
  margin-right: var(--brief-scroll, 0px);
}

/* Плюс і ручка блока стоять ліворуч від рядка — у смузі, яку тримає для них
   текст опису (--brief-gutter), плюс поле самої коробки. Своє місце під них
   редактор відміряє сам і своє: у вузькій колонці він відсуває текст на
   50px праворуч, а кнопки ставить у правому краю рядка. Обидва відступи
   скидаємо й ставимо свої, дзеркальні.
   Селектори з .codex-editor посередині — не примха: власні правила редактора
   доточуються до сторінки останніми, і без цієї зайвої ланки вони б
   переважили */
.brief__editor .codex-editor .codex-editor__redactor {
  margin-left: var(--brief-gutter);
  margin-right: 0;
}
/* кнопки — рівно в цю смугу: правим краєм до тексту (панель редактора про
   смугу нічого не знає, тож її ширину віднімаємо самі), лівим — до поля
   коробки, а 4px між ними й текстом лишаються повітрям */
.brief__editor .codex-editor .ce-toolbar__actions {
  right: calc(100% - var(--brief-gutter));
  left: auto;
  padding-right: 4px;
}
/* самі кнопки дрібніші за початкові — інакше вдвох вони в смугу не стають */
.brief__editor .ce-toolbar__plus,
.brief__editor .ce-toolbar__settings-btn {
  width: 22px;
  height: 22px;
}
.brief__editor .ce-toolbar__settings-btn {
  margin-left: 2px;
}
.brief__editor .ce-toolbar__plus svg,
.brief__editor .ce-toolbar__settings-btn svg {
  width: 18px;
  height: 18px;
}
/* Своє обмеження ширини редактору тут ні до чого: колонка вмісту в нього
   вужча за картку й стоїть по центру, а опис має правитися рівно там, де
   він потім і буде */
.brief__editor .ce-block__content,
.brief__editor .ce-toolbar__content {
  max-width: none;
}
/* Запас під останнім блоком редактор ставить сам і чималий — щоб було куди
   клікнути під текстом. Під карткою опису, де внизу ще й кнопки, стільки
   порожнечі ні до чого. !important тут не примха: редактор пише цей відступ
   прямо в style елемента, і по-іншому його не перебити */
.brief__editor .codex-editor__redactor {
  padding-bottom: 60px !important;
}
/* Блоки редактора — тим самим кеглем і ритмом, що й готовий опис: той
   самий текст має лежати в правці рядок у рядок із тим, як він щойно
   стояв в описі. Свої відступи редактор ставить усередину блоків
   (в абзаца це padding), а між ними не ставить нічого — тож власні
   прибираємо, а відбивку робимо ту саму, що в .brief__body */
.brief__editor .ce-block {
  font-size: 14px;
  line-height: 1.55;
}
.brief__editor .ce-block + .ce-block {
  margin-top: 12px;
}
.brief__editor .ce-paragraph {
  padding: 0;
  line-height: 1.55;
}
/* заголовок ділить текст — відбивка перед ним більша, після нього
   менша, як і в описі. :has() тут по суті: у розмітці редактора рівень
   заголовка видно тільки всередині блока, на самому блоці його немає */
.brief__editor .ce-block + .ce-block:has(h2.ce-header) {
  margin-top: 22px;
}
.brief__editor .ce-block + .ce-block:has(h3.ce-header) {
  margin-top: 18px;
}
.brief__editor .ce-block:has(.ce-header) + .ce-block {
  margin-top: 8px;
}
/* список: своє поле й свої проміжки між пунктами редактор теж ставить
   сам — міняємо на ті, з якими список стоїть в описі */
.brief__editor .cdx-list {
  padding: 0;
  gap: 4px;
}
.brief__editor .cdx-list__item {
  line-height: 1.55;
}
.brief__editor h2.ce-header {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.55;
  padding: 0;
}
.brief__editor h3.ce-header {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.55;
  padding: 0;
}
/* картка прикріпленого файла: свій вигляд у неї від інструмента — правимо
   тільки розмір напису, щоб назва файла не була більшою за сам текст */
.brief__editor .cdx-attaches__title {
  font-size: 14px;
}
/* Кнопки правки — під редактором, по правому краю картки */
.brief__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}
/* У попапі гортається сам опис, тож кнопки прилипають до низу коробки:
   інакше «Зберегти» лежало б у кінці тексту, і до нього щоразу треба було б
   догортати весь опис. Фон і риска — щоб текст не проступав під ними */
.modal__box--brief .brief__actions {
  position: sticky;
  bottom: 0;
  margin: 0 -20px -20px;
  padding: 12px 20px;
  border-top: 1px solid var(--c-border);
  background: var(--c-surface);
}

/* --- Варіант 2: опис колонкою ---
   Ліворуч опис, праворуч переписка — навпіл. Опис і гілка тут рівні за
   вагою: в описі стоять малюнки й таблиці, яким потрібна ширина, а вужчою
   колонкою переписка тільки нарощувала б рядки.
   minmax(0, 1fr) обов'язковий замість простого 1fr: інакше довге слово,
   посилання чи широка таблиця в описі розсунули б свою колонку за половину.
   align-items: start — щоб колонки не тягнулися одна за одною до спільної
   висоти: без цього прилипання опису не працює зовсім */
.issue-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

/* Прилипають обидві колонки, і правило в них спільне: наперед невідомо, що
   вийде коротшим — опис чи переписка. Буває короткий опис при довгій гілці,
   буває навпаки, а порожньою при гортанні не має лишатися жодна половина:
   умова й відповіді на неї потрібні на екрані водночас.
   Рухатись у своїй клітинці гріда є куди тільки коротшій колонці — вона й
   прилипає; довша задає висоту ряду, стоїть на весь час гортання і порожньою
   не лишається сама собою.
   Свого гортання всередині колонок немає: опис читають разом зі сторінкою, а
   не в коробці з власною смугою.
   --stick-top — де саме колонка спиняється. Коли вона вміщається в екран, це
   76px: висота шапки сайту (60) з відбивкою (16), тобто колонка стає під
   шапку. Коли не вміщається — від'ємне число, рівно на скільки вона за екран
   виступає: тоді колонка спершу догортується до кінця й аж тоді спиняється,
   притиснута низом до краю екрана. Рахує його issue-cols.js: власної висоти
   елемента CSS не знає. Поки не порахував — ті самі 76px */
@media (min-width: 1101px) {
  .issue-cols > * {
    position: sticky;
    top: var(--stick-top, 76px);
  }
  /* Поки опис правлять, колонка нікуди не прилипає: сторінку гортають як
     завжди. Інакше меню блоків і панель редактора їхали б угору разом із
     прилиплою карткою */
  .issue-cols .brief--editing {
    position: static;
  }
}
/* У попапі коробка опису гортається сама, і на час правки те гортання
   прибираємо: інакше меню блоків і панель редактора різало б її краєм */
.brief--editing .brief__box {
  overflow: visible;
}

/* Опис колонкою іде на всю ширину картки: смуги ліворуч у тексту немає.
   Читають опис куди частіше, ніж правлять, а порожній відступ під кнопки
   редактора видно весь час — тож на час правки кнопки виходять із картки
   назовні, у поле сторінки ліворуч від неї.
   Скільки того поля — залежить від вікна: до 1280px сторінка стоїть на всю
   ширину, і ліворуч від картки лишається саме її поле (28px), а ширше —
   ще й половина того, що за 1280 не влізло. 1296 замість 1280 — запас на
   смугу гортання: 100vw міряє вікно разом із нею, а сторінка стоїть уже
   без неї.
   --brief-lane — на скільки правий край кнопок відступає від тексту.
   Найкраще 25px: поле коробки (20) з рамкою (1) і 4px повітря за карткою.
   Коли поля стільки немає, кнопки заходять назад під край картки — рівно
   настільки, щоб не втекти за край вікна */
@media (min-width: 1101px) {
  .issue-cols .brief {
    --brief-gutter: 0px;
    --brief-out: calc(28px + max(0px, (100vw - 1296px) / 2));
    --brief-lane: clamp(2px, var(--brief-out) - 28px, 25px);
  }
  /* правим краєм кнопки стають на смугу, самі лишаються за нею. Поле
     праворуч у панелі більше ні до чого: повітря між кнопками й текстом
     тепер міряє сама смуга */
  .issue-cols .brief__editor .codex-editor .ce-toolbar__actions {
    right: calc(100% + var(--brief-lane));
    padding-right: 0;
  }
}

/* --- Варіант 3: опис попапом ---
   Коробка ширша за підтвердження дії й на всю висоту екрана: опис — це
   сторінка тексту, а не питання «ви впевнені?».
   Сам попап — та сама .modal, що й підтвердження: підкладка, z-index і
   закриття по кліку повз коробку в них спільні */
.modal__box--brief {
  display: flex;
  flex-direction: column;
  max-width: 760px;
  max-height: 100%;
  padding: 0;
  overflow: hidden;
}
/* заголовок попапа стоїть, гортається тільки текст під ним */
.modal__box--brief .brief__box {
  /* min-height потрібен саме нулем: без нього коробка-флекс не дає вмісту
     стиснутись, і замість гортання опис просто обрізався б знизу */
  min-height: 0;
  overflow-y: auto;
}

/* Сторінка під відкритим попапом не гортається — клас вішає brief.js.
   Правило стоїть на <body>: у нього overflow за замовчуванням visible, тож
   браузер віддає гортання сторінки саме йому */
body.scroll-lock {
  overflow: hidden;
}

/* Кнопка «Опис задачі» в рядку стану питання. Розміром вона зі статус поруч,
   але блакитна й з іконкою: серед маркерів стану вона має читатися саме як
   дія, а не як ще одна позначка */
.brief-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  margin-left: 8px;
  padding: 4px 10px;
  border: 1px solid var(--c-primary-soft);
  border-radius: 20px;
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.brief-btn:hover,
.brief-btn[aria-expanded="true"] {
  border-color: var(--c-primary);
}
.brief-btn svg {
  width: 14px;
  height: 14px;
}

/* --- мобільна версія опису --- */
@media (max-width: 1100px) {
  /* Колонок немає: опис лягає карткою над перепискою — і згорнутий, інакше
     переписка починалася б за екраном. Розкриває його каретка (brief.js) */
  .issue-cols {
    display: block;
  }
  /* прилипання тут не відмінюємо — воно живе у своєму @media від 1101px */
  .issue-cols .brief {
    /* опис, гілка й форма тут — одна суцільна стрічка: відступ між описом і
       перепискою тільки крав висоту, а межу між ними однаково тримає риска.
       Риска ця — верхня рамка гілки, тож власну нижню картка опису знімає:
       поруч вони давали подвійну лінію. Той самий прийом, що й у форми
       відповіді під гілкою */
    margin: 0;
    /* картка на всю ширину — як гілка й форма під нею */
    border-left: none;
    border-right: none;
    border-bottom: none;
    border-radius: 0;
    box-shadow: none;
  }
  /* Згорнутий опис — сам заголовок картки, і тоді риска під заголовком
     впирається в рамку гілки: та сама подвійна лінія, тільки з іншого боку.
     Тож поки опис згорнутий, риски в заголовку немає — ділити їй нема чого */
  .issue-cols .brief--closed .brief__head {
    border-bottom: none;
  }
  .brief__head {
    padding: 12px;
  }
  .brief__box {
    padding: 12px 12px 16px;
  }
  /* поле коробки тут менше — стільки ж добираємо смугою під кнопки блока,
     щоб текст опису стояв від краю картки так само, як на широкому екрані */
  .brief {
    --brief-gutter: 38px;
  }
  .brief__toggle {
    display: inline-flex;
  }

  /* у попапі опис займає весь екран: на вузькому екрані поля навколо коробки
     тільки крадуть у тексту ширину */
  .modal--brief {
    padding: 0;
  }
  .modal__box--brief {
    max-width: none;
    height: 100%;
    border-radius: 0;
  }

  /* у рядку стану лишається сама іконка: поруч уже стоять статус, виконавець
     і три крапки, і напису серед них місця немає */
  .brief-btn {
    padding: 5px;
    border-radius: 50%;
  }
  .brief-btn__text {
    display: none;
  }
}

/* ============ Вхід ============ */
/* Сторінка без шапки й підвалу: одна картка по центру екрана. Усі три панелі —
   вхід, відновлення пароля і новий пароль за листом — лежать у ній,
   показана завжди одна */
.auth {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
}

.auth__box {
  width: 100%;
  max-width: 380px;
  padding: 28px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.auth__logo {
  margin-bottom: 20px;
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.5px;
  text-align: center;
}
.auth__logo span {
  color: var(--c-primary);
}

/* Рядок для того, хто прийшов за посиланням на питання чи проект */
.auth__notice {
  margin-bottom: 20px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--c-primary-soft);
  color: var(--c-text);
  font-size: 13px;
  line-height: 1.5;
}

/* Рядок з помилкою (не той пароль, Google не пустив) — той самий блок,
   лише червоний; помилка окремого поля стоїть під ним */
.auth__notice--error {
  background: #fdecec;
  color: var(--c-red-dark);
}

.auth__error {
  color: var(--c-red);
  font-size: 13px;
  line-height: 1.4;
}

.auth__panel[hidden] {
  display: none;
}

.auth__title {
  margin-bottom: 16px;
  font-size: 20px;
  font-weight: 700;
}

.auth__hint {
  margin-bottom: 16px;
  color: var(--c-text-soft);
  font-size: 13px;
  line-height: 1.5;
}

.auth__form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.auth__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.auth__label {
  color: var(--c-text-soft);
  font-size: 13px;
  font-weight: 500;
}

.auth__input {
  width: 100%;
}

.auth__submit {
  margin-top: 2px;
}

/* «Забули пароль?» і «Повернутися до входу» — кнопки, а не посилання:
   вони не ведуть на іншу адресу, а перемикають панель на цій самій сторінці */
.auth__link {
  display: block;
  margin: 14px auto 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: 13px;
  color: var(--c-primary);
  cursor: pointer;
}
.auth__link:hover {
  text-decoration: underline;
}

.auth__or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 20px 0;
  color: var(--c-text-soft);
  font-size: 12px;
}
.auth__or::before,
.auth__or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--c-border);
}

/* Ряд входів через чужі акаунти: скільки їх у config/social.php, стільки
   й кнопок, кожна на всю ширину картки — одна під одною читаються як
   рівноцінні двері, а не як головна й запасна */
.auth__socials {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.auth__social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 9px 16px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text);
  font-size: 14px;
  font-weight: 600;
}
.auth__social:hover {
  background: var(--c-bg);
  text-decoration: none;
}

/* Той самий логотип, що в профілі, лише дрібніший: там він позначає рядок
   списку, тут стоїть у рядку тексту кнопки */
.auth__social .social__logo {
  width: 18px;
  height: 18px;
}

/* Телеграм малює свою кнопку сам, усередині iframe: її ні розтягнути, ні
   перефарбувати — обгортка лише ставить її по центру ряду */
.auth__widget {
  display: flex;
  justify-content: center;
}
.auth__widget iframe {
  max-width: 100%;
}

/* ============ Смуга «дивлюсь чужим акаунтом» ============ */
/* Стоїть над шапкою і жовта, бо мусить читатися як стан усього екрана, а не
   як ще один рядок у ньому: доки вона є, кожна дія нижче йде від чужого імені */
.impersonation {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 8px 20px;
  background: var(--c-yellow-soft);
  border-bottom: 1px solid var(--c-border);
  font-size: 13px;
}

.impersonation__btn {
  padding: 3px 10px;
  font-size: 13px;
}
.impersonation__btn svg {
  width: 14px;
  height: 14px;
  margin-left: 6px;
}

/* ============ Текстова сторінка ============ */
/* Сторінки з CMS: угорі шлях і заголовок, нижче блоки, які редактор склав у
   адмінці. Ширину тут тримає не .page, а сам текст — рядок довший за 70
   символів читати важко, тож колонка вужча за решту розділів */

.page__heading {
  min-width: 0;
}

.crumbs {
  margin-bottom: 6px;
}
.crumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 0;
  margin: 0;
  list-style: none;
  font-size: 13px;
  color: var(--c-text-soft);
}
/* Роздільник малює сам список, а не розмітка: у ній лише самі ланки */
.crumbs__item + .crumbs__item::before {
  content: "/";
  margin-right: 6px;
  color: var(--c-border);
}
.crumbs__link {
  color: var(--c-text-soft);
}
.crumbs__item--current {
  color: var(--c-text);
}

.text {
  max-width: 760px;
}

.text__block + .text__block {
  margin-top: 28px;
}

.text__title {
  margin-bottom: 12px;
  font-size: 18px;
  font-weight: 700;
}

/* Розмітка всередині блоку — редакторова, класів на ній немає, тож правила
   стоять на самих тегах */
.text__block p,
.text__block ul,
.text__block ol {
  margin-bottom: 12px;
  line-height: 1.6;
}
.text__block ul,
.text__block ol {
  padding-left: 20px;
}
.text__block li + li {
  margin-top: 4px;
}
.text__block h2,
.text__block h3 {
  margin: 20px 0 10px;
  font-weight: 700;
}
.text__block h2 {
  font-size: 18px;
}
.text__block h3 {
  font-size: 16px;
}
.text__block img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius);
}
.text__block table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 12px;
}
.text__block th,
.text__block td {
  padding: 8px 10px;
  border: 1px solid var(--c-border);
  text-align: left;
}

.text__figure {
  margin: 0;
}
.text__caption {
  margin-top: 6px;
  font-size: 13px;
  color: var(--c-text-soft);
}

/* Скільки картинок у блоці, стільки й колонок, доки вони не вужчі за 160px —
   ряд не треба задавати в адмінці */
.text__gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
}
.text__thumb img {
  width: 100%;
  height: 140px;
  object-fit: cover;
  border-radius: var(--radius);
}

/* Пропорція 16:9 без магічних висот: висоту дає padding від ширини */
.text__video {
  position: relative;
  padding-top: 56.25%;
}
.text__video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: var(--radius);
}

.text__teasers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}
.text__teaser {
  padding: 16px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
}
.text__teaser-icon {
  width: 22px;
  height: 22px;
  margin-bottom: 8px;
  color: var(--c-primary);
}
.text__teaser-title {
  margin-bottom: 6px;
  font-size: 15px;
  font-weight: 700;
}
.text__teaser-text {
  font-size: 13px;
  line-height: 1.5;
  color: var(--c-text-soft);
}

/* ============ 404 ============ */
/* Сторінка живе в тій самій обгортці .page, що й решта розділів — з шапкою і
   підвалом, — тож блок лише центрує текст у вільній висоті */
.notfound {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: 80px;
  text-align: center;
}

.notfound__box {
  max-width: 420px;
}

.notfound__code {
  font-size: 64px;
  font-weight: 800;
  line-height: 1;
  color: var(--c-primary);
}

.notfound__title {
  margin-top: 12px;
  font-size: 22px;
  font-weight: 700;
}

.notfound__text {
  margin-top: 10px;
  color: var(--c-text-soft);
  font-size: 14px;
  line-height: 1.6;
}

.notfound__btn {
  display: inline-flex;
  margin-top: 20px;
}
.notfound__btn:hover {
  background: #3352c9;
  text-decoration: none;
}


/* ============ Оплата і Звіти ============ */
/* Дві сторінки на одному блоці .month: журнал транзакцій і звіти про час.
   Місяць — така сама згортна група, як проект у списку: та сама картка, та
   сама каретка, той самий код в app.js. «Розгорнути» так само стоїть у шапці
   таблиці по правому краю, а на мобільному переїжджає в заголовок сторінки.
   Далі спільна частина — сам місяць; таблиці в них різні й лежать нижче
   кожна своєю секцією */

.month {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 14px;
}

.month__header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-border);
}
/* у згорнутого місяця під шапкою вже нічого немає — межа злилася б із
   нижнім краєм самої картки в подвійну лінію */
.month--collapsed .month__header {
  border-bottom: none;
}

.month__name {
  font-size: 16px;
  font-weight: 700;
}

.month__count {
  font-size: 13px;
  white-space: nowrap;
  color: var(--c-text-soft);
}

/* Підсумки місяця — праворуч, по одному на напрямок. Адмін бачить обидва
   («Від клієнтів» і «Виконавцям») та ще баланс — різницю між ними; клієнт
   і виконавець — лише свій напрямок: у їхніх записах другий бік завжди
   адмін, тож і рахувати різницю нема з чим */
.month__sums {
  display: flex;
  align-items: baseline;
  gap: 20px;
  margin-left: auto;
}
.month__sum {
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* гроші, що прийшли мені, — зеленим; що пішли від мене — звичайним темним.
   Напрямок рахується від того, хто дивиться (payDir у pay.php), тому для
   клієнта його ж платіж — це «пішли», а для виконавця той самий за змістом
   запис — «прийшли» */
.month__sum--in {
  color: var(--c-green);
}
/* Баланс — різниця між двома попередніми, і бачить його тільки адмін.
   Синім, бо зеленим уже позначені надходження, а звичайним темним — виплати:
   третій колір і виділяє підсумок з двох доданків, з яких він вийшов */
.month__sum--balance {
  color: var(--c-primary);
}
/* Виправлення помилок у «Звітах» — бордовим, тим самим, що час у рядку звіту
   поза оплатою: сума і рядки, з яких вона склалася, позначені однаково */
.month__sum--fix {
  color: var(--c-red-dark);
}
.month__label {
  margin-right: 8px;
  font-size: 12px;
  font-weight: 500;
  color: var(--c-text-soft);
}

/* «Платежі»: кількість оплат — саме число в дужках одразу за назвою місяця,
   тож вона стоїть у самому заголовку, а не окремим блоком поруч: між сусідами
   в шапці 12px, і на такій відстані дужки читалися б як окремий підпис.
   Жирність заголовка їй не потрібна — це підпис, а не назва */
.page-payments .month__name .month__count {
  font-weight: 500;
}

/* «Платежі»: підсумки місяця — у колонках сталої ширини, щоб та сама колонка
   кожної картки лягала рівно під ту саму колонку картки вище. Інакше кожен
   місяць починає свої числа там, де скінчилися числа сусіда, і очима їх уже
   не порівняти.

   Ширина саме стала, а не за вмістом: суми в кожного місяця свої, і колонки
   «по вмісту» розійшлися б від картки до картки. Колонку обирає напрямок, а
   не порядок — місяць без надходжень або без балансу лишає свою порожньою і
   не зсуває решту. Адмін має всі три («Від клієнтів», «Виконавцям» і баланс
   між ними), решта — лише свій бік, і третьої колонки їм тримати нема для
   чого (`Payment\ViewModels\PaymentsMonthViewModel::money`).

   Довга сума в дві валюти переноситься в своїй же колонці, а не налазить на
   сусідню, — тому тут, на відміну від «Звітів», рядок не заборонено рвати */
.page-payments .month__sums {
  --month-sum-col: 256px;
  display: grid;
  grid-template-columns: repeat(2, var(--month-sum-col));
  column-gap: 16px;
}
.role-admin.page-payments .month__sums {
  grid-template-columns: repeat(3, var(--month-sum-col));
}

/* У адміна колонок три, і стоять вони не по правому краю шапки, а одразу за
   назвою місяця: «Від клієнтів → Виконавцям → Баланс» читаються зліва
   направо разом із самим місяцем, а не через півшапки порожнечі.
   Відступ від назви невеликий, але сталий — назва тримає ширину найдовшого
   місяця (з рахунком у дужках це 115px на «September (100)»), інакше колонки
   починалися б там, де скінчилося слово, і в кожній картці по-своєму.
   Каретку до правого краю притискає тепер вона сама, а не суми перед нею.

   Ширина колонки росте разом з екраном і впирається в дві межі: вужче за
   256px три колонки вже не тримають суму в дві валюти в один рядок, а ширше
   за 310px їх не пускає сама сторінка — `.page` не буває ширшою за 1280px,
   і решту тієї ширини забирають назва з кареткою */
.role-admin.page-payments .month__name {
  flex: 0 0 auto;
  min-width: 120px;
}
.role-admin.page-payments .month__sums {
  --month-sum-col: clamp(256px, 23vw, 310px);
  margin-left: 0;
}
.role-admin.page-payments .month__toggle {
  margin-left: auto;
}
.page-payments .month__sum {
  white-space: normal;
}
.page-payments .month__sum--in {
  grid-column: 1;
}
.page-payments .month__sum--out {
  grid-column: 2;
}
.page-payments .month__sum--balance {
  grid-column: 3;
}

/* Спільна шапка колонок над місяцями — те саме, що .branches-head над списком
   проектів: порожня таблиця з тим самим colgroup, тож ширини збігаються
   з таблицями в місяцях */
.month-head {
  margin: 0 1px 4px;
}
/* Клас таблиці в селекторі не для краси: без нього він важить рівно стільки ж,
   скільки .pays th і .reports th нижче, і фон шапки дістався б тому правилу,
   що стоїть у файлі пізніше. Над списком проектів шапка так само без фону */
.month-head .pays,
.month-head .pays th,
.month-head .reports,
.month-head .reports th {
  background: transparent;
}
.month-head .pays th,
.month-head .reports th {
  border-bottom: none;
}

/* «Згорнути / розгорнути» — по правому краю шапки, під кареткою місяця, як
   над списком проектів. І на «Платежах», і в «Звітах» кнопка стоїть у клітинці
   сама, а та вже вирівняна праворуч: клітинка там одна на кілька останніх
   колонок (сума з валютою / час із жучком) — жодній із них вузької ширини
   під кнопку не вистачило б */

/* ============ Таблиця оплат ============ */
.month__rows {
  overflow-x: auto;
  border-radius: 0 0 var(--radius) var(--radius);
}
.month--collapsed .month__rows {
  display: none;
}

.pays {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  min-width: 904px;
}

.pays__col-date { width: 96px; }
.pays__col-note { width: auto; }
.pays__col-from { width: 200px; }
.pays__col-to   { width: 200px; }
.pays__col-sum  { width: 120px; }
.pays__col-cur  { width: 56px; }
/* Галочка «отримано» — остання колонка на «Платежах». В оплатах проекту її
   немає: там рядок не переказ, а його частина, і підтверджують отримання
   самого переказу, а не кожної частки. Колонки з colgroup там просто немає,
   тож ця ширина в тій таблиці ні на що не впливає.
   56 = 12 + 32 + 12: галочка тут така сама 32-піксельна, як каретка місяця,
   і відбита від краю тими самими 12px, що й вона в шапці, — обидві стоять
   на одній осі по правому краю картки */
.pays__col-ok   { width: 56px; }

/* Оплати проекту — таблиця та сама, а колонок на одну більше: рядок там не
   переказ, а його частина, і в неї є гілка. Через неї сітка ширша, а імена
   боків трохи вужчі — коментар усе одно забирає весь залишок */
.pays--branch {
  min-width: 1020px;
}
.pays__col-branch { width: 200px; }
.pays--branch .pays__col-from,
.pays--branch .pays__col-to { width: 170px; }

.pays th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--c-text-soft);
  padding: 8px 12px;
  background: #fafbfd;
  border-bottom: 1px solid var(--c-border);
  white-space: nowrap;
}

.pays td {
  padding: 6px 12px;
  border-bottom: 1px solid var(--c-border);
  vertical-align: middle;
}
/* останній рядок межі не має — її роль грає нижній край картки */
.pays tr:last-child td {
  border-bottom: none;
}

.pays__row:hover {
  background: #f8faff;
}

.pays__date {
  white-space: nowrap;
  color: var(--c-text-soft);
}

.pays__note {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Коментар — посилання, хоч і кнопка: клік нікуди не веде, він показує
   частини оплати прихованими рядками під нею. Виглядає як звичайне
   посилання, бо для того, хто читає, це те саме — «розкрити подробиці» */
.pays__note-btn {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  max-width: 100%;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: var(--c-primary);
  text-align: left;
  cursor: pointer;
}
/* сам текст коментаря, а не вся кнопка, — це його ріжемо трикрапкою, щоб
   каретка праворуч лишалася на місці й не з'їхала за край разом із текстом */
.pays__note-btn span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pays__note-btn:hover span {
  text-decoration: underline;
}
/* Каретка коментаря — та сама, що згортає місяць, тільки без рамки й дрібніша:
   без неї синій текст читається як звичайне посилання, а він не веде нікуди,
   а розкриває частини оплати під рядком */
.pays__note-btn::after {
  content: '\25BE';
  transition: transform 0.15s;
  flex: none;
  transform: rotate(-90deg);
  font-size: 11px;
  line-height: 1;
  color: var(--c-text-soft);
}
.pays__note-btn[aria-expanded='true']::after {
  transform: none;
}

/* Частина оплати: за яку гілку, якого проекту і скільки з цієї суми.
   Стоїть у тих самих колонках, що й оплата, тільки тихіше — це розшифровка
   рядка вище, а не окремий запис */
.pays__part td {
  padding: 3px 12px;
  border-bottom: 1px solid var(--c-border);
  font-size: 13px;
  color: var(--c-text-soft);
}
/* межа під розгорнутою оплатою зникає — блок оплати з її частинами
   замикає остання з них */
.pays__row--open td {
  border-bottom: none;
}
/* зсув від краю колонки — так гілка не читається як ще один коментар */
.pays__part .pays__branch {
  padding-left: 24px;
}
.pays__branch {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* номер гілки в її проекті — той самий, що в списку гілок і у звітах
   (.reports__num); частини однієї оплати бувають з різних проектів, тож
   номери в сусідніх рядках повторюються */
.pays__num {
  margin-right: 6px;
  font-weight: 700;
}
.pays__project {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pays__part-sum {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pays__from,
.pays__to {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pays th.pays__col-sum,
.pays th.pays__col-cur,
.pays__sum,
.pays__cur,
.pays__part-sum,
.pays__part-cur {
  text-align: right;
}

.pays__sum {
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* той самий колір напрямку, що й у підсумку місяця */
.pays__row--in .pays__sum {
  color: var(--c-green);
}

.pays__cur {
  text-transform: uppercase;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* Порожній список — та сама смуга під шапкою колонок, що в питаннях проекту
   (.issues__empty). У прототипі її немає: там дані завжди є, а тут фільтр із
   пошуком лишають список порожнім, і сама лише шапка колонок читалася б як
   недовантажена сторінка */
.pays__empty {
  padding: 24px;
  text-align: center;
  color: var(--c-text-soft);
}

@media (max-width: 1100px) {
  /* картка місяця — без рамки й тіні, як картка проекту */
  .month {
    border: none;
    border-radius: 0;
    box-shadow: none;
    margin-bottom: 10px;
  }

  /* шапка місяця — два рядки:
     1) назва, кількість оплат за нею і каретка з правого краю
     2) підсумки, притиснуті праворуч
     Кількість стоїть саме за назвою, а не окремим рядком: це підпис до неї,
     і разом вони читаються як «Серпень, 4 оплати» */
  .month__header {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 4px 8px;
    border-bottom: none;
  }
  /* назва й кількість стоять на спільній лінії шрифту, а не по центру
     висоти рядка: кегль у них різний (16 проти 13), і центрування зсувало б
     кількість угору від назви, за якою вона й читається */
  .month__name {
    grid-column: 1;
    grid-row: 1;
    align-self: baseline;
  }
  .month__count {
    grid-column: 2;
    grid-row: 1;
    align-self: baseline;
  }
  .month__toggle {
    grid-column: 3;
    grid-row: 1;
    align-self: center;
  }
  .month__sums {
    grid-column: 1 / -1;
    grid-row: 2;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    margin-left: 0;
  }
  /* Три колонки підсумків на «Платежах» — розкладка широкого екрана: тут на
     них немає ширини, і вони стають тим самим стовпчиком, що й у «Звітах» */
  .page-payments .month__sums {
    display: flex;
    column-gap: 0;
  }

  /* «Звіти»: усі три суми — одним рядком, у тому ж порядку, що й на широкому
     екрані: всі години, з них на виправлення, і скільки лишилося в оплату.
     Стовпчик із трьох сум гнав шапку місяця у висоту, а рядком вони й
     читаються відніманням. Підпис виправленням тут зайвий, його заміняє
     бордовий колір — той самий, що на часі в рядку звіту. На «Платежах» суми
     лишаються стовпчиком, тож правило й питає саме про виправлення */
  .month__sums:has(.month__sum--fix) {
    flex-flow: row wrap;
    align-items: baseline;
    justify-content: flex-end;
    column-gap: 14px;
  }
  .month__sum--fix .month__label {
    display: none;
  }

  /* --- таблиця перетворюється на картки --- */
  /* колонок у картці немає, тож і спільна шапка над місяцями зайва */
  .month-head {
    display: none;
  }
  .month__rows {
    overflow-x: visible;
  }
  .pays {
    display: block;
    min-width: 0;
    table-layout: auto;
  }
  /* У місяці таблиця заголовків не має зовсім — їх несе спільна .month-head
     над картками. А от в оплатах проекту місяців немає, і шапка стоїть у
     самій таблиці: у картковій розкладці її прибирати треба тут */
  .pays thead {
    display: none;
  }
  .pays tbody {
    display: block;
  }

  /* Перший рядок картки — уся оплата коротко: дата, хто кому і скільки.
     Чотири колонки: дата й обидва боки беруть свою ширину, остання тягнеться
     на весь залишок і притискає суму до правого краю. Тісно стане — імена
     обріжуться (min 0 у їхніх колонках), а дата із сумою лишаться цілі.
     Вирівняні по лінії шрифту: кегль у трьох різний (12, 13, 15) */
  .pays__row {
    display: grid;
    grid-template-columns: auto minmax(0, auto) minmax(0, auto) minmax(max-content, 1fr) auto;
    align-items: baseline;
    padding: 10px 12px;
    border-top: 1px solid var(--c-border);
  }
  .pays__row:hover {
    background: none;
  }

  .pays td {
    display: block;
    border: none;
    padding: 0;
  }

  .pays td.pays__date {
    grid-column: 1;
    grid-row: 1;
    padding-right: 10px;
    font-size: 12px;
  }
  .pays td.pays__sum {
    grid-column: 4;
    grid-row: 1;
    justify-self: end;
    padding-left: 10px;
    font-size: 15px;
  }
  /* Коментар — під іменами, а не над ними: спершу видно, хто кому платив, і
     вже потім за що. Він же й розкриває частини оплати, тож іде останнім —
     розгорнуті частини стають прямим його продовженням */
  .pays td.pays__note {
    grid-column: 1 / -1;
    grid-row: 2;
    padding-top: 4px;
    font-weight: 600;
    white-space: normal;
  }

  /* Гілка — своїм рядком під коментарем: колонок у картці немає, а за що
     пішли гроші, треба бачити так само, як і за яким переказом. Обрізати її
     тут нема потреби — рядок свій і вільний, тож текст просто переноситься */
  .pays--branch td.pays__branch {
    grid-column: 1 / -1;
    grid-row: 3;
    padding-top: 2px;
    font-size: 12px;
    color: var(--c-text-soft);
    white-space: normal;
  }

  /* відправник і одержувач — поспіль, зі стрілкою між ними замість підписів
     «Від» і «Кому»: напрямок видно з самої стрілки, а окремі рядки лише
     гнали б картку у висоту. Обидві клітинки з min-width: 0, тож довге ім'я
     стискає свою колонку, а не ламає рядок */
  .pays td.pays__from,
  .pays td.pays__to {
    grid-row: 1;
    font-size: 13px;
    min-width: 0;
  }
  .pays td.pays__from { grid-column: 2; }
  .pays td.pays__to   { grid-column: 3; }

  .pays td.pays__to::before {
    content: '→';
    margin: 0 6px;
    color: var(--c-text-soft);
  }

  /* Галочка «отримано» — за сумою, останньою в першому рядку картки: у
     таблиці вона стоїть у кінці рядка, і в картці лишається там же.
     По центру рядка, а не по лінії шрифту: у значка її немає */
  .pays td.pays__ok {
    grid-column: 5;
    grid-row: 1;
    align-self: center;
    padding-left: 6px;
  }

  /* валюта переїхала до самої суми — .cur-tag у тій же клітинці */
  .pays td.pays__cur {
    display: none;
  }

  /* Частина оплати — свій маленький рядок під карткою: гілка з проектом
     ліворуч, частка суми праворуч. Колонок у картці немає, тож порожня
     клітинка під датою і валюта окремо тут зайві */
  .pays__part {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    padding: 0 12px 8px;
  }
  /* display: grid вище переважив би [hidden] — гасимо схований рядок окремо */
  .pays__part[hidden] {
    display: none;
  }
  .pays__part td {
    display: block;
    padding: 0;
    border: none;
  }
  .pays__part .pays__branch {
    grid-column: 1;
    grid-row: 1;
    padding-left: 0;
  }
  .pays__project {
    grid-column: 1;
    grid-row: 2;
    font-size: 12px;
  }
  .pays__part-sum {
    grid-column: 2;
    grid-row: 1 / span 2;
    justify-self: end;
    padding-left: 10px;
  }
  /* у картці межі малює верхній край наступної оплати — частинам своїх
     ліній не треба зовсім; порожня клітинка під галочкою тут теж зайва */
  .pays td.pays__part-gap,
  .pays td.pays__part-cur,
  .pays td.pays__part-ok {
    display: none;
  }
}

/* ============ Таблиця звітів ============ */
/* Своя сітка колонок, як і в оплат. Час стоїть передостаннім, за коментарем:
   усі години так читаються одним стовпчиком під сумами місяця та за рік, — а
   останню колонку тримає жучок звіту поза оплатою. Своя колонка йому потрібна
   саме заради цього стовпчика: в одній клітинці з часом він зсував число, і
   години в сусідніх рядках починалися з різних місць.
   936 = дата 76 + проект 180 + гілка 200 + виконавець 170 + коментар 206
       (гумова, забирає всю зайву ширину) + час 64 + жучок 40.
   Але колонок у ролей неоднаково: «Додано» бачить лише адмін, «Виконавець» —
   усі, крім самого виконавця. Тому мінімальна ширина в кожної своя, а який
   у таблиці набір колонок, каже модифікатор від PHP — питати про роль
   тут не доводиться.

   Найширший набір — адмінський, 1024, — мусить уміщатися в сторінку на самій
   межі десктопа: 1101 − 17 смуга прокрутки − 28 × 2 поля сторінки − 1 × 2
   рамки картки. Інакше таблиці місяців поїхали б у свій горизонтальний скрол,
   а спільна шапка над ними лишилась би стояти на місці */
.reports {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  min-width: 936px;
}
.reports--added {
  min-width: 1024px; /* + «Додано» 88 */
}
.reports--noworker {
  min-width: 766px; /* − «Виконавець» 170 */
}
/* Наскрізні «Звіти» без тієї колонки, але з виконавцем у дужках усередині
   гілки (.reports__by, стоїть завжди разом із --noworker): клітинка гілки
   мусить умістити обидва імені й бере собі сто пікселів зі звільнених ста
   сімдесяти — решта, як і всюди, йде коментарю. 866 = 766 + 100. У списку
   самого виконавця цього модифікатора немає: там імені в дужках теж немає,
   і гілка лишається на своїх двохстах */
.reports--by .reports__col-branch {
  width: 300px;
}
.reports--by {
  min-width: 866px;
}

/* Звіти однієї гілки: колонок «Проект» і «Гілка» в таблиці немає — проект
   стоїть у шапці сторінки, гілка заголовком над списком, — тож сітка вужча
   на ці 380 пікселів:
   556 = дата 76 + виконавець 170 + коментар 206 (гумова) + час 64 + жучок 40.
   Набір колонок і тут залежить від ролі, тому комбінації з --added і
   --noworker виписані окремо: поодинці ті модифікатори несуть ширини
   загальних «Звітів» і за порядком у файлі перебили б цей */
.reports--branch {
  min-width: 556px;
}
.reports--branch.reports--added {
  min-width: 644px; /* + «Додано» 88 */
}
.reports--branch.reports--noworker {
  min-width: 386px; /* − «Виконавець» 170 */
}

.reports__col-added   { width: 88px; }
.reports__col-date    { width: 76px; }
.reports__col-project { width: 180px; }
.reports__col-branch  { width: 200px; }
.reports__col-worker  { width: 170px; }
.reports__col-note    { width: auto; }
.reports__col-time    { width: 64px; }
/* Колонка жучка — рівно під значок: 14px іконки й запас з боків, якого
   вистачає і на 12px від краю таблиці, і на зсув під каретку місяця в
   «Звітах» (див. .month .reports td.reports__bug нижче) */
.reports__col-bug     { width: 40px; }

.reports th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--c-text-soft);
  padding: 8px 12px;
  background: #fafbfd;
  border-bottom: 1px solid var(--c-border);
  white-space: nowrap;
}

/* Верх, а не середина: коментар буває в кілька рядків, і решта клітинок
   мусить стояти на одній лінії з його першим рядком, а не плавати посередині */
.reports td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--c-border);
  vertical-align: top;
}
/* останній рядок межі не має — її роль грає нижній край картки */
.reports tr:last-child td {
  border-bottom: none;
}

.reports__row:hover {
  background: #f8faff;
}

/* Дата звіту й дата, коли його завели, — обидві приглушені: у рядку вони
   службові, читають його з коментаря */
.reports__date,
.reports__added {
  white-space: nowrap;
  color: var(--c-text-soft);
}

/* Час по правому краю своєї колонки разом із заголовком — як грошові
   колонки на «Фінансах»: однакової довжини значення так читаються стовпчиком.
   У шапці по тому самому краю стає кнопка «Розгорнути / згорнути»: клітинка
   там одна на дві колонки — час і жучка */
.reports th.reports__col-time,
.reports__time {
  text-align: right;
}
.reports__time {
  white-space: nowrap;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Під набраним часом — те, що нарахував лічильник (бачить лише адмін). Дрібно
   й сіро, бо в оплату йде верхнє число; помаранчеве, коли час переписали, —
   саме такі рядки й шукають очима */
.reports__timer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 3px;
  font-size: 12px;
  font-weight: 400;
  color: var(--c-text-soft);
}
.reports__timer .icon {
  width: 11px;
  height: 11px;
}
.reports__timer--diff {
  color: var(--c-orange);
}

/* Звіт поза оплатою — виправлення власної помилки. Позначає його бордовий
   час: рамка з боків рядка брала на себе забагато уваги там, де йдеться про
   одне число, а колір стоїть саме на тих годинах, яких немає в оплаті. Той
   самий бордовий несуть і підсумки виправлень — у шапці місяця та за рік, —
   тож рядок і сума читаються як одне. Що це саме виправлення, каже жучок
   перед самим числом — той самий, що й у списку питань, — і підказка на весь
   рядок (title у розмітці) */
.reports__row--unpaid .reports__time {
  color: var(--c-red-dark);
}
/* Значок у колонці один: у схованому від клієнта звіті око стає замість
   жучка, а не поруч із ним — колонка вузька, і два значки в ній читалися б
   гірше за один. Що це виправлення помилки, каже тоді колір: те саме
   бордове, що й на часі поруч, — рядок так лишається одного кольору.
   У звіті на доробку око сіре, базовим кольором .kind--hidden */
.reports__row--unpaid .kind--hidden {
  color: var(--c-red-dark);
}
/* Жучок — в останній колонці, за часом: у клітинці часу він зсував число, і
   години в сусідніх рядках починалися з різних місць. Колонка вузька, і
   значок у ній сам собі стовпчик. Власний відступ .kind тут зайвий —
   праворуч від нього край */
.reports__bug {
  text-align: right;
}
.reports__bug .kind {
  margin-right: 0;
}
/* У «Звітах» значок стоїть не по правому краю таблиці, а по центру каретки
   місяця над ним: у каретки видно рамку 32px, і по краю таблиці значок під
   нею читався зсунутим — вирівнює їх лише центр у центр, 28px від краю.
   Розсовувати під це колонку не можна (з її 40px складені min-width
   таблиці), тож центр дають відступи самої клітинки: 21px праворуч і 5px
   ліворуч на 14px значка. У звітах гілки каретки немає — там колонка
   лишається зі звичайними 12px */
.month .reports td.reports__bug {
  padding-right: 21px;
  padding-left: 5px;
}

/* Проект і гілка — посилання на сторінку проекту, обидва звичайним текстом:
   виділяти жирним тут нема чого, головне в рядку — коментар. Обидві колонки
   тримаються одного рядка й обрізаються крапками; переноситься в таблиці лише
   сам коментар, тож висоту рядка задає саме він. Власного правила коментарю
   не треба — так поводиться звичайна клітинка, а переноси всередині тексту
   ставить уже <br> із reportNote() */
.reports__project,
.reports__branch {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.reports__project a,
.reports__branch a {
  color: var(--c-text);
}
.reports__project a:hover,
.reports__branch a:hover {
  color: var(--c-primary);
  text-decoration: underline;
}

/* номер гілки стоїть у тій самій комірці, що й назва, — як у списку гілок */
.reports__num {
  margin-right: 6px;
  font-weight: 700;
  color: var(--c-text-soft);
}

/* Виконавець у дужках після гілки — так його читають усі, крім адміна: колонка
   «Виконавець» адмінова, а решті вона коштувала б 170 пікселів у найширшій
   таблиці CRM. Ім'я тут другорядне (головне в клітинці — гілка), тож воно
   дрібніше й приглушене, і поза посиланням: чия це рука — не частина адреси,
   куди гілка веде. Переносу немає — клітинка й так обрізається крапками, а в
   картці мобільної версії рядок переноситься весь */
.reports__by {
  margin-left: 6px;
  font-size: 12px;
  font-weight: 400;
  color: var(--c-text-soft);
}

/* Порожній список — та сама смуга під шапкою колонок, що в питаннях проекту
   (.issues__empty) і в його оплатах (.pays__empty). У прототипі її немає:
   там дані завжди є, а тут пошук лишає список порожнім, і сама лише шапка
   колонок читалася б як недовантажена сторінка */
.reports__empty {
  padding: 24px;
  text-align: center;
  color: var(--c-text-soft);
}


@media (max-width: 1100px) {
  /* --- таблиця перетворюється на картки --- */
  /* колонок у картці немає, тож і спільну шапку над місяцями ховає те саме
     правило .month-head, що й на «Платежах» */
  .reports {
    display: block;
    min-width: 0;
    table-layout: auto;
  }
  /* Ширини звітів гілки виписані парами класів — і цим важать більше за саме
     .reports, — тож у картковій розкладці мінімальну ширину доводиться знімати
     з них окремо: інакше картки лишилися б із десктопною сіткою */
  .reports--branch.reports--added,
  .reports--branch.reports--noworker {
    min-width: 0;
  }
  /* У місяці таблиця заголовків не має зовсім — їх несе спільна .month-head
     над картками. А от у звітах гілки місяців немає, і шапка стоїть у самій
     таблиці: у картковій розкладці її прибирати треба тут — так само, як в
     оплатах проекту */
  .reports thead {
    display: none;
  }
  .reports tbody {
    display: block;
  }

  /* дата, «додано», виконавець, жучок і час ділять перший рядок картки, решта
     йде на всю ширину. Гумова колонка тут четверта — та, у кінці якої стоїть
     жучок: вона й розсовує пару «жучок + час» до правого краю картки */
  .reports__row {
    display: grid;
    grid-template-columns: auto auto auto minmax(0, 1fr) auto;
    padding: 10px 12px;
    border-top: 1px solid var(--c-border);
  }
  .reports__row:hover {
    background: none;
  }

  .reports td {
    display: block;
    border: none;
    padding: 0;
  }

  .reports td.reports__date {
    grid-column: 1;
    grid-row: 1;
    font-size: 12px;
  }
  /* Коли звіт завели — тут же за датою і в дужках: окремого рядка ця довідка
     в картці не варта, а розбіжність із датою звіту поруч видно навіть краще.
     Підпис їй не потрібен — дужки самі кажуть, що число службове */
  .reports td.reports__added {
    grid-column: 2;
    grid-row: 1;
    padding-left: 5px;
    font-size: 12px;
  }
  .reports td.reports__added::before {
    content: '(';
  }
  .reports td.reports__added::after {
    content: ')';
  }
  /* Виконавець — у тому ж рядку, що й дата: у картці це така сама службова
     довідка, і окремий рядок під неї лише гнав би картку у висоту. Своєї
     ширини вимагати не може (min-width: 0), тож довге ім'я стискається
     крапками, а не відсуває час */
  .reports td.reports__worker {
    grid-column: 3;
    grid-row: 1;
    min-width: 0;
    padding-left: 8px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    color: var(--c-text-soft);
  }
  /* Час — правим краєм першого рядка картки, а жучок приїжджає в картку
     перед ним: у списку карток так само видно, які години поза оплатою.
     Окремої колонки під значок тут не треба — колонок у картці немає, — тож
     він стає в кінець гумової й іде впритул до часу */
  .reports td.reports__bug {
    grid-column: 4;
    grid-row: 1;
    justify-self: end;
    align-self: center;
  }
  /* відступи, якими значок вирівняно під каретку місяця, тут знімаємо:
     у картці ні колонки, ні каретки над ним немає */
  .month .reports td.reports__bug {
    padding: 0;
  }
  .reports td.reports__time {
    grid-column: 5;
    grid-row: 1;
    justify-self: end;
    padding-left: 6px;
    font-size: 15px;
  }

  /* Гілка з проектом — одним рядком через кому, спершу гілка, і це заголовок
     картки: за ним її й знаходять очима, тож він більший за все інше в ній.
     Підписи «Гілка» і «Проект» тут зайві: зв'язка читається й без них. Проект
     дописує сама гілка (data-project у розмітці), тож рядок переноситься як
     суцільний текст і весь лишається одним посиланням, а власна клітинка
     проекту в картку не йде зовсім */
  .reports td.reports__branch {
    grid-column: 1 / -1;
    grid-row: 2;
    padding-top: 4px;
    overflow: visible;
    white-space: normal;
    font-size: 15px;
    font-weight: 600;
  }

  /* коментар — під заголовком і дрібнішим за нього: у картці він текст до
     гілки, а не сам заголовок */
  .reports td.reports__note {
    grid-column: 1 / -1;
    grid-row: 3;
    padding-top: 2px;
    font-size: 13px;
  }
  .reports__branch a::after {
    content: ', ' attr(data-project);
  }
  .reports td.reports__project {
    display: none;
  }

}


/* ============ Команда ============ */
/* Виконавець — така сама згортна група, як проект у списку: та сама картка,
   та сама каретка, той самий код в app.js. Тому й таблиця під шапкою — та
   сама .branches, і спільна шапка колонок над групами — той самий .branches-head.
   Відрізняється лише сама шапка групи: там людина, а не проект, — звідси
   окремий блок .member замість спільних .project__*.

   Колонок тут п'ять: клієнта в рядку немає (у групі він не один), зате є
   коментар адміна, якого немає більше ніде.
   Активність тут стоїть перед питаннями, одразу за назвою: розділ читають
   питанням «хто чим зайнятий», і години відповідають на нього першими.
   1014 = проект 220 + активність 270 + питання 160 + коментар 260 + оновлено 104 */
.member {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 14px;
}

/* Своя картка — перша в списку. Одного порядку мало: перший рядок нічим не
   відрізняється від решти, тож підсвічуємо рамкою й шапкою. Колір той самий
   первинний, що й у посилань, тільки шапка на його світлому тлі: картка має
   впадати в око, а не світитися цілком — під шапкою йдуть звичайні рядки
   таблиці, і читати їх однаково у своїй картці й у чужій */
.member--me {
  border-color: var(--c-primary);
}
.member--me .member__header {
  background: var(--c-primary-soft);
  /* тло шапки доходить до самого краю картки — без цього воно зрізало б їй
     заокруглені кути. Мінус піксель рамки, щоб кут не двоївся */
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}
/* у згорнутої картки шапка — і є вся картка, тож заокруглена з усіх боків */
.member--me.member--collapsed .member__header {
  border-radius: calc(var(--radius) - 1px);
}

/* «Ви» при своєму імені — пігулка, як роль автора в гілці, тільки в колір
   картки: колір сам по собі не пояснює, чому ця картка інша */
.member__me {
  padding: 1px 8px;
  flex-shrink: 0;
  border-radius: 20px;
  background: var(--c-surface);
  font-size: 12px;
  font-weight: 600;
  color: var(--c-primary);
}

.member__header {
  display: flex;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-border);
}
/* у згорнутої групи під шапкою вже нічого немає — межа злилася б із нижнім
   краєм самої картки в подвійну лінію */
.member--collapsed .member__header {
  border-bottom: none;
}

/* Ім'я з аватаркою — та сама аватарка виконавця, що в рядках інших списків.
   Тут вона стоїть при заголовку групи, тож без окремого блока .worker:
   імені-тексту поруч із нею більше нічого немає.
   Ім'я стоїть у колонці назв проектів і займає рівно її: 208 = 220 колонки
   − 12 лівого паддінга шапки. Ширину тримає саме воно, тож решта блоків
   стає на свої колонки без жодних зсувів */
.member__name {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 208px;
  flex-shrink: 0;
  font-size: 16px;
  font-weight: 700;
}

/* Довге ім'я ріжемо трикрапкою, а не пускаємо на кружечки: ширини блоків
   шапки тримають сітку таблиці під нею */
.member__title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* В адміна ім'я веде у «Фінанси», відфільтровані по людині, — як ім'я клієнта
   в «Клієнтах»: не синє, колір і підкреслення лише на наведенні */
.member__title--link {
  color: inherit;
  text-decoration: none;
}
.member__title--link:hover,
.member__title--link:focus-visible {
  color: var(--c-primary);
  text-decoration: underline;
}
/* Питання по всіх проектах людини — контурними кружечками, як підсумок
   проекту в списку (правило спільне, у секції з .dot).
   Паддінг повторює паддінг клітинки: блоки шапки стоять на своїх колонках
   краєм у край, а кружечки в рядках під ними починаються на 12px правіше —
   без цього підсумок стояв би лівіше за самі кружечки */
.member__issues {
  width: 160px;
  padding-left: 12px;
  flex-shrink: 0;
  white-space: nowrap;
}

/* Місце колонки коментарів у шапці групи — порожнє: коментар пишуть до
   проекту, а не до людини. Без цього блока дата й каретка з'їхали б із
   колонки «Оновлено» на всю ширину коментаря ліворуч.
   Гумова тут саме ця колонка, тож і в шапці розтягується цей блок: решта
   тримає свої пікселі, а надлишок сторінки дістається йому одному */
.member__note {
  flex: 1;
  min-width: 0;
}

/* Дата з кареткою стає рівно на колонку «Оновлено»: 92 = 104 − 12 правого
   паддінга шапки. Так дата групи стоїть точно над датами рядків, а каретка —
   над кнопками «Приховати» */
.member__summary {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: 92px;
  flex-shrink: 0;
  /* той самий зазор, що між датою та іконкою в .upd — інакше дата групи
     стоїть на 6px лівіше за дати проектів під нею */
  gap: 8px;
}

/* Найсвіжіше оновлення по проектах — видно і згорнутою групою, і розгорнутою */
.member__upd {
  white-space: nowrap;
  font-size: 13px;
  color: var(--c-text-soft);
}

.member__rows {
  overflow-x: auto;
  /* overflow-x робить і вертикаль скрол-контейнером, тож даємо запас зверху,
     щоб тултіпи кружечків першого рядка не обрізались */
  margin-top: -32px;
  padding-top: 32px;
  border-radius: 0 0 var(--radius) var(--radius);
}
.member--collapsed .member__rows {
  display: none;
}

/* Людина без активних проектів. Картку показуємо все одно: «Команда» — це
   список людей, а не список зайнятих, і вільні руки тут якраз те, що шукають */
.member__empty {
  padding: 12px;
  font-size: 13px;
  color: var(--c-text-soft);
}

/* Коментар адміна до проекту. Клітинка та сама в обох ролях, різне лише те,
   що в ній стоїть: в адміна поле вводу, у виконавця готовий рядок */
.branches__note {
  /* єдина колонка з довільним текстом — їй одній переноси дозволені */
  white-space: normal;
}

/* Поле коментаря живе в рядку таблиці, але коментар тут читають і пишуть
   нарівні з рештою рядка — тож і шрифт у ньому такий самий, як у полях
   форм, і на всю ширину колонки. Нижче за них воно лишається: рядок
   таблиці не має рости під поле. Рамку лишаємо — по ній і видно, що
   сюди можна писати */
.input--note {
  width: 100%;
  padding: 8px 12px;
  font-size: 14px;
  transition: border-color 0.15s, background 0.15s;
}
/* Мить після збереження. Кнопки «Зберегти» поруч немає — рядок іде на сервер
   сам, коли з поля пішов фокус, — тож саме ця позначка й каже, що він дійшов.
   Два класи, а не один: по Enter поле лишається у фокусі, а зелене має бути
   видно і в ньому — інакше .input:focus перебив би рамку синім */
.input--note.input--saved,
.input--msg.input--saved {
  border-color: var(--c-green);
  background: var(--c-green-soft);
}

/* --- повідомлення в картці виконавця --- */
/* Два поля про саму людину, а не про її проекти. Стоять під таблицею й
   згортаються разом із нею: згорнута картка — це один рядок про людину, і
   листування в ньому ні до чого.
   Смуга своя, з верхньою межею: під нею вже не рядки таблиці, а форма, і без
   лінії поля читались би продовженням останнього рядка.
   Тло те саме, що в сторінки, — блок помітно окремий від таблиці й не
   потребує для цього ні рамки навколо кожного поля, ні заголовка */
.member__msgs {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border-top: 1px solid var(--c-border);
  background: var(--c-bg);
  border-radius: 0 0 calc(var(--radius) - 1px) calc(var(--radius) - 1px);
}
.member--collapsed .member__msgs {
  display: none;
}

.member__msg {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Підпис і галочка одним рядком: галочка про це саме поле, і стоїть вона
   при його підписі, а не під самим полем */
.member__msg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* Підпис тихий: поле під ним і так видно за рамкою, а сам підпис лише
   називає, що в ньому писати */
.member__msg-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--c-text-soft);
}

/* Саме поле. Ширина вся, висота від двох рядків і росте вручну: тексти тут
   короткі, а фіксувати їх однією висотою на всі картки — значить різати
   довші */
.input--msg {
  width: 100%;
  padding: 7px 10px;
  font-size: 13px;
  font-family: inherit;
  line-height: 1.45;
  resize: vertical;
  transition: border-color 0.15s, background 0.15s;
}

/* Повідомлення на всі проекти — трьома мовами: поле на мову, мітка мови
   ліворуч від нього. Мітка вузька й тиха — окремий підпис над кожним полем
   утричі подовжив би картку, а що це те саме повідомлення, і так каже
   спільний підпис над трьома */
.member__langs {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.member__lang {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.member__lang-code {
  flex: 0 0 32px;
  padding-top: 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--c-text-soft);
}
.member__lang .input--msg {
  flex: 1;
  min-width: 0;
}

/* Галочка — та сама, що «за замовчуванням» у формі гілки, тільки без
   вертикальних відступів під висоту сусіднього поля: тут вона стоїть у рядку
   підпису, а не в рядку вводу */
.member__check {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}
.member__box {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  accent-color: var(--c-primary);
  cursor: pointer;
}

/* Той самий коментар у виконавця — просто рядок. Приглушений: це не його
   слова й не дані проекту, а помітка адміна збоку */
.note {
  font-size: 14px;
  color: var(--c-text-soft);
}

/* Ширину тримають дві колонки посередині — кружечкам більше за їхні 160 не
   треба, даті вистачає 104, — а весь надлишок забирає коментар: єдина
   колонка, якій зайва ширина справді потрібна, і після зняття графіка
   активності до неї відходять і його 270.
   Назва проекту лишається на своїх 220: разом із іменем виконавця над нею
   вони в цю ширину влазять, а все, що ширше, тільки відсувало б праворуч
   кружечки — а їх читають першими.
   744 = проект 220 + питання 160 + коментар 260 + дата 104, і це мінімум:
   ширшої за нього таблиця стає вже за рахунок коментаря */
@media (min-width: 1101px) {
  body.page-team .branches {
    min-width: 744px;
  }
  body.page-team .branches__col-note {
    width: auto;
  }
  body.page-team .branches__col-issues {
    width: 160px;
    min-width: 0;
  }
}

/* --- мобільна версія «Команди» --- */
@media (max-width: 1100px) {
  .member {
    border: none;
    border-radius: 0;
    box-shadow: none;
    margin-bottom: 10px;
  }

  /* шапка групи — два рядки, як у проекта в списку:
     1) ім'я з аватаркою, дата, каретка
     2) кружечки праворуч */
  .member__header {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 6px 10px;
    /* перша картка проекту під шапкою має свою верхню межу — разом із межею
       шапки лінія читалась подвійною */
    border-bottom: none;
  }
  .member__name {
    grid-column: 1;
    grid-row: 1;
    /* у картці колонок немає — ім'я бере всю ширину свого рядка */
    width: auto;
    min-width: 0;
    overflow: hidden;
  }
  .member__summary {
    grid-column: 2;
    grid-row: 1;
    width: auto;
    justify-self: end;
    align-self: center;
    gap: 12px;
  }

  /* другий рядок шапки — кружечки праворуч, під датою: у перший рядок їх не
     пускає ім'я — воно б звузилось */
  .member__issues {
    grid-column: 2;
    grid-row: 2;
    width: auto;
    /* у картці колонок немає — зсув під паддінг клітинки тут зайвий */
    padding-left: 0;
    justify-self: end;
    align-self: center;
  }

  /* у картковій шапці колонок немає — тримати місце під коментар нема для
     чого, а сам він стоїть окремим рядком у картці проекту */
  .member__note {
    display: none;
  }

  .member__rows {
    overflow-x: visible;
    margin-top: 0;
    padding-top: 0;
  }
  .member__empty {
    padding: 10px 12px;
    border-top: 1px solid var(--c-border);
  }

  /* у картці рамки немає, і сірий блок читався б не її частиною, а розривом
     між людьми — тут його від рядків відділяє сама лінія */
  .member__msgs {
    background: var(--c-surface);
    border-radius: 0;
  }

  /* у картці рядок кружечків стоїть сам — праворуч від них нічого немає
     (графіка активності тут не буває), тож і клітинка бере всю ширину: інакше
     її лінія-роздільник обривалась би на середині картки */
  .page-team .branches td.branches__issues {
    grid-column: 1 / -1;
  }

  /* коментар — останній рядок картки, під рядком з кружечками: у нього
     самого йому не стати (там довільний текст, а не число), а вище
     він розсунув би проект і його питання */
  .page-team .branches td.branches__note {
    grid-column: 1 / -1;
    grid-row: 3;
    padding-top: 8px;
  }
  /* у картці колонок немає, і сірий рядок сам по собі не читається як
     коментар адміна — підписуємо, як підписані решта рядків картки.
     Полю підпис не потрібен: у нього є placeholder */
  .note::before {
    content: 'Коментар адміна: ';
    font-weight: 500;
  }

  /* Фільтр тут один і стоїть у рядку сам, тож кнопки, що його згортає, у
     розмітці немає — а поле показуємо одразу, без стану --open. На інших
     сторінках та кнопка ховає кілька полів разом і має за що чіплятися */
  .page-team .page__filters {
    display: flex;
    order: 0;
  }
}

/* ============ Статистика ============ */
/* Місяць таблицею: колонка — доба, рядок — людина, клітинка — стовпчик у
   висоту годин. Мірка одна на всю таблицю, і саме через це рядки стоять
   спільною сіткою: стовпчики порівнюють і поперек рядка, і вздовж колонки.
   Групи, що згортаються, тут ні до чого — рядок один на людину і читається
   цілком, тож і картка на сторінці одна на всю таблицю */

.stat {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* Тридцять із гаком колонок на вузький екран не стають — таблиця їде вбік
     усередині картки. Колонка з іменами лишається стояти (sticky нижче):
     без імені рядок стовпчиків нічого не значить */
  overflow-x: auto;
}

/* border-collapse: separate, а не collapse, як у решти таблиць: колонка імен
   липка, а зібрані межі на липкій клітинці не малюються — вони належать уже
   не їй, а сітці таблиці, і при прокрутці лишаються стояти на місці.
   Тому межі тут при самих клітинках, а проміжку між ними немає (spacing: 0).

   Мінімальна ширина: імена 226 + 31 доба по 28 + підсумок 72. Ширину доби
   задає час у клітинці — «7:30» мусить лишатися читабельним; сам стовпчик
   обійшовся б і вдвічі вужчою колонкою. Ширина колонки імен — рівно під
   найдовше ім'я з пігулкою «Ви» поруч: у своєму рядку ім'я не має
   обриватися крапками */
.stat__table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  min-width: 1166px;
}
.stat__col-name  { width: 226px; }
.stat__col-day   { width: auto; }
.stat__col-total { width: 72px; }

/* Заголовок дня: день тижня над числом. Обидва дрібні — це підпис до
   стовпчика, а не дані до читання */
.stat__day {
  padding: 6px 0 5px;
  text-align: center;
  background: #fafbfd;
  border-bottom: 1px solid var(--c-border);
}
.stat__weekday {
  display: block;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--c-text-soft);
}
.stat__date {
  display: block;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Колонка імен. Липка — при прокрутці вбік стоїть на місці; тінь праворуч
   замість межі, бо межа поїхала б разом із рештою таблиці. Тло непрозоре:
   інакше стовпчики просвічували б крізь імена */
.stat__name {
  position: sticky;
  left: 0;
  z-index: 1;
  padding: 8px 12px;
  background: var(--c-surface);
  box-shadow: 1px 0 0 var(--c-border);
  border-bottom: 1px solid var(--c-border);
}
/* заголовок колонки імен несе назву місяця — він же й перекриває заголовки
   днів, коли таблиця під ним їде вбік, тож стоїть шаром вище за них */
.stat th.stat__name {
  z-index: 2;
  text-align: left;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  background: #fafbfd;
  border-bottom: 1px solid var(--c-border);
}

/* Підсумок за місяць — остання колонка. Липкий, як і колонка імен, тільки з
   протилежного боку: на вузькому екрані рядок їде вбік, і сума має лишатися
   на очах так само, як ім'я, — інакше по неї щоразу довелося б прокручувати
   таблицю до кінця. Тінь ліворуч замість межі — з тієї ж причини, що й у
   колонки імен: зібрані межі на липкій клітинці не малюються */
.stat__total {
  position: sticky;
  right: 0;
  z-index: 1;
  padding: 0 12px;
  text-align: right;
  white-space: nowrap;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: var(--c-surface);
  box-shadow: -1px 0 0 var(--c-border);
  border-bottom: 1px solid var(--c-border);
}
/* заголовок підсумку — підпис, як над днями, а не число: дрібний і тихий.
   Шаром вище за дні, як і заголовок колонки імен */
.stat th.stat__total {
  z-index: 2;
  padding: 6px 12px 5px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--c-text-soft);
  background: #fafbfd;
}

/* Клітинка доби. Висота стала й однакова в усіх рядках — це і є висота
   графіка, від низу до верху: дванадцятигодинний день заповнює клітинку
   цілком і впирається в межу рядка. Запасу зверху немає навмисне — саме
   впертий у стелю стовпчик і каже, що день був довгий */
.stat__cell {
  position: relative;
  height: 52px;
  padding: 0;
  border-bottom: 1px solid var(--c-border);
}
/* останній рядок межі не має — її роль грає нижній край картки */
.stat__row:last-child .stat__cell,
.stat__row:last-child .stat__total,
.stat__row:last-child .stat__name {
  border-bottom: none;
}

/* Вихідні — колонкою іншого тону, від заголовка до низу таблиці: порожня
   клітинка в ці дні означає не прогул, а те, що роботи й не чекали.
   У шапці тон темніший за тло заголовків, у рядках — за біле тло картки:
   в обох випадках крок один і той самий, тож колонка читається суцільною */
.stat__day--off {
  background: #eceff6;
}
.stat__cell--off {
  background: #f4f6fa;
}

/* Наведення веде рядок через усю ширину: тридцять колонок оком не пройти,
   і без підсвітки погляд легко з'їжджає на сусідній рядок. Вихідні під
   наведенням лишаються темнішими за будні — інакше колонка розірвалася б */
.stat__row:hover .stat__cell,
.stat__row:hover .stat__total,
.stat__row:hover .stat__name {
  background: #f8faff;
}
.stat__row:hover .stat__cell--off {
  background: #eef2f9;
}

/* Сьогодні — теж колонкою на всю висоту, тільки в колір розділу, а не в
   сірий: у таблиці за поточний місяць саме на цьому стовпчику рядок і
   уривається, і без позначки цю добу щоразу довелося б відшукувати оком
   серед тридцяти однакових чисел. За інший місяць такої колонки немає
   зовсім — і це теж відповідь: місяць закритий.

   Правила стоять після вихідних і після наведення навмисно: субота буває
   сьогоднішньою, і тоді верх бере синій. Сірий тон нічого не втрачає — який
   це день тижня, написано над числом.

   У шапці, крім тла, ще й лінія знизу — тінню всередину, а не межею:
   table-layout: fixed рахує межу в ширину колонки, і доба з нею стала б
   ширшою за сусідні, з'їхавши з-під свого числа. */
.stat__day--today {
  background: var(--c-primary-soft);
  box-shadow: inset 0 -2px 0 var(--c-primary);
}
.stat__day--today .stat__weekday,
.stat__day--today .stat__date {
  color: var(--c-primary);
}
/* Тло клітинки світліше за шапку рівно настільки, щоб стовпчик години на
   ньому лишався таким самим помітним, як на білому тлі решти діб: колонка
   позначає добу, а не приглушує дані в ній */
.stat__cell--today {
  background: #f1f5fe;
}
.stat__row:hover .stat__cell--today {
  background: #e9eefc;
}

/* Свій рядок — тлом на обох липких колонках, при імені й при підсумку, як
   своя картка в «Команді»: вони стоять по краях рядка і тримають його разом.
   Самі стовпчики лишаються в спільному кольорі: підсвічені, вони здавалися б
   більшими за сусідні, а таблицю саме про порівняння й читають */
.stat__row--me .stat__name,
.stat__row--me:hover .stat__name,
.stat__row--me .stat__total,
.stat__row--me:hover .stat__total {
  background: var(--c-primary-soft);
}
/* «Ви» при своєму імені — та сама пігулка, що в «Команді» */
.stat__me {
  padding: 1px 8px;
  flex-shrink: 0;
  border-radius: 20px;
  background: var(--c-surface);
  font-size: 12px;
  font-weight: 600;
  color: var(--c-primary);
}

/* Стовпчик години. Мірка спільна на всю таблицю: дванадцять годин на добу —
   вся клітинка, тож стовпчик рахується у відсотках від її висоти, а не в
   пікселях на годину. Через це та сама мірка сама собою тримається й на
   вузькому екрані, де клітинка нижча: міняється висота, а не пропорція.

   Дванадцять, а не десять: робочий день буває й довший, а стеля, в яку
   впирається кожен другий стовпчик, перестає бути мірою — усі переробки
   під нею стають на око однакові.

   Ширина — вся клітинка, від краю до краю: доба в таблиці й так відміряна
   колонкою, і вужчий стовпчик лише лишав би між днями порожнечу. Кути прямі,
   без заокруглень: стовпчики стоять упритул, і скошений верх різав би саме
   ту лінію, по якій висоту й порівнюють. Де закінчується день, каже число
   в клітинці */
.stat__bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(var(--h) / 12 * 100%);
  max-height: 100%;
  background: var(--c-stat);
}

/* Понад дванадцять годин. Сам стовпчик у такий день уже впирається в стелю
   й заповнює клітинку цілком — далі рости нема куди, і всі переробки, і на
   годину, і на п'ять, виглядали б однаково. Тому зверху лягає другий
   стовпчик, темніший, і росте знизу вгору на ті самі відсотки: скільки
   годин понад дванадцять, стільки в клітинці темного.

   Знизу, а не згори: там же стоїть число годин, і читати «скільки саме
   переробив» доводиться поруч із ним, а не через усю клітинку */
.stat__bar--over {
  background: var(--c-stat-over);
}

/* Число годин — унизу клітинки, на самому стовпчику. Стовпчик через це й
   світлий: темна цифра на ньому мусить читатися так само, як на білому тлі
   короткого дня, де стовпчика під нею майже немає. Стоїть завжди на одній
   лінії, хоч би якої висоти був стовпчик, — тож числа читаються ще й
   упоперек таблиці, як звичайна колонка цифр */
.stat__hours {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 3px;
  text-align: center;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--c-text);
}

/* ім'я в колонці не переноситься й не відсуває стовпчики — довге
   обрізається крапками */
.stat__name .worker {
  min-width: 0;
}
.stat__name .worker__name {
  overflow: hidden;
  text-overflow: ellipsis;
}


@media (max-width: 1100px) {
  /* Картка розпускається на всю ширину екрана: ні межі, ні тіні, ні
     заокруглень — те саме, що з рештою карток на вузькому. Прокрутки більше
     немає зовсім, тож і overflow тут уже нема за чим тримати */
  .stat {
    border: none;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
    /* низ сторінки на вузькому екрані без відступу, а таблиця впирається в
       підвал самим краєм останнього стовпчика — трохи повітря під нею */
    margin-bottom: 12px;
  }

  /* Тридцять із гаком колонок і колонка імен в один рядок на телефоні не
     стають — і не мають: замість того, щоб їхати вбік, рядок людини
     розкладається на два. Зверху ім'я і всього за місяць, під ним — увесь
     місяць на всю ширину. Заради цього таблиця й перестає бути таблицею:
     сітку колонок задає вже сам рядок, а не спільний на всю таблицю
     колонтитул */
  .stat__table {
    display: block;
    min-width: 0;
    table-layout: auto;
  }
  .stat__table colgroup,
  .stat__table thead,
  .stat__table tbody {
    display: block;
  }
  /* Шапка складається так само, як рядок людини: місяць першим поверхом,
     під ним — числа по добах тією самою сіткою. Через це число стоїть рівно
     над своїм стовпчиком і в кожному рядку нижче */
  .stat__table thead tr {
    display: grid;
    grid-template-columns: repeat(var(--days, 31), minmax(0, 1fr));
  }
  .stat th.stat__name {
    grid-row: 1;
    grid-column: 1 / -1;
    display: block;
    position: static;
    box-shadow: none;
    border-bottom: none;
  }
  /* Дня тижня в колонці завширшки з ніготь не написати — лишається саме
     число, і воно дрібне: це підпис до стовпчика, а не рядок для читання.
     Який це день тижня, каже тло вихідних — воно йде колонкою до самого низу
     таблиці й без підпису */
  .stat th.stat__day {
    grid-row: 2;
    padding: 0 0 3px;
  }
  .stat__weekday {
    display: none;
  }
  .stat th.stat__day .stat__date {
    font-size: 8px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.3px;
  }
  /* Підпис «Всього» зайвий: сума стоїть у рядку впритул до імені, а не в
     кінці довгої стрічки, де її треба було б підписувати */
  .stat th.stat__total {
    display: none;
  }

  /* Рядок людини — сітка в стільки колонок, скільки в місяці днів (--days
     ставить сторінка): у лютому їх двадцять вісім, і дорахований до
     тридцяти першої порожній хвіст лишив би стрічку недомальованою.
     Ім'я з підсумком ідуть першим рядом сітки, доби — другим.

     minmax(0, 1fr), а не просто 1fr: сама по собі колонка не вужчає за свій
     вміст, і остання роздалася б під суму за місяць, забравши ширину в
     решти. Доби тоді стали б різні, а число в шапці з'їхало б зі свого
     стовпчика */
  .stat__row {
    display: grid;
    grid-template-columns: repeat(var(--days, 31), minmax(0, 1fr));
    padding-bottom: 8px;
    border-bottom: 1px solid var(--c-border);
  }
  .stat__row:last-child {
    border-bottom: none;
  }

  /* Ім'я й сума липнути перестають — їхати вбік уже нічому. Межа теж:
     рядок тримає одну спільну, свою на кожній клітинці вона розрізала б
     двома лініями і сам рядок */
  .stat__name,
  .stat__total {
    position: static;
    box-shadow: none;
    border-bottom: none;
    align-self: center;
  }
  /* Ім'я забирає весь перший ряд, крім останньої колонки, — а сума стоїть у
     ній, притиснута до правого краю, і виходить за неї вліво: сама колонка
     завширшки в добу, у неї не стало б і «100:00». Запас праворуч в імені —
     рівно те місце, куди сума виходить: інакше довге ім'я підповзло б їй
     під цифри замість того, щоб обірватися крапками */
  .stat__name {
    grid-row: 1;
    grid-column: 1 / -2;
    padding: 8px 64px 6px 12px;
  }
  .stat__total {
    grid-row: 1;
    grid-column: -2 / -1;
    justify-self: end;
    padding: 8px 12px 6px 0;
  }
  /* «Ви» вміщається: ім'я стоїть у своєму рядку на всю ширину, а не в
     вузькій колонці, як було, коли таблиця їхала вбік */
  .stat__name .worker__avatar {
    width: 24px;
    height: 24px;
    font-size: 10px;
  }

  /* Доба — колонка сітки, а не колонка таблиці. Клітинка нижча за
     десктопну: увесь місяць тепер лежить під іменем, і рядок людини
     складається з двох поверхів. Мірка від цього не з'їжджає — стовпчик
     рахується у відсотках від висоти клітинки, тож дванадцять годин
     заповнюють її й тут.

     Ряд заданий прямо, а не лишений на розсуд сітки: у розмітці підсумок
     стоїть після діб, останнім у рядку, і сітка, розставляючи все за
     порядком у коді, засунула б першу добу в порожній кут біля імені, а
     підсумок зіпхнула б у стрічку */
  .stat__cell {
    grid-row: 2;
    height: 40px;
    border-bottom: none;
  }
  /* Години в клітинці лишаються — тільки лягають боком: у колонку в десяток
     пікселів «13:30» упоперек не стає ні за яким кеглем, а вздовж стовпчика
     стає й читається. Знизу вгору, як підписи на осях графіків: погляд іде
     туди ж, куди й сам стовпчик. Час при цьому той самий, що скрізь на
     сторінці, — обрізати його до самих годин означало б завести тут другий
     формат заради двох зайвих пікселів.

     Ширина в один кегль і поля auto — щоб рядок став точно посередині
     колонки: у боковому письмі текст ліпиться до правого краю, а поворот
     на 180° переносить його до лівого */
  .stat__hours {
    bottom: 4px;
    width: 1em;
    margin: 0 auto;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: 7px;
    line-height: 1;
    letter-spacing: -0.3px;
  }

  /* Фільтри тут стоять самі, без пошуку поруч, тож кнопки, що їх згортає, у
     розмітці немає, — те саме, що в «Команді». Місяць і рік ідуть двома
     рядками: селект у стовпчику фільтрів і так на всю ширину */
  .page-stat .page__filters {
    display: flex;
    order: 0;
  }
}

/* ============ Профіль ============ */
/* Свої дані чотирма картками: особисті дані, аватарка, пароль і підключені
   акаунти. Кожна картка — окрема форма зі своєю кнопкою, тож і на екрані
   вони мають читатися як окремі: спільна поверхня, але між ними проміжок,
   а не лінія.

   Поверхня та сама, що в .member і .project — біле тло, межа, тінь і
   --radius, — але без таблиці всередині, тож блок свій.

   Сторінка вужча за решту розділів: у полів вводу є розумна ширина, і
   розтягнуті на 1280px вони читалися б як рядки таблиці, а не як форма.

   Дві колонки: три форми стовпчиком і аватарка збоку. Аватарка одна й
   маленька, а не форма на десяток полів, тож у загальному стовпчику вона
   читалася б як порожня смуга на всю ширину */
.profile {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 240px;
  gap: 14px;
  max-width: 1000px;
}

/* Стовпчик форм. Аватарка в розмітці стоїть перед ним, а на екрані —
   праворуч від нього: на вузькому екрані колонки немає, і там вона має
   лягти під заголовок, а не під соцмережі */
.profile__main {
  display: grid;
  gap: 14px;
  grid-column: 1;
  grid-row: 1;
}

/* Аватарка збоку лишається на екрані, поки гортають форми. 81px — це
   висота шапки з її межею (61) плюс верхній паддінг сторінки (20): шапка
   сама sticky, і без цього запасу блок ліз би під неї.
   align-self: start — інакше грід розтягнув би колонку на всю висоту
   сусідньої і липнути не було б чому */
.profile__side {
  position: sticky;
  top: 81px;
  align-self: start;
  grid-column: 2;
  grid-row: 1;
}

.profile__card {
  /* картка — комірка гріда, а комірка за замовчуванням не вужча за свій
     min-content. У рядку соцмережі той min-content задає пошта: вона
     nowrap, і разом із кнопкою праворуч розпирала картку ширше за екран —
     на 320px сторінка їхала вбік. Нуль повертає розпір назад у рядок, де
     його й задумано гасити: пошта обрізається трикрапкою, кнопка ціла */
  min-width: 0;
  padding: 18px 20px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.profile__title {
  font-size: 16px;
  font-weight: 700;
}

/* Пояснення під заголовком картки або збоку від аватарки: що саме тут
   станеться. Тихіше за все навколо — його читають один раз */
.profile__hint {
  margin-top: 6px;
  color: var(--c-text-soft);
  font-size: 13px;
  line-height: 1.5;
}

/* Рядок над формою після сабміту — «збережено» або чому не вийшло: той
   самий блок, що .auth__notice на вході. Помилка окремого поля стоїть під
   самим полем */
.profile__notice {
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--c-primary-soft);
  color: var(--c-text);
  font-size: 13px;
  line-height: 1.5;
}
.profile__notice--error {
  background: #fdecec;
  color: var(--c-red-dark);
}
.profile__error {
  color: var(--c-red);
  font-size: 13px;
  line-height: 1.4;
}

/* Те саме повідомлення, але від abc-response.js: коли форму відправлено
   аджаксом, сервер відповідає 422, і скрипт сам підставляє .invalid-feedback
   під поле та вішає .is-invalid на нього. Класи чужі — з бутстрапа, на якому
   написаний рушій, — тож просто зводимо їх до свого вигляду, щоб помилка
   виглядала однаково, прийшла вона з перезавантаженням сторінки чи без */
.invalid-feedback {
  color: var(--c-red);
  font-size: 13px;
  line-height: 1.4;
}
.input.is-invalid {
  border-color: var(--c-red);
}
/* поле відповіді — не .input (у того свої паддінги під однорядкові поля),
   тож червону рамку йому треба сказати окремо */
.compose__field.is-invalid {
  border-color: var(--c-red);
}

/* Поля у дві колонки: підписи короткі, а вісім полів стовпчиком зробили б
   картку вдвічі вищою за решту сторінки. Колонки рівні й гумові — так
   ширина полів не залежить від довжини підпису */
.profile__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 16px;
}

/* Підпис із полем — той самий стовпчик, що у формі входу. Обгортка тут
   <label>, тож клік по підпису потрапляє в поле й окремого for не треба */
.profile__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* поле на всю ширину картки — так стоїть поточний пароль над двома новими */
.profile__field--wide {
  grid-column: 1 / -1;
}

.profile__label {
  color: var(--c-text-soft);
  font-size: 13px;
  font-weight: 500;
}

/* Ширину полю дає колонка, а не воно саме: .input--search і .input--filter
   тримають свої пікселі, а тут поля мають ділити рядок нарівно */
.profile__input {
  width: 100%;
}
/* Селект поясу теж тягнеться на колонку: спільне select.input міряє себе по
   вибраному пункту (--sel-w), а в сітці профілю поле має стояти врівень із
   сусідом */
select.input.profile__input {
  width: 100%;
}
/* Пояс, який людина не міняє сама, — рядок тексту на місці поля. Відступи
   поля лишаються, без рамки: текст стоїть на рівні сусіднього input, але
   не прикидається ним */
.profile__text {
  padding: 10px 0;
  font-size: 14px;
  color: var(--c-text);
}

.profile__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
}

/* Аватарка: кружечок, підказка й кнопки одна під одною по центру. Колонка
   вузька, поставити щось поруч із кружечком у ній ніде.
   Форм тут дві — завантаження і видалення, — тож стовпчиків теж два:
   зовнішній розводить форми, внутрішній розкладає саме завантаження */
.profile__avatar,
.photo-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}
.profile__avatar {
  margin-top: 16px;
}
.photo-form {
  width: 100%;
}
/* відступи між рядками тут дає gap самої колонки */
.profile__avatar .profile__hint,
.profile__avatar .profile__actions {
  margin-top: 0;
}
.profile__avatar .profile__actions {
  justify-content: center;
  flex-wrap: wrap;
}

/* Сам кружечок — він же поле завантаження: <input type="file"> схований
   усередині <label>. Виглядає як аватарка в шапці, тільки більша: поки фото
   немає, всередині ті самі ініціали на тому самому синьому, бо саме такою
   аватарку зараз бачать інші. Вибране фото JS кладе сюди <img>, який
   кружечок обрізає по собі */
.photo {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 84px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--c-primary);
  color: #fff;
  font-size: 26px;
  font-weight: 700;
  cursor: pointer;
}
.photo:hover {
  opacity: 0.9;
}
/* поки завантаження немає, кружечок — просто аватарка, а не кнопка */
.photo--static {
  cursor: default;
}
.photo--static:hover {
  opacity: 1;
}
.photo__slot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  overflow: hidden;
}
.photo__slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Фотоапарат у куті — щоб кружечок читався як кнопка вибору файла, а не як
   просто картинка. Обведення кольором картки відбиває значок від аватарки
   під ним, на якому б тлі та не стояла */
.photo__badge {
  position: absolute;
  right: -2px;
  bottom: -2px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 2px solid var(--c-surface);
  border-radius: 50%;
  background: var(--c-bg);
  color: var(--c-text-soft);
}
.photo__badge svg {
  width: 15px;
  height: 15px;
}
.photo:hover .photo__badge {
  color: var(--c-primary);
}

/* «Видалити аватарку» — не кнопка форми поруч зі «Зберегти», а тихий рядок
   під нею: дія рідкісна й незворотна, і сперечатися за увагу з головною
   кнопкою їй ні до чого. Червоною стає лише під курсором — до того колір
   у ній зайвий */
.photo__delete {
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: 13px;
  color: var(--c-text-soft);
  cursor: pointer;
}
.photo__delete:hover {
  color: var(--c-red);
}

/* Підключені акаунти: рядок на сервіс — логотип, назва зі станом і кнопка.
   Рядки ділить лінія, а не проміжок: це один список, а не окремі картки */
.profile__socials {
  margin-top: 8px;
}

.social {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
}
.social + .social {
  border-top: 1px solid var(--c-border);
}

/* Логотипи чужі й кольорові, тож лежать інлайном у розмітці, а не в
   спрайті. viewBox у них різні — квадрат однаковий задає це правило */
.social__logo {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
}

.social__body {
  flex: 1;
  min-width: 0;
}
.social__name {
  font-weight: 600;
}
/* Під назвою або пошта прив'язаного акаунта, або «Не підключено». Довга
   пошта обрізається, а не тисне кнопку праворуч */
.social__state {
  font-size: 13px;
  color: var(--c-text-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* прив'язаний — зеленим: стан видно ще до того, як прочитано сам рядок */
.social__state--on {
  color: var(--c-green);
}

/* «Підключити» — посилання, «Відключити» — кнопка сабміту; вигляд у них
   спільний, тож inline-flex і тут, і там */
.social__btn {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
a.social__btn:hover {
  text-decoration: none;
}

/* Розсилки: табличка — рядок на розсилку, колонка на канал, прапорець на
   перетині. Рядки ділить лінія, як у підключених акаунтах: це один список.
   Колонки каналів вузькі й рівні, решту ширини бере назва розсилки */
.mailing {
  width: 100%;
  margin-top: 12px;
  border-collapse: collapse;
  font-size: 14px;
}
.mailing th,
.mailing td {
  padding: 10px 0;
  text-align: left;
  vertical-align: middle;
}
.mailing thead th {
  color: var(--c-text-soft);
  font-size: 13px;
  font-weight: 500;
}
.mailing tbody tr {
  border-top: 1px solid var(--c-border);
}
.mailing .mailing__channel {
  width: 90px;
  text-align: center;
}
.mailing__name {
  font-weight: 600;
}
/* коли розсилка приходить — під назвою, тихіше */
.mailing__when {
  display: block;
  margin-top: 2px;
  color: var(--c-text-soft);
  font-size: 13px;
  font-weight: 400;
}
.mailing__box {
  width: 16px;
  height: 16px;
  accent-color: var(--c-primary);
  cursor: pointer;
}
/* канал, яким доставити нема куди, — прапорець блідий і не клікається;
   чому — пише рядок під табличкою */
.mailing__box:disabled {
  cursor: not-allowed;
}

@media (max-width: 1100px) {
  /* на 320px дві колонки по 90 з'їли б половину рядка */
  .mailing .mailing__channel {
    width: 72px;
  }

  /* колонки немає: аватарка просто лягає під заголовок сторінки, першою —
     такий у неї порядок у розмітці. Проміжок між картками той самий, що між
     групами в списках */
  .profile {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }
  .profile__main {
    gap: 10px;
    grid-column: 1;
    grid-row: 2;
  }
  /* липнути нема куди: блок такий самий на всю ширину, як решта карток */
  .profile__side {
    position: static;
    grid-column: 1;
    grid-row: 1;
  }

  /* картки лягають на всю ширину, як усюди на вузькому екрані: своєї межі
     та тіні їм більше не треба, від сірого тла їх відбиває сам білий блок */
  .profile__card {
    padding: 14px 12px;
    border: none;
    border-radius: 0;
    box-shadow: none;
  }

  /* дві колонки лишаються й тут: підписи короткі, а поля ходять парами —
     ім'я з прізвищем, новий пароль із його повтором, — і читати пару поруч
     простіше, ніж одне під одним. Стовпчиком вісім полів витягли б картку
     на два екрани. Проміжок стає менший за десктопний: у 320px ширину
     віддаємо самим полям, а не повітрю між ними */
  .profile__grid {
    gap: 10px;
  }

}


/* ============ Доступи ============ */
/* Список гілок проекту з людьми в кожній. Була тут таблиця «гілка × людина»
   з фіксованою сіткою стовпців — по стовпцю на людину, — і на десятку людей
   вона їхала вбік. Стовпців більше немає зовсім: рядок гілки і ряд імен, який
   просто переноситься, коли їх багато. Таблиці, отже, теж немає — вирівнювати
   по стовпцях нічого */
.access__row {
  display: flex;
  align-items: baseline;
  gap: 4px 16px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--c-border);
}
/* останній рядок межі не має — її роль грає нижній край плашки. Питаємо про
   останню дитину списку, а не про .access__row: під рядками може стояти
   «Додати», і тоді межа зайва вже в нього */
.access > :last-child {
  border-bottom: none;
}
.access__row:hover {
  background: #f8faff;
}

/* Гілка ліворуч фіксованою шириною: у списку вона одна на рядок, і без
   спільної ширини імена починалися б у кожному рядку з іншого місця — око
   веде саме той стовпчик, з якого вони починаються.
   Номер тихіший за назву — те саме, що в списку гілок */
.access__branch {
  flex: none;
  width: 240px;
}
.access__branch-name {
  font-weight: 600;
}
/* архівна гілка притлумлена — як у списку гілок */
.access__row--archived .branches__num,
.access__row--archived .access__branch-name {
  color: var(--c-text-soft);
}

/* Люди рядка. Переносяться самі: у гілці їх двоє-троє, але буває й більше, і
   ширину під них наперед не задають. Проміжок між людьми більший за проміжок
   між іменем і роллю всередині людини — інакше сусідня роль читалася б як
   чужа пара */
.access__people {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 18px;
  min-width: 0;
}
.access__person {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.access__name {
  font-size: 13px;
}
/* у гілці нікого — підпис на місці людей, тихий: це не помилка, а стан */
.access__none {
  font-size: 13px;
  color: var(--c-text-soft);
}

/* Рівень доступу пігулкою. Заливка світла, а не суцільна, як у .status:
   пігулок тут по одній на людину, і суцільний колір перетворив би список на
   мозаїку. Кольори ті самі, що в решті сайту, тільки взяті парою
   «фон --*-soft / текст --*» */
.level {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.level--lead      { background: var(--c-purple-soft);  color: var(--c-purple); }
.level--worker    { background: var(--c-green-soft);   color: var(--c-green); }
.level--assistant { background: var(--c-primary-soft); color: var(--c-primary); }

/* Роль — кнопка: нею відкривають попап. Пігулка від цього не міняється ні на
   піксель — той самий колір, той самий розмір, — бо змінити роль людини
   клікають саме по ролі, а не по чомусь поруч із нею.
   Що вона натискається, каже курсор і обвід на наведенні: обвід кольору самої
   пігулки, тобто того ж рівня, а не сірий системний.
   Кнопкою стає й «Виконавець»: сам цей рівень задає гілка, але попап під ним
   відкриває рівні тієї ж людини в решті гілок — свою він показує замкненою */
button.level {
  border: none;
  font-family: inherit;
  cursor: pointer;
}
button.level:hover,
button.level:focus-visible {
  box-shadow: inset 0 0 0 1px currentColor;
}

/* Рядок «Додати» під списком — і такий самий рядок під блоками паролів.
   Межі знизу в них немає (правило вище для списку, таке саме в обгортці
   блоків), а верхня приходить від останнього рядка над ними */
.access__foot,
.access__pwd-foot {
  padding: 8px 14px;
  border-bottom: 1px solid var(--c-border);
}

/* Дія — тиха текстова кнопка в колір посилання: стоїть вона під даними й
   перетягувати увагу на себе їй нема за чим. Дії «Звітів» проекту
   (.branch-add і .report-add) виглядають інакше — вони стоять не під
   списком, а в шапці розділу, і там тихий текст загубився б між вкладками.
   Класи два, бо кнопки належать різним попапам: .access__act слухає
   project-access.js, .access__pwd-add — project-passwords.js. Вигляд у них
   спільний: обидві заводять новий рядок у тому самому списку.
   Шрифт беремо від сторінки, а не браузерний: поруч у рядку стоїть
   «Редагувати» з тим самим кеглем, і два різні шрифти в одному списку видно */
.access__act,
.access__pwd-add {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: none;
  border-radius: 6px;
  background: none;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--c-primary);
  cursor: pointer;
}
.access__act:hover,
.access__pwd-add:hover {
  background: var(--c-primary-soft);
}
.access__act svg,
.access__pwd-add svg {
  width: 14px;
  height: 14px;
}
/* Від'ємний відступ з'їдає власний паддінг кнопки — рівно на нього, — і
   плюсик стає під ті самі 14px рядка, з яких починаються номери гілок */
.access__act--add,
.access__pwd-add {
  margin-left: -8px;
}

/* Підпис над плашкою: паролі й гілки лежать двома окремими плашками, і кожна
   каже, що в ній. Поки списки стояли одним, різницю між ними тримала товста
   лінія всередині плашки; тепер її тримає проміжок, а назвати списки все одно
   треба — рядки в них на вигляд однакові.
   Кегль менший за заголовок сторінки й не набагато більший за самі рядки: над
   плашкою це підпис, а не другий заголовок — сторінку вже названо в шапці
   проекту. Відступ зверху більший за нижній: підпис належить плашці під ним,
   а не тій, що над ним */
.access-caption {
  margin: 4px 0 8px;
  font-size: 14px;
  font-weight: 700;
}
/* до наступного підпису — той самий проміжок, що між картками: плашка над ним
   уже віддала свої 14px, і зайвого тут не треба */
.table-box + .access-caption {
  margin-top: 6px;
}

/* Назва блоку — кнопка на місці назви гілки: назву гілки читають, а цю
   відкривають — попапом.
   Підкреслення лишається постійним, а не тільки на наведенні: у рядку воно
   стоїть саме, без сусідів-посилань, і без риски його не відрізнити від
   жирної назви гілки навпроти.
   Риска штрихова, а не суцільна: суцільна в цій системі означає перехід —
   так підкреслені адреси в попапі паролів, — а тут нікуди не переходять,
   тут розкривають попап поверх тієї самої сторінки. Відступ під літери
   потрібен саме штриховій: упритул її штрихи зливаються з хвостиками «р» і
   «ц» у самому слові.
   Суцільною вона стає на наведенні — тим і показує, що натискається */
.access__pwd {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: inherit;
  font-weight: 600;
  color: var(--c-primary);
  cursor: pointer;
}
.access__pwd svg {
  width: 15px;
  height: 15px;
}
.access__pwd-text {
  text-decoration: underline dashed;
  text-underline-offset: 3px;
}
.access__pwd:hover .access__pwd-text {
  text-decoration: underline solid;
}

/* Ім'я в рядку паролів — те саме, що в гілці, тільки саме по собі: рівня
   поруч немає, і .access__person, який тримав пару «ім'я + пігулка», тут
   нема чого тримати */
.access__pwd-user {
  font-size: 13px;
}

/* «Редагувати» стоїть у кінці самих імен, а не окремим рядком під списком,
   тож від'ємного відступу під край рядка йому не треба — решта в нього та
   сама, що в дії під гілками */
.access__pwd-edit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  border: none;
  border-radius: 6px;
  background: none;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--c-primary);
  cursor: pointer;
}
.access__pwd-edit:hover {
  background: var(--c-primary-soft);
}
.access__pwd-edit svg {
  width: 14px;
  height: 14px;
}

@media (max-width: 700px) {
  /* Гілка стає заголовком над своїми людьми: 240px під назву — це більша
     частина вузького екрана, і людям лишалася б смужка на одне ім'я */
  .access__row {
    display: block;
    padding: 10px 12px;
  }
  .access__branch {
    width: auto;
    padding-bottom: 6px;
  }
  .access__row:hover {
    background: none;
  }
  .access__foot,
  .access__pwd-foot {
    padding: 8px 12px;
  }
}

/* ============ Попап доступів ============ */
/* Голова, тіло й хрестик у попапа ті самі, що у форми нового проекту: обидва
   — .modal__box--form із заголовком, серединою, що гортається, і кнопками
   внизу. Правила спільні, а класи в кожного свої: попапи це два різні блоки,
   і чужий __head усередині access-form читався б як помилка */
.access-form__head,
.project-form__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.access-form__close,
.project-form__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.access-form__close svg,
.project-form__close svg {
  width: 15px;
  height: 15px;
}
.access-form__close:hover,
.project-form__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}
.access-form__body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 16px;
  /* min-height нулем — інакше коробка-флекс не дасть вмісту стиснутись, і
     замість гортання довгий список гілок обрізався б знизу */
  min-height: 0;
  overflow-y: auto;
  /* поле в фокусі малює рамку в колір, і при overflow вона різалась би по
     краю коробки — тож лишаємо їй місце */
  padding: 2px;
}

/* Коробка вужча за форму проекту: там сторона і її ставка стоять одним
   рядком із чотирьох полів, а тут у рядку всього двоє — гілка й рівень */
.access-form {
  max-width: 520px;
}

.access-form__label {
  display: block;
  margin-bottom: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}
.access-form__pick .input {
  width: 100%;
}

/* Легенда рівнів — пігулка й пояснення до неї, рядком на рівень. Стоїть на
   тлі, на відміну від вибору людини: то поле форми, а це довідка, і плутати
   їх на око не можна. Пігулки в стовпчик однією шириною (min-width), інакше
   пояснення починалися б з різних місць */
.access-form__legend {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 12px;
  border-radius: 8px;
  background: var(--c-bg);
  list-style: none;
}
.access-form__legend-item {
  display: flex;
  align-items: center;
  gap: 10px;
}
.access-form__legend-item .level {
  flex-shrink: 0;
  min-width: 92px;
  text-align: center;
}
.access-form__legend-text {
  font-size: 12px;
  color: var(--c-text-soft);
}

/* «Усім гілкам» — підпис і кнопки рівнів одним рядком, з переносом: на
   вузькому екрані три кнопки в рядок не влазять, а різати їх нема куди.
   Стоїть щільно над списком гілок: рядок про те, що зараз станеться зі
   списком, — і між ними нічого чужого бути не може */
.access-form__bulk {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: -4px;
}
.access-form__bulk-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}
/* Кнопки тихі, обведенням: поруч із ними стоять пігулки рівнів, і три
   кольорові кнопки читалися б як ще одна легенда, а не як дія */
.access-form__bulk-btn {
  padding: 4px 10px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  background: var(--c-surface);
  font: inherit;
  font-size: 12px;
  color: var(--c-text);
  cursor: pointer;
}
.access-form__bulk-btn:hover {
  border-color: var(--c-primary);
  background: var(--c-primary-soft);
  color: var(--c-primary);
}

.access-form__rows {
  display: flex;
  flex-direction: column;
}

/* Рядок форми — гілка ліворуч, рівень праворуч. Гілка забирає все зайве
   місце, рівень стоїть своєю шириною: список рівнів короткий і однаковий у
   всіх рядках, тож поля вишиковуються в стовпчик самі */
.access-form__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 46px;
  padding: 4px 0;
}
.access-form__row + .access-form__row {
  border-top: 1px solid var(--c-border);
}
.access-form__branch {
  min-width: 0;
  font-weight: 600;
}
.access-form__level {
  flex-shrink: 0;
}

/* Замкнений рядок — людина вже виконавець цієї гілки. Замість поля стоїть та
   сама пігулка, що в списку */
.access-form__locked {
  display: flex;
  align-items: center;
  gap: 8px;
}
.access-form__locked[hidden] {
  display: none;
}
/* сама гілка в замкненому рядку теж тихішає: правити в ньому нічого */
.access-form__row--locked .access-form__branch {
  color: var(--c-text-soft);
}

@media (max-width: 700px) {
  /* Підпис «Усім гілкам:» забирає рядок собі, а кнопки йдуть під ним усі
     три разом: поруч із підписом вони в рядок не влазять, і остання з них
     перескакувала вниз сама, окремо від двох сусідніх */
  .access-form__bulk-label {
    flex-basis: 100%;
  }

  /* Гілка й рівень стають одне під одним: назва гілки буває довга, і поруч
     із полем вона тиснулася б у два-три рядки */
  .access-form__row {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding: 10px 0;
  }
  .access-form__level {
    width: 100%;
  }
}

/* ============ Попапи паролів ============ */
/* Їх два: сам блок під його назвою в рядку (він же заводить новий блок під
   «Додати блок») і доступ до блоку під «Редагувати» в кінці імен. Голова з
   хрестиком у них та сама, що у форми проекту й попапа доступів (див. «Попап
   доступів»), а класи свої */
.pwd__head,
.pwd-user__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.pwd__close,
.pwd-user__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.pwd__close svg,
.pwd-user__close svg {
  width: 15px;
  height: 15px;
}
.pwd__close:hover,
.pwd-user__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}
/* нижня кнопка «Закрити» ділить клас із хрестиком — вона робить те саме, —
   але вигляд у неї від .btn, і правила хрестика їй ні до чого */
.modal__actions .pwd__close {
  width: auto;
  height: auto;
  margin-left: 0;
}
/* display у кнопок голови виставлений вище, і звичайного [hidden] їм мало:
   на час правки ховається олівець, а разом із «Закрити» внизу — і хрестик
   лишається на місці */
.pwd__edit[hidden],
.pwd__close[hidden] {
  display: none;
}

/* У голові попапа паролів кнопок дві — олівець і хрестик. Праворуч їх жене
   заголовок, а не власний margin-left кожної: два авто-відступи розсунули б
   кнопки по краях голови, а олівець має зникати на час правки, не тягнучи за
   собою хрестика */
.pwd__head .modal__title {
  margin-right: auto;
}
.pwd__head .pwd__close {
  margin-left: 0;
}
/* Олівець — така сама тиха квадратна кнопка, як хрестик поруч: у голові
   попапа дві однакові за вагою дії, і виділяти одну з них нічим */
.pwd__edit {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.pwd__edit svg {
  width: 15px;
  height: 15px;
}
.pwd__edit:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Коробка вужча за форму доступів (820px), але ширша за звичайний
   .modal__box: у ній рядки тексту, і записи паролів — адреса, логін, ключ —
   часто довші за півсотні знаків, а перенесені вони читаються гірше, ніж
   одним рядком */
.pwd {
  max-width: 690px;
}
.pwd__body {
  margin-top: 16px;
  /* min-height нулем — інакше коробка-флекс не дасть вмісту стиснутись, і
     довгий текст обрізався б знизу замість гортання */
  min-height: 0;
  overflow-y: auto;
}

/* Назва блоку в правці — звичайне поле з підписом, як у решти форм. Стоїть
   над паролями й відділене від них тим самим відступом, що між полями форми
   проекту: це два різні поля одного запису, а не підпис до тексту.
   У читанні рядка немає зовсім — назву тоді показує заголовок попапа */
.pwd__name-row {
  margin-bottom: 14px;
}
.pwd__label {
  display: block;
  margin-bottom: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}
/* Поле бере всю ширину коробки: назви бувають у два-три слова, і тримати їх
   у половині рядка нема за чим */
.pwd__name {
  width: 100%;
}

/* Паролі — один текст, як його записали. Переноси й порожні рядки лишає
   white-space: саме вони й ділять текст на системи, і другого поділу —
   межами чи відступами — йому не треба.
   Моноширинний шрифт на весь блок, а не на самі паролі: де в тексті пароль,
   а де примітка, попап не знає — розмітки в ньому немає. Зате в паролі
   розрізняють «l» і «1», «O» і «0», а в звичайному шрифті вони однакові.
   Рветься по буквах: пароль — не слово, і рвати його можна де завгодно, аби
   він не виїхав за край попапа */
.pwd__text {
  white-space: pre-wrap;
  word-break: break-word;
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 13px;
  line-height: 1.7;
}
/* Адреси підкреслені постійно, а не на наведенні: у суцільному тексті інакше
   не видно, що з нього клікається */
.pwd__text a {
  text-decoration: underline;
}

.pwd__none {
  font-size: 13px;
  color: var(--c-text-soft);
}

/* Поле правки — той самий текст, тільки в полі, тож і шрифт у нього той
   самий, моноширинний: інакше рядок, набраний у правці, ставав би на місце
   іншої довжини, ніж щойно був. Росте воно вниз за текстом (resize), а межу
   йому кладе сама коробка попапа — тіло її гортається */
.pwd__field {
  width: 100%;
  min-height: 220px;
  padding: 10px 12px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text);
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 13px;
  line-height: 1.7;
  resize: vertical;
}
.pwd__field:focus {
  border-color: var(--c-primary);
  outline: none;
}

/* «Видалити блок» — така сама тиха кнопка, як «Скасувати» поруч, але з
   протилежного краю: авто-відступ праворуч розсуває її й пару «Скасувати —
   Зберегти» по кутах попапа. Дія незворотна, і промазати по ній через 8px
   проміжку було б надто легко.
   Червоною вона стає на наведенні, а не одразу: у ряду з трьох кнопок
   постійний червоний перетягував би на себе все — а натискають її раз на рік.
   display у правилі не свій, тож звичайного [hidden] тут вистачає: у читанні
   кнопки немає, і ховає її скрипт разом із рештою правки */
.pwd__del {
  margin-right: auto;
}
.pwd__del:hover {
  border-color: var(--c-red);
  color: var(--c-red);
}

/* Попап доступу до паролів: список тих, кому вони відкриті, і поле під
   наступного. Ширина йому потрібна така сама, як звичайному .modal__box, —
   у рядку тут одне поле й хрестик */
.pwd-user__body {
  margin-top: 16px;
}
/* Рядки списку. Проміжок між ними менший за проміжок до поля під наступного:
   рядки — один список, а поле під ними — вже інша дія */
.pwd-user__rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 5px;
}
.pwd-user__row {
  display: flex;
  align-items: center;
  gap: 6px;
}
/* Поле з уже доданою людиною: тло сіре, як у вимкненого, бо правити його не
   можна — людину не переписують, її прибирають і беруть іншу */
.pwd-user__input {
  min-width: 0;
  flex: 1;
  background: var(--c-bg);
}
/* Хрестик — тиха квадратна кнопка, як у голови попапа. Червоніє на
   наведенні: прибирання не скасовується нічим, окрім «Відміни» на весь попап */
.pwd-user__del {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.pwd-user__del svg {
  width: 13px;
  height: 13px;
}
.pwd-user__del:hover {
  background: var(--c-bg);
  color: var(--c-red);
}

/* Поле під наступного стоїть трохи нижче за список: між ним і рядками —
   межа між тим, хто вже є, і тим, кого додають */
.pwd-user__new {
  margin-top: 10px;
}
/* .combo — флекс, і поле в ньому саму ширину не бере */
.pwd-user__field {
  width: 100%;
}

/* Що станеться по «Зберегти» — тихим рядком під полем, як підказки рівнів у
   формі доступів */
.pwd-user__hint {
  margin-top: 8px;
  font-size: 12px;
  color: var(--c-text-soft);
}

/* ============ Попап правки питання ============ */
/* Назва питання й гілка одним вікном — під «Редагувати» в меню питання.
   Голова, тіло й хрестик ті самі, що у форми проекту й попапа доступів:
   правила спільні (див. «Попап доступів»), а класи в кожного свої */
.issue-form__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.issue-form__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.issue-form__close svg {
  width: 15px;
  height: 15px;
}
.issue-form__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Коробка найвужча з трьох форм: полів тут усього два, і в широкій вони
   розтягувались би на всю ширину екрана ні за чим.
   Гортати тут теж нема чого — але max-height лишається від .modal__box--form:
   на низькому екрані форма має обрізатись прокруткою, а не вилізти за край */
.issue-form {
  max-width: 460px;
}

.issue-form__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
  min-height: 0;
  overflow-y: auto;
  /* поле в фокусі малює рамку в колір — при overflow вона різалась би по
     краю коробки, тож лишаємо їй місце */
  padding: 2px;
}

.issue-form__field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.issue-form__field .input {
  width: 100%;
}

.issue-form__label {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* ============ Попап пов'язаних питань ============ */
/* Дерево зв'язків під гілочкою в шапці питання. Голова, тіло й хрестик ті
   самі, що в решти форм-попапів (див. «Попап доступів»), класи свої */
.tree-form__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.tree-form__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.tree-form__close svg {
  width: 15px;
  height: 15px;
}
.tree-form__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Коробка вужча за форму проекту й ширша за правку питання: рядок дерева —
   це номер, назва і статус в один рядок, і вузька коробка різала б назви
   багатокрапкою вже на другому рівні вкладення */
.tree-form {
  max-width: 640px;
}

.tree-form__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 16px;
  /* min-height нулем — інакше коробка-флекс не дасть вмісту стиснутись, і
     довге дерево обрізалось би знизу замість гортання */
  min-height: 0;
  overflow-y: auto;
  /* поле в фокусі малює рамку в колір — при overflow вона різалась би по
     краю коробки, тож лишаємо їй місце */
  padding: 2px;
}

.tree-form__label {
  display: block;
  margin-bottom: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}
.tree-form__pick .input {
  width: 100%;
}

/* Підказка, у якій номер стоїть попереду назви. У пошуку по людях і
   проектах уточнення тримається правого краю (.suggest__meta), а тут воно
   головне: номер читають першим, тож рядок починається з нього, а назва
   йде за ним і забирає решту місця — задовга обрізається багатокрапкою.
   Однакова ширина номера вишиковує назви в стовпчик, а цифри в ньому
   моноширинні — ті самі, що в номері рядка дерева */
.suggest--num .suggest__item {
  justify-content: flex-start;
  gap: 8px;
}
.suggest--num .suggest__meta {
  min-width: 30px;
  font-variant-numeric: tabular-nums;
}

/* --- Саме дерево ---
   Рядок на питання, вкладення — рейками ліворуч. Список плоский (глибину
   несе data-depth рядка), тож відступ рядку дають самі рейки: скільки їх,
   на стільки рядок і зсунуто */
.tree {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Рядок дерева. Тло непрозоре не для краси: рядок, який тягнуть, їде поверх
   сусідів, і крізь прозорий просвічували б їхні назви */
.tree__row {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 38px;
  padding-right: 4px;
  border-radius: 8px;
  background: var(--c-surface);
}
.tree__row:hover {
  background: var(--c-bg);
}
/* поточне питання — те, зі сторінки якого дерево й відкрили. Виділене тлом
   і жирнішою назвою: у дереві з десятка рядків себе шукають першим ділом */
.tree__row--current,
.tree__row--current:hover {
  background: var(--c-primary-soft);
}
.tree__title--current {
  font-weight: 700;
}

/* Рейки зв'язків — по одній на рівень вкладення. Ширина тут та сама, що
   TREE_STEP в issue-tree.js: нею ж рахується, на скільки рівнів відвели
   руку при перетягуванні, і розійтися їм не можна */
.tree__rails {
  display: flex;
  flex: none;
  align-self: stretch;
}
.tree__rail {
  position: relative;
  width: 22px;
}
/* Вертикаль рівня. Наскрізна там, де в предка нижче ще лишились сусіди;
   під останньою дитиною вона доходить до коліна й уривається — інакше
   лінія висіла б у порожнечу. Який із двох випадків, вирішує JS: по
   самому рядку цього не видно */
.tree__rail--through::before,
.tree__rail--elbow::before {
  content: '';
  position: absolute;
  left: 11px;
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--c-border);
}
.tree__rail--elbow:not(.tree__rail--through)::before {
  bottom: auto;
  height: 50%;
}
/* поличка від вертикалі до самого рядка — те коліно, що й робить список
   деревом на око */
.tree__rail--elbow::after {
  content: '';
  position: absolute;
  left: 11px;
  top: 50%;
  width: 9px;
  border-top: 1px solid var(--c-border);
}

/* Рукоятка. Тиха, поки рядок не чіпають: у дереві з десятка рядків десяток
   значків читався б як візерунок. touch-action знімає гортання пальцем по
   самій рукоятці — інакше на дотику список їхав би замість рядка */
.tree__grip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 24px;
  height: 26px;
  margin-right: 2px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--c-act);
  cursor: grab;
  touch-action: none;
}
.tree__grip svg {
  width: 14px;
  height: 14px;
}
.tree__grip:hover,
.tree__grip:focus-visible {
  background: var(--c-bg);
  color: var(--c-text-soft);
}
.tree--drag .tree__grip {
  cursor: grabbing;
}

/* Номер із назвою — те саме, що в рядку списку питань (.issues__title):
   назва жирна, номер перед нею тихий і моноширинний */
.tree__title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
  color: var(--c-text);
}
a.tree__title:hover,
a.tree__title:hover .tree__num {
  color: var(--c-primary);
  text-decoration: none;
}
.tree__num {
  margin-right: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
  font-variant-numeric: tabular-nums;
}

.tree__status {
  flex: none;
  margin: 0 6px 0 10px;
}

/* Хрестик рве зв'язок із питанням — саме питання нікуди не дівається, тож
   він тихий і червоніє лише під курсором, як решта незворотних дій */
.tree__unlink {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.tree__unlink svg {
  width: 14px;
  height: 14px;
}
.tree__unlink:hover {
  background: var(--c-surface);
  color: var(--c-red);
}
.tree__row--current .tree__unlink:hover {
  background: var(--c-surface);
}

/* --- Перетягування ---
   Рядок, який тягнуть, лишається на своєму місці в списку й лише зсунутий
   полем transform: так решта рядків не стрибає під курсором, а місце, куди
   він ляже, показує риска нижче. Кліки йому тепер ні до чого — під
   курсором має бути список, а не сам рядок */
.tree--drag {
  user-select: none;
}
.tree__row--drag {
  z-index: 2;
  box-shadow: var(--shadow);
  pointer-events: none;
}
/* поки тягнуть, підсвітка на наведення тільки заважає читати місце вставки */
.tree--drag .tree__row:hover {
  background: var(--c-surface);
}
.tree--drag .tree__row--current:hover {
  background: var(--c-primary-soft);
}

/* Місце майбутньої вставки. Висоти в риски немає, а сама лінія намальована
   поверх: із власною висотою список смикався б на кожен рух руки. Відступ
   ліворуч ставить JS — це і є та глибина, на яку рядок ляже */
.tree__drop {
  position: relative;
  height: 0;
  list-style: none;
}
.tree__drop::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--c-primary);
}

@media (max-width: 700px) {
  /* Статус у вузькому рядку з'їдає назву — а назва тут головне: дерево
     читають, щоб зрозуміти, з чого що виросло. Стан питання видно в його
     власній шапці, до якої звідси один клік */
  .tree__status {
    display: none;
  }
  .tree__rail {
    width: 16px;
  }
}

/* ============ Попап нового питання ============ */
/* Усе, з чого починається питання, одним вікном — під «плюсом» у шапці
   сайту: проект із гілкою, назва зі станами й опис у редакторі. Голова,
   тіло й хрестик ті самі, що в решти форм-попапів (див. «Попап доступів»),
   класи свої.

   Коробка ширша за правку питання, але вужча за форму проекту: рядків у
   ряд тут майже не стоїть, а от опис — це вже сторінка тексту, і у вузькій
   коробці рядки в ньому дрібнішали б до неможливого */
.issue-add__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.issue-add__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.issue-add__close svg {
  width: 15px;
  height: 15px;
}
.issue-add__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

.issue-add {
  max-width: 720px;
}

.issue-add__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 16px;
  /* min-height нулем — інакше коробка-флекс не дасть вмісту стиснутись, і
     замість гортання форма просто обрізалась би знизу */
  min-height: 0;
  overflow-y: auto;
  /* поле в фокусі малює рамку в колір — при overflow вона різалась би по
     краю коробки, тож лишаємо їй місце */
  padding: 2px;
}

/* Проект і гілка одним рядком: проект бере всю ширину, що лишилась, гілка
   стоїть числом — під найдовший свій пункт */
.issue-add__row {
  display: flex;
  gap: 12px;
}

.issue-add__field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  /* поле в рядку не має тиснутись під довгим підписом сусіда */
  min-width: 0;
  flex: 1;
}
/* Проект і гілка ділять свій рядок навпіл: обидва — flex: 1 від
   .issue-add__field, і власної ширини гілці більше не дають. Раніше вона
   стояла на 220px під найдовший свій пункт, але з виконавцем у дужках пункти
   стали довшими, і фіксована ширина тільки обрізала б їх трикрапкою */
.issue-add__field .input {
  width: 100%;
}

/* Поле проекту — той самий блок, що й пошук у фільтрах (parts/search.php),
   тільки в колонці форми, а не в рядку шапки: і саме поле, і коробка
   вибору беруть усю ширину, замість власних 260px пошуку.
   Підказці лишаємо межу, нижчу за її звичайні 320px: тіло попапа
   гортається, і довший список ховався б за його краєм */
.issue-add__field--project .search {
  width: 100%;
}
.issue-add__field--project .search__pick {
  width: 100%;
}
.issue-add__field--project .suggest {
  max-width: none;
  max-height: 220px;
}
/* Вибір тут ставить не сервер, а браузер: на сторінках коробка приходить
   або полем, або блоком із назвою запису, бо вибір лежить в адресі, — а в
   попапі вибирають значення, і обидва стани лежать у розмітці разом
   (issue-add.js показує один із них). Схований блок має саме зникати:
   display: flex із .search__pick інакше сильніший за [hidden] */
.issue-add__field--project .search__pick[hidden] {
  display: none;
}
/* Хрестик у полі попапа один і тримається краю: лупи поруч немає — шукати
   тут нема куди відправляти, підказка приходить сама. Показуємо його, поки
   є що скидати: вибраний проект або набране в полі */
.issue-add__field--project .search__clear {
  display: none;
  right: 4px;
}
.issue-add__field--project .search:has(.search__pick:not([hidden])) .search__clear,
.issue-add__field--project .search:has(.input--search:not(:placeholder-shown)) .search__clear {
  display: flex;
}
/* і поле відступає праворуч під один хрестик, а не під пару кнопок */
.issue-add__field--project .search:has(.input--search:not(:placeholder-shown)) .input--search {
  padding-right: 40px;
}

/* Форму відмовили — рядок про це стоїть угорі тіла попапа, над полями:
   попап відкривається сам, з набраним усередині, і прочитати відмову
   більше ніде (partials/issue_add) */
.issue-add__error {
  margin: 0;
  padding: 8px 12px;
  border-radius: 8px;
  background: #fdecec;
  color: var(--c-red-dark);
  font-size: 13px;
}

/* Підпис поля. inline-flex — через позначку мови в підписі «Опис»: вона
   вища за сам рядок, і без вирівнювання по центру сиділа б на базовій
   лінії, задираючи слово вгору */
.issue-add__label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* Стани під назвою — свій рядок на всю ширину. У шапці форми відповіді ті
   самі три селекти тісняться в ряд з іменем і мають там фіксовану ширину
   (див. .compose__states); тут рядок їхній власний, і ділять вони його
   нарівно: лишати посеред нього порожнечу нема за чим.
   Селектів у рядку три або чотири — своїм його бачить лише команда
   ($seeInternal), і видимість стає до них четвертою, — тож ширину їм дає
   flex, а не жодне число: рядок ділиться на стільки, скільки їх прийшло.
   min-width: 0 — щоб рядок ділився саме нарівно: власна ширина найдовшого
   пункту інакше не дала б полю стиснутись і зіпхнула б сусідів. Підпис, що
   не вліз, обрізає трикрапка — у розкритому списку він усе одно цілий */
.issue-add__states {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 4px;
}
.issue-add__states select.input {
  flex: 1;
  min-width: 0;
  width: auto;
  text-overflow: ellipsis;
}

/* Опис — та сама картка, що на сторінці питання, тільки без тіні: там вона
   стоїть карткою на сторінці, а тут це поле однієї форми, і тінь читалась
   би як зайвий шар усередині попапа */
.issue-add__brief {
  box-shadow: none;
}
.issue-add__brief .brief__box {
  padding: 12px 16px 16px;
}
/* редактор порожній, поки в описі нічого не набрали, — тримаємо йому висоту,
   інакше картка складалася б у смужку */
.issue-add__brief .brief__editor {
  min-height: 120px;
}

/* На вузькому екрані гілка йде під проект: удвох у рядку вони лишили б
   назві проекту кілька літер. Стани лишаються рядком — трьома вони
   вміщаються так само, як у розкритій .compose.
   Але команді їх приходить чотири (видимість), і вчотирьох на такій ширині
   від підписів лишилися б самі трикрапки, — тож четвертий складає рядок
   удвічі, квадратом 2×2. Умова на кількість, а не на роль: :nth-last-child
   рахує, скільки селектів у рядку насправді, і поки їх троє, правило мовчить:
   рядок клієнта лишається таким, яким і був.
   Основа — половина рядка за відрахуванням проміжку, flex-grow лишається
   одиницею: два в ряд, два під ними */
@media (max-width: 640px) {
  .issue-add__row {
    flex-direction: column;
  }
  .issue-add__states {
    gap: 8px;
  }
  .issue-add__states select.input:nth-last-child(n+4),
  .issue-add__states select.input:nth-last-child(n+4) ~ select.input {
    flex-basis: calc(50% - 4px);
  }
}

/* ============ Попап правки повідомлення ============ */
/* Текст повідомлення й вкладення до нього — під «Редагувати» в меню
   повідомлення. Голова, тіло й хрестик ті самі, що в решти форм-попапів
   (див. «Попап доступів»), класи свої */
.msg-form__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.msg-form__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.msg-form__close svg {
  width: 15px;
  height: 15px;
}
.msg-form__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Ширина по формі відповіді, а не по формі проекту: правлять тут той самий
   текст, що набирали там, і рядки мають ламатися так само */
.msg-form {
  max-width: 640px;
}

.msg-form__body {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  margin-top: 16px;
  /* поле в фокусі малює рамку в колір — при overflow вона різалась би по
     краю коробки, тож лишаємо їй місце */
  padding: 2px;
}

/* Поле — те саме, що у формі відповіді: та сама рамка, той самий розмір
   тексту. Росте воно не під текст, а до стелі коробки: попап уже й так
   стоїть по центру екрана, і стрибати за кожним рядком йому нема куди */
.msg-form__field {
  width: 100%;
  min-height: 160px;
  padding: 10px 12px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  color: var(--c-text);
  font: inherit;
  resize: vertical;
}
.msg-form__field:focus {
  border-color: var(--c-primary);
  outline: none;
}

/* Поки їде текст повідомлення, поле замкнене: його наливає сервер, а не
   розмітка гілки (/assets/js/msg-edit.js). Мить, тож без спінера — просто
   тьмяне поле, у якому ще нема чого правити */
.msg-form__field:disabled {
  background: var(--c-bg);
  color: var(--c-text-soft);
  cursor: default;
}

/* Вкладення — ті самі плитки, що під повідомленням і у формі відповіді */
.msg-form__files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
  list-style: none;
}
.msg-form__files[hidden] {
  display: none;
}

/* «Прикріпити файл» стоїть у ряду кнопок ліворуч — margin-right: auto
   відсуває до нього «Відмінити» й «Зберегти». Сам <input type="file">
   схований у підписі, тож клік по тексту відкриває вибір файлів без JS */
.msg-form__attach {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-right: auto;
  color: var(--c-text-soft);
  font-weight: 500;
  cursor: pointer;
}
.msg-form__attach:hover {
  color: var(--c-primary);
}
.msg-form__attach svg {
  width: 16px;
  height: 16px;
}

/* На вузькому екрані підпис із кнопками в один рядок не вміщається:
   «Прикріпити файл» іде своїм рядком над ними */
@media (max-width: 520px) {
  .msg-form .modal__actions {
    flex-wrap: wrap;
  }
  .msg-form__attach {
    width: 100%;
    margin-right: 0;
  }
}


/* ============ Попап правки гілки ============ */
/* Назва гілки й три оплати — під олівцем у першій колонці «Звітів».
   Голова, тіло й хрестик ті самі, що в решти форм-попапів (див. «Попап
   доступів»), класи свої */
.branch-form__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.branch-form__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.branch-form__close svg {
  width: 15px;
  height: 15px;
}
.branch-form__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Коробка вужча за форму нового проекту: там у рядку сторони чотири поля —
   разом із самою людиною, — а тут людину не вибирають, і полів три */
.branch-form {
  max-width: 700px;
}

.branch-form__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
  /* min-height нулем — інакше коробка-флекс не дасть вмісту стиснутись, і
     замість гортання форма обрізалась би знизу */
  min-height: 0;
  overflow-y: auto;
  /* поле в фокусі малює рамку в колір — при overflow вона різалась би по
     краю коробки, тож лишаємо їй місце */
  padding: 2px;
}

.branch-form__field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  /* поле в стовпчику не має тиснутись під довгим підписом сусіда */
  min-width: 0;
}
.branch-form__field .input {
  width: 100%;
}

.branch-form__label {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* Рядок форми. Поля міряються по нижньому краю — так само, як у формі
   нового проекту: підпис в одному з них може перейти на другий рядок */
.branch-form__row {
  display: grid;
  gap: 10px;
  align-items: end;
}

/* Назва гілки і галочка «за замовчуванням»: назві — вся ширина, що
   лишилась, галочці — рівно її підпис. Верхньої межі тут немає: вона
   розділяє сторони нижче, а назва з галочкою — і є перший рядок форми */
.branch-form__row--name {
  grid-template-columns: 1fr auto;
}

/* Галочка стоїть у рядок із набраною назвою, а не з підписом над нею.
   Вертикальні відступи й рамка ті самі, що в .input поруч, тільки рамка
   прозора: так висота підпису збігається з висотою поля сама, без числа в
   пікселях, — а рядок міряється по нижньому краю */
.branch-form__check {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 0;
  border: 1px solid transparent;
  font-size: 14px;
  white-space: nowrap;
  cursor: pointer;
}
.branch-form__box {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  accent-color: var(--c-primary);
  cursor: pointer;
}

/* Сторона і її оплата: підпис із іменем, форма оплати, сума, валюта.
   Пропорції ті самі, що у формі нового проекту, — форми стоять поруч у
   роботі, і рядок ставки має читатись однаково в обох.
   Верхня межа розділяє сторони: три однакові рядки поспіль без неї злилися
   б в одну решітку з дев'яти полів */
.branch-form__row--party {
  grid-template-columns: 1.7fr 1.1fr 0.9fr 1fr;
  padding-top: 12px;
  border-top: 1px solid var(--c-border);
}

/* Підпис сторони на місці поля людини: сама сторона зверху, під нею ім'я.
   Ім'я тут довідка, а не вибір — кого гілці призначили, видно в її рядку і
   в «Доступах», — тож і кегль у нього менший за підпис */
.branch-form__side {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  /* рядок міряється по нижньому краю полів, а підпис стоїть без поля —
     опускаємо його на висоту рамки, щоб імена стали в один рядок із
     набраним у сусідніх полях */
  padding-bottom: 7px;
}
.branch-form__side-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}
.branch-form__who {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* сторони в гілці ще немає — ставку їй ставлять наперед */
.branch-form__who--none {
  font-weight: 400;
  color: var(--c-text-soft);
}

/* На вузькому екрані коробка стає майже на всю ширину, і чотири колонки в
   рядок уже не влазять: підпис сторони йде окремим рядком, а три поля під
   ним розкладаються самі — так само, як у формі нового проекту */
@media (max-width: 700px) {
  .branch-form__row--party {
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  }
  .branch-form__row--party > .branch-form__side {
    grid-column: 1 / -1;
    padding-bottom: 0;
  }
}


/* ============ Попап нового звіту ============ */
/* Гілка, тип і рядки «що зроблено — скільки часу» — під кнопкою «Додати
   звіт» на «Звітах» проекту. Голова, тіло й хрестик ті самі, що в решти
   форм-попапів (див. «Попап доступів»), класи свої.
   Самі рядки — .report-line і .report-time зі сторінки «Додати звіти»
   (нижче, «Форма звітів»): це один і той самий рядок звіту, і виглядати
   він має однаково, звідки б звіт не заводили */
.report-new__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.report-new__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.report-new__close svg {
  width: 15px;
  height: 15px;
}
.report-new__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Коробка найвужча з попапів сторінки: у формі два селекти в рядок і текст
   під ними — ширше їй нічим було б розпорядитись, а довгий рядок тексту
   читається гірше за короткий */
.report-new {
  max-width: 560px;
}

.report-new__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
  /* min-height нулем — інакше коробка-флекс не дасть вмісту стиснутись, і
     замість гортання форма обрізалась би знизу: рядків у звіті буває
     скільки завгодно */
  min-height: 0;
  overflow-y: auto;
  /* поле в фокусі малює рамку в колір — при overflow вона різалась би по
     краю коробки, тож лишаємо їй місце */
  padding: 2px;
}

.report-new__field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  /* поле в стовпчику не має тиснутись під довгим підписом сусіда */
  min-width: 0;
}
.report-new__field .input {
  width: 100%;
}

.report-new__label {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* Гілка, тип і дата одним рядком. Гілці більше: у ній номер і назва, а тип —
   два слова, з яких довше «Доробка». Дата — поле сталої ширини: число в ньому
   завжди однакової довжини, і ділити з ним залишок рядка нема за чим.
   Поля міряються по нижньому краю — так само, як у решти форм: підпис в
   одному з них може перейти на другий рядок */
.report-new__row {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) 150px;
  gap: 10px;
  align-items: end;
}

/* Рядки звіту одним стовпчиком — той самий проміжок, що між ними на
   сторінці «Додати звіти» */
.report-new__lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Рядок тут із двох колонок, а не з трьох: третя на «Додати звіти» тримає
   місце під хрестик, який прибирає питання з таймера. Питань тут немає —
   усі рядки набирають руками, — і порожня колонка лише відсунула б час від
   правого краю */
.report-new .report-line {
  grid-template-columns: minmax(0, 1fr) auto;
}

/* На вузькому екрані коробка стає майже на всю ширину, і два селекти в
   рядок уже тиснуть один одного: назва гілки в них довга */
@media (max-width: 480px) {
  .report-new__row {
    grid-template-columns: 1fr;
  }
}


/* ============ Легенда стану ============ */
/* Що означає кожен пункт трьох селектів у шапці форми відповіді — під знаком
   питання перед ними. Голова, тіло й хрестик ті самі, що в решти
   форм-попапів (див. «Попап доступів»), класи свої.
   Коробка стоїть після .modal__box--form навмисно: свою ширину вона перебиває
   тим, що йде пізніше, — специфічність в обох по одному класу */
.legend {
  max-width: 640px;
}

.legend__head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.legend__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.legend__close svg {
  width: 15px;
  height: 15px;
}
.legend__close:hover {
  background: var(--c-bg);
  color: var(--c-text);
}

/* Групи — по одній на селект. Гортається саме тіло, а не вся коробка:
   заголовок із хрестиком лишається на місці, як у формі проекту */
.legend__body {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-top: 16px;
  min-height: 0;
  overflow-y: auto;
}

.legend__subtitle {
  font-size: 14px;
  font-weight: 700;
}
.legend__list {
  margin-top: 10px;
  list-style: none;
}

/* Маркер із підписом ліворуч, пояснення праворуч. Колонка маркера однакова
   в усіх групах — інакше списки роз'їхалися б і легенда читалася б як
   чотири різні таблиці. Ширина по найдовшому підпису («Виправлення помилки»).
   justify-items не дає пігулці розтягтися на всю колонку: на сайті вона
   всюди завширшки зі свій підпис */
.legend__item {
  display: grid;
  grid-template-columns: 172px minmax(0, 1fr);
  align-items: start;
  justify-items: start;
  gap: 12px;
  font-size: 13px;
}
.legend__item + .legend__item {
  margin-top: 10px;
}
/* підпис із маркером — самі маркери ті самі, що в списку питань: іконка
   терміновості, жучок типу і пігулка статусу. У «звичайної» терміновості
   й у доробки маркера немає й тут — саме це в рядку й показано */
.legend__mark {
  display: flex;
  align-items: center;
  font-weight: 600;
}
/* рядок без маркера — та сама «звичайна» терміновість і доробка. Порожнє
   поле рівно там, де в сусідів іконка: 14px самого значка плюс 6px його
   відступу (.kind). Підписи в групі стають на одну вертикаль, і видно, що
   маркера тут немає, а не що рядок з іншої колонки */
.legend__mark--bare {
  padding-left: 20px;
}
.legend__text {
  color: var(--c-text-soft);
  line-height: 1.45;
}

/* На вузькому екрані двох колонок немає: підпис стає над поясненням —
   на 172px маркера й 12px відступу від тексту лишалася б смужка */
@media (max-width: 560px) {
  .legend__item {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }
}

/* ============ Таймер питання ============ */
/* Блок у правому нижньому куті сторінки питання — розмітка в кінці
   templates/modules/projects/issue.blade.php, поведінка в timer.js.
   position: fixed, а не sticky в колонці: час вмикають посеред роботи, коли
   переписка догортана куди завгодно, і кнопка має стояти на тому самому
   місці на будь-якій висоті сторінки.
   Кут лівий: правий низ на телефоні зайнятий — і кнопками самого браузера, і
   тим, що туди звично кладуть, — і таймер там просто не видно.
   z-index між шапкою (10) і попапами-меню (40): таймер має лежати поверх
   сторінки, але під усім, що з неї відкривається */
.timer {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 150px;
}

/* Картка з годинником і кнопкою. Поверхня саме на ній, а не на всьому
   блоці: над карткою стоїть ще й «Додати звіти» окремою плашкою, і зникнути
   воно має без наслідків для решти. Блок при цьому притиснутий низом, тож
   картка від того не рушить з місця — а рушила б, якби посилання займало
   висоту всередині неї */
.timer__card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Годинник. По центру блока, як і кнопка під ним: рядок міняється щосекунди,
   і від краю він то відступав би, то ні — а посередині годинам, яких за день
   набігає й два розряди, є куди рости в обидва боки.
   Цифри табличні: у пропорційних одиниця вужча за решту, і рядок смикався б
   шириною на кожній секунді */
.timer__clock {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--c-text-soft);
}
.timer__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.timer__time {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

/* Поки час іде, червоніє вся картка, а не рядок усередині неї: таймер
   стоїть у куті екрана, і помітити його запущеним треба боковим зором, не
   вчитуючись у цифри. Годинник на заливці — білий */
.timer--on .timer__card {
  background: var(--c-red);
  border-color: var(--c-red);
}
.timer--on .timer__clock {
  color: #fff;
}

/* Кнопки стоять на всю ширину блока: у кожному стані вона там одна —
   «Старт» або «Стоп», — і вирівнювати її по краю нема з чим */
.timer__actions {
  display: flex;
}
.timer__start,
.timer__stop {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
}
.timer__start svg,
.timer__stop svg {
  width: 13px;
  height: 13px;
}
/* display: flex сам по собі заступив би hidden — ховаємо явно, як і хрестик
   вибраної людини в полі з автопідказкою */
.timer__start[hidden],
.timer__stop[hidden] {
  display: none;
}

/* «Старт» червоний, а не синій .btn--primary, як решта головних кнопок:
   блок стоїть поверх сторінки, а не в ній, і в синьому губився б серед
   посилань і плашок під собою — на телефоні його просто не помічали.
   Червоний тут не про небезпеку, а про єдину дію в куті екрана. Рамка, а не
   заливка: суцільний червоний у цього блока значить «час іде», і вимкнений
   таймер його не займає — під наведенням кнопка якраз ним і заливається,
   показуючи, у що перейде блок */
.timer__start {
  background: var(--c-surface);
  border: 1px solid var(--c-red);
  color: var(--c-red);
}
.timer__start:hover {
  background: var(--c-red);
  color: #fff;
}

/* «Стоп» стоїть уже на червоному, тож ті самі два кольори міняються
   місцями: біла заливка, червоний напис. Стани лишаються різними на вигляд,
   а не тільки написом */
.timer__stop {
  background: var(--c-surface);
  border: 1px solid var(--c-surface);
  color: var(--c-red);
}
.timer__stop:hover {
  background: var(--c-bg);
}

/* Звіти заводять, коли час уже не йде, — тож посилання є лише у вимкненого
   таймера. Запущений його прибирає: серед дня з питання не йдуть. Картка під
   ним від того не рухається — блок стоїть на низу екрана, і зникла плашка
   тягне за собою тільки порожнє місце над карткою.
   Плашка своя, а не просто рядок: посилання лежить уже не на картці, а на
   самій сторінці, і без поверхні під собою читалося б поверх переписки */
.timer__reports {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  font-size: 13px;
  font-weight: 600;
}
.timer__reports svg {
  width: 14px;
  height: 14px;
}
.timer--on .timer__reports {
  display: none;
}

/* Поля під таймер сторінка не тримає: він стоїть у куті поверх неї, і
   порожня смуга в кінці читалася б як обрив сторінки, а не як повітря. Кінець
   сторінки тут такий самий, як усюди, — див. .page. Клас page--timer ставить
   PHP тим, у кого таймер є, і потрібен він лише формі відповіді нижче.

   Тут таймер ще карткою в куті — а от знизу вже смугою, і поля під нього не
   треба зовсім (див. @media 700px). Стільки, скільки картка займає від низу
   екрана (165px), без підвалу (54px): його вона накриває однаково, і місця
   там нікому не треба. Решта — повітря, щоб кнопки форми не впиралися в неї */
@media (min-width: 701px) and (max-width: 1100px) {
  .page--timer .compose {
    padding-bottom: 132px;
  }
}

/* На телефоні таймер — не картка в куті, а смуга на всю ширину внизу екрана:
   годинник, кнопка й «Додати звіти» одним рядком. Картка тут завелика — вона
   лізла поверх переписки, та ще й тримала під себе порожнє поле в кінці
   сторінки. Смуга не тримає нічого: вона стоїть рівно на місці підвалу й
   накриває саме його, а не те, що читають */
@media (max-width: 700px) {
  .timer {
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    /* поверхня тепер на самій смузі, а не на картці всередині неї: смуга
       лежить поверх переписки, і без тла крізь неї читався б текст */
    background: var(--c-surface);
    border-top: 1px solid var(--c-border);
  }
  /* картка й плашка в смузі — просто групи елементів рядка: своєї поверхні
     в них більше немає, її тримає смуга */
  .timer__card,
  .timer--on .timer__card {
    flex-direction: row;
    align-items: center;
    gap: 12px;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
  }
  .timer__reports {
    /* у розмітці посилання стоїть перед карткою — у рядку воно останнє,
       і йде до правого краю смуги */
    order: 1;
    margin-left: auto;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
    /* підпис у два слова, і на 320px він переносився — смуга від того ставала
       вдвічі вища й перестала збігатися з підвалом, який накриває */
    white-space: nowrap;
  }
  /* годинник у смузі не стискається: цифри тут — головне, і обрізати їх
     нема куди. Місце під три елементи в рядку набирається меншим значком і
     тіснішим проміжком — на 320px усі троє вміщаються рівно */
  .timer__clock {
    flex-shrink: 0;
    gap: 6px;
  }
  .timer__icon {
    width: 16px;
    height: 16px;
  }
  /* час іде — червоніє вся смуга: картки, яку можна було залити, тут немає */
  .timer--on {
    background: var(--c-red);
    border-top-color: var(--c-red);
  }
  .timer__time {
    font-size: 19px;
  }
  /* кнопка в рядку міряється написом, а не шириною блока */
  .timer__start,
  .timer__stop {
    width: auto;
    padding: 8px 14px;
    font-size: 13px;
  }
}


/* Поки по питанню сторінки йде час, блок схований — увімкнений лічильник
   показує смуга внизу (.timer-bar); display: flex інакше сильніший за
   [hidden] */
.timer[hidden] {
  display: none;
}

/* ============ Таймер унизу ============ */
/* Увімкнений лічильник виглядає однаково на кожній сторінці, на самому
   питанні теж: червона смуга на всю ширину, прикріплена до низу екрана.
   Висотою вона рівно з підвал (--footer-h), тож у кінці сторінки лягає точно
   на нього й накриває цілком, а посеред сторінки — лише стільки ж, скільки
   займав би підвал. Питання з посиланням, годинник і «Стоп» —
   partials/timer_bar, поведінка в timer.js. Шапка тим часом червона
   (.topbar--timer, нижче).
   z-index той самий, що в блока .timer: поверх сторінки, під попапами */
.timer-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--footer-h);
  padding: 0 28px;
  background: var(--c-red);
  color: #fff;
  font-weight: 600;
}
.timer-bar[hidden] {
  display: none;
}
.timer-bar__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
/* Назва питання стискається першою й обрізається трикрапкою — аж до нуля.
   Номер, годинник і кнопка не стискаються ніколи — по номеру питання
   впізнають, а повна назва є в підказці посилання */
.timer-bar__issue {
  display: flex;
  gap: 6px;
  min-width: 0;
  white-space: nowrap;
  color: #fff;
}
.timer-bar__issue:hover {
  color: #fff;
  text-decoration: underline;
}
.timer-bar__number {
  flex-shrink: 0;
  opacity: 0.8;
}
.timer-bar__title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* годинник і «Стоп» — до правого краю. Цифри табличні — інакше рядок
   смикався б шириною щосекунди */
.timer-bar__time {
  flex-shrink: 0;
  margin-left: auto;
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* «Стоп» на червоному — біла заливка й червоний напис, як у прототипі */
.timer-bar__stop {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  padding: 7px 14px;
  background: var(--c-surface);
  color: var(--c-red);
  font-size: 13px;
}
.timer-bar__stop:hover {
  background: var(--c-bg);
}
.timer-bar__stop svg {
  width: 12px;
  height: 12px;
}

/* Лічильник іде по іншому питанню, а на цьому стоїть блок зі «Стартом» —
   блок піднімається над смугою, щоб вона його не накрила. Формі відповіді
   на планшеті — стільки ж поля більше (див. .page--timer .compose) */
body:has(.timer-bar:not([hidden])) .timer {
  bottom: calc(var(--footer-h) + 20px);
}
@media (min-width: 701px) and (max-width: 1100px) {
  body:has(.timer-bar:not([hidden])) .page--timer .compose {
    padding-bottom: calc(132px + var(--footer-h));
  }
}

/* Поки лічильник іде, шапка червона на будь-якій ширині. Написи на ній білі,
   «плюс» і бургер — напівпрозорим білим: синя заливка на червоному тлі
   кричала б двома кольорами одразу */
.topbar--timer {
  background: var(--c-red);
  border-bottom-color: var(--c-red);
}
.topbar--timer .topbar__logo,
.topbar--timer .topbar__logo span,
.topbar--timer .topbar__user-name,
.topbar--timer .user-btn:hover .topbar__user-name,
.topbar--timer .user-btn[aria-expanded="true"] .topbar__user-name {
  color: #fff;
}
.topbar--timer .add-btn,
.topbar--timer .burger {
  background: rgba(255, 255, 255, 0.2);
  border-color: transparent;
  color: #fff;
}
.topbar--timer .add-btn:hover,
.topbar--timer .burger:hover,
.topbar--timer .burger[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.32);
  color: #fff;
}
.topbar--timer .burger__icon span,
.topbar--timer .burger[aria-expanded="true"] .burger__icon span {
  background: #fff;
}
.topbar--timer .topbar__avatar {
  background: #fff;
  color: var(--c-red);
}

/* Пункти меню стоять у самій шапці лише на широкому екрані — підсвітка
   напівпрозорим білим замість світло-синього, який на червоному не
   читається. На вузькому меню випадає білою панеллю, і там усе як завжди */
@media (min-width: 1101px) {
  .topbar--timer .topbar__link {
    color: rgba(255, 255, 255, 0.85);
  }
  .topbar--timer .topbar__link:hover {
    background: rgba(255, 255, 255, 0.15);
    color: #fff;
  }
  .topbar--timer .topbar__link--active {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
  }
}

@media (max-width: 1100px) {
  .timer-bar {
    gap: 8px;
    padding: 0 14px;
    font-size: 13px;
  }
  .timer-bar__icon {
    width: 16px;
    height: 16px;
  }
  .timer-bar__time {
    font-size: 17px;
  }
}

/* На телефоні блок зі «Стартом» сам смуга внизу — над червоною смугою
   він стає впритул */
@media (max-width: 700px) {
  body:has(.timer-bar:not([hidden])) .timer {
    bottom: var(--footer-h);
  }
  .timer-bar__stop {
    padding: 7px 10px;
  }
}

/* ============ Додавання звітів ============ */
/* Сторінка report-add.php: проекти, у них гілки, у гілці два звіти поруч.
   Картка проекту тут та сама, що в решті розділів, — поверхня з рамкою й
   тінню, — а всередині неї гілки йдуть простим списком, розділені рискою:
   згортати їх нема за чим, з формою працюють згори вниз і по всіх одразу */
.page-report-add .page__title-text {
  display: flex;
  align-items: center;
  gap: 6px;
  color: inherit;
}
.page-report-add .page__title-text:hover {
  color: var(--c-primary);
  text-decoration: none;
}
.page-report-add .page__title-text:hover .page__title-back {
  color: inherit;
}

/* Дата стоїть у шапці сторінки, на місці фільтрів решти розділів */
.report-form__date {
  display: flex;
  align-items: center;
  gap: 8px;
}
.report-form__label {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

/* «Сьогодні» / «Вчора» — перемикач із двох кнопок, той самий, що вибирає
   мову в меню профілю: варіантів мало, вони обидва на очах, і натиснутий
   видно, не відкриваючи нічого */
.report-form__days {
  display: flex;
  gap: 6px;
}
.report-form__day {
  padding: 7px 12px;
  border: 1px solid var(--c-border);
  border-radius: 8px;
  background: var(--c-surface);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--c-text-soft);
  cursor: pointer;
}
.report-form__day:hover {
  border-color: var(--c-primary);
  color: var(--c-primary);
}
.report-form__day--active {
  background: var(--c-primary-soft);
  border-color: var(--c-primary);
  color: var(--c-primary);
}

.report-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.report-form__project {
  padding: 16px 18px 18px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Назва проекту й сума по всіх його гілках. Сума притиснута до правого
   краю — там же, де стоять суми гілок під нею: три числа в стовпчик
   читаються як підсумок, а розкидані по рядках — ні */
.report-form__project-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--c-border);
  font-size: 16px;
}
.report-form__project-name {
  min-width: 0;
  overflow-wrap: anywhere;
}
.report-form__project-time {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 14px;
  color: var(--c-text-soft);
  font-variant-numeric: tabular-nums;
}

/* Гілки одна під одною, риска між ними. Останню риску не малюємо: низ
   картки й так її край */
.report-form__branch {
  padding: 14px 0 0;
}
.report-form__branch + .report-form__branch {
  margin-top: 14px;
  border-top: 1px solid var(--c-border);
}

.report-form__branch-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 14px;
}

/* Галочка з назвою одним підписом: клікають по гілці часто, і цілий
   заголовок влучає краще за квадратик. min-width нулем — щоб довга назва
   тиснулась усередині підпису, а не виносила час за край картки */
.report-form__branch-check {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  cursor: pointer;
}
.report-form__branch-box {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  accent-color: var(--c-primary);
  cursor: pointer;
}
/* Номер гілки — той самий сірий префікс перед назвою, що номер питання в
   списках: він потрібен, щоб знайти гілку в «Звітах», а не для читання */
.report-form__branch-num {
  flex-shrink: 0;
  color: var(--c-text-soft);
  font-weight: 400;
}
.report-form__branch-name {
  min-width: 0;
  overflow-wrap: anywhere;
}
.report-form__branch-time {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--c-text-soft);
  font-variant-numeric: tabular-nums;
}

/* Кошик — той самий тихий значок, що прибирає повідомлення в питанні: у
   рядку гілки він стоїть поруч із часом і до кліку на себе не тягне.
   Червоніє на ховері — прибирання все-таки, ще й із підтвердженням.
   Стоїть одразу за назвою: правий край заголовка віддано числам, і час
   гілки має ставати рівно під час проекту над ним */
.report-form__branch-del {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  cursor: pointer;
}
.report-form__branch-del svg {
  width: 14px;
  height: 14px;
}
.report-form__branch-del:hover {
  background: var(--c-bg);
  color: var(--c-red);
}

/* Гілка, з якої галочку зняли: блоків не видно, лишається сам заголовок.
   Час у ньому не зникає, а перекреслюється — так з рядка видно не тільки
   те, що гілка не піде в звіти, а й скільки годин при цьому лишається
   осторонь. У підсумках проекту й форми їх уже немає */
.report-form__branch--off .report-form__pair {
  display: none;
}
.report-form__branch--off .report-form__branch-name {
  color: var(--c-text-soft);
}
.report-form__branch--off .report-form__branch-time {
  text-decoration: line-through;
  opacity: 0.6;
}

/* Гілка, у яку звіт не додати: закрита або не в хвилинах. Не згорнута —
   час на ній має бути видно, щоб його не забули, — але червонувата, без
   галочки й з заблокованими полями. Поля відступають від країв тла на ту
   саму ширину, на яку тло виходить за межі гілки */
.report-form__branch--locked {
  margin-left: -10px;
  margin-right: -10px;
  padding: 14px 10px 10px;
  border-radius: 10px;
  background: var(--c-red-soft);
}
.report-form__branch--locked + .report-form__branch,
.report-form__branch + .report-form__branch--locked {
  border-top-color: transparent;
}
.report-form__branch--locked .report-form__branch-check,
.report-form__branch--locked .report-form__branch-box {
  cursor: default;
}
.report-form__branch--locked .report-form__branch-time {
  text-decoration: line-through;
}
.report-form__branch--locked .report-card {
  background: var(--c-surface);
}
.report-form__branch-lock {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  color: var(--c-red);
}
.report-form__branch-lock svg {
  width: 14px;
  height: 14px;
}

/* Два звіти гілки поруч: доробки ліворуч, помилки праворуч. minmax(0, 1fr)
   замість 1fr — щоб довгий рядок у коментарі не розсував свою половину */
.report-form__pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 12px;
}

/* Сам звіт: заголовок із часом, під ним коментар. Тло тихіше за картку
   проекту — так пара блоків читається як вкладена в гілку, а не як ще дві
   картки поруч */
.report-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  background: var(--c-bg);
  border: 1px solid var(--c-border);
  border-radius: 10px;
}

/* Порожній звіт — той, якому таймер нічого не приніс. Рамка пунктиром: блок
   лишається на місці (дописати в нього хочуть саме тут), але зайвого разу
   на себе не тягне */
.report-card--empty {
  border-style: dashed;
}

.report-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.report-card__kind {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}
.report-card__kind svg {
  width: 13px;
  height: 13px;
}
/* Жучок і підпис при ньому — тим самим темно-червоним, що маркер типу в
   списках питань: тип звіту й тип питання тут одне й те саме */
.report-card--bug .report-card__kind {
  color: var(--c-red-dark);
}

/* Час у рядку звіту: години й хвилини окремими полями, двокрапка між ними
   лишається на очах, але вже не набирається. Ширина поля — рівно під дві
   цифри (більше в нього й не введеться, maxlength="2"), тож зайвого місця
   в ньому немає й воно не вдає поле, у яке щось дописують.
   Вирівняні праворуч — цифри стають до двокрапки, як у самому «1:20», і
   однозначні години не роз'їжджаються з двозначними */
.report-time {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.report-time__part {
  width: 34px;
  padding: 7px 6px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.report-time__sep {
  color: var(--c-text-soft);
}

/* Час звіту — сума рядків, і стоїть він текстом на тому самому місці, де в
   гілці й у проекті стоять їхні суми: правий край заголовка */
.report-card__time {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--c-text-soft);
  font-variant-numeric: tabular-nums;
}

/* Рядки звіту одним стовпчиком. Проміжок той самий, що між частинами
   картки: рядки — це і є її вміст, і виділяти їх із неї нема за чим */
.report-card__lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Рядок: те, про що він, ліворуч на всю ширину, час і хрестик праворуч.
   minmax(0, 1fr) замість 1fr — щоб довга назва питання не виносила час за
   край картки.
   Третя колонка стала й порожня в дописаних рядках: хрестик стоїть лише в
   тих, що прийшли з таймера, а кожен рядок — окрема сітка, і без цієї
   колонки поля часу в сусідніх рядках розійшлися б на ширину кнопки.
   Верхнє вирівнювання: у дописаного рядка ліворуч текстареа, і час має
   стояти при першому її рядку, а не посередині розтягнутої */
.report-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 26px;
  align-items: start;
  gap: 8px;
}

/* Хрестик рядка — той самий тихий значок, що кошик у гілці, тільки менший:
   стоїть він у кожному рядку з питанням, і повторений десяток разів мав би
   бути ще тихішим за нього. Червоніє на ховері — прибирання все-таки */
.report-line__del {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 34px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--c-text-soft);
  opacity: 0.7;
  cursor: pointer;
}
.report-line__del svg {
  width: 11px;
  height: 11px;
}
.report-line__del:hover {
  background: var(--c-surface);
  color: var(--c-red);
  opacity: 1;
}

/* Текст рядка. Висоту тягне під набране report-add.js — рядок звіту буває
   і в слово, і в абзац; тут лишається стеля, після якої поле перестає рости
   й прокручується всередині: інакше один довгий рядок відсунув би решту
   форми за екран. Ручний розтяг за куток при цьому не забираємо — він же
   стоїть і у формі відповіді; убік не тягнеться нікуди, своя колонка й так
   уся його */
.report-line__note {
  width: 100%;
  max-height: 220px;
  resize: vertical;
  font-family: inherit;
  line-height: 1.5;
}

/* «Додати» — та сама тиха текстова кнопка в колір посилання, що додає
   доступ у проекті. Від'ємний відступ з'їдає її власний паддінг, і плюсик
   стає під ліву межу рядків над ним */
.report-card__add {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: -8px;
  padding: 4px 8px;
  border: none;
  border-radius: 6px;
  background: none;
  font-size: 13px;
  font-weight: 600;
  color: var(--c-primary);
  cursor: pointer;
}
.report-card__add:hover {
  background: var(--c-primary-soft);
}
.report-card__add svg {
  width: 14px;
  height: 14px;
}

/* Рядок кнопок прилипає до низу вікна: форма довша за екран, і «Додати» не
   має чекати, поки її догортають. Поверхня в нього та сама, що в картки
   проекту, — інакше на прилиплому рядку просвічував би текст під ним */
.report-form__foot {
  position: sticky;
  bottom: 16px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.report-form__total {
  margin-right: auto;
  font-size: 13px;
  color: var(--c-text-soft);
}
.report-form__total-time {
  margin-left: 8px;
  font-size: 16px;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
}
/* Чому форму не прийняли — одним рядком над кнопкою, як у «Внести оплату» */
.report-form__error {
  margin: 0;
  padding: 0 18px;
  color: var(--c-red);
  font-size: 13px;
  line-height: 1.4;
}
/* --- мобільна версія «Додавання звітів» --- */
@media (max-width: 1100px) {
  /* Картка проекту лягає на всю ширину екрана — те саме роблять картки
     проектів у решті розділів. Кутів, бічної рамки й тіні при цьому немає:
     край картки й край екрана — те саме, а заокруглені кути на самій межі
     читалися б як обрізані. Проекти одне від одного відбиває сірий проміжок
     між ними */
  .report-form__project {
    border: none;
    border-radius: 0;
    box-shadow: none;
  }

  /* Тихе тло звіту тут теж зайве: картка проекту вже лежить не на білому
     полі з полями з боків, а на весь екран, і сіра плашка всередині неї
     виходила другим тлом поверх сірого тла сторінки. Поки звіти стоять
     поруч, рамка їх іще ділить; коли стануть у стовпчик — піде й вона */
  .report-card {
    background: none;
  }
}

@media (max-width: 760px) {
  /* Двом звітам у рядок не стати: коментар у півширини мобільного екрана
     став би стовпчиком з одного слова. Ідуть один під одним */
  .report-form__pair {
    grid-template-columns: 1fr;
    gap: 18px;
  }

  /* У стовпчику рамка вже нічого не ділить — сусід у звіту тільки згори й
     знизу, а там його межу видно й так, за проміжком. Лишившись, вона стала б
     четвертою вкладеністю поспіль: екран, картка проекту, гілка, звіт.
     Разом із рамкою йдуть і поля: без неї вони відсували рядки звіту від
     лівого краю ні за чим, і заголовок «Доробки» не ставав під назву гілки
     над ним. Пунктир порожнього звіту тут теж зникає — його показувала та
     сама рамка; порожній звіт видно за самими полями, вони порожні */
  .report-card {
    padding: 0;
    border: none;
  }
  /* а в гілці, куди звіт не додати, біла плашка без полів притиснулась би до
     тексту — картка лягає просто на червонувате тло гілки */
  .report-form__branch--locked .report-card {
    background: none;
  }
}

@media (max-width: 700px) {
  /* Дата йде під заголовок окремим рядком — так само, як фільтри решти
     розділів на вузькому екрані */
  .page-report-add .page__head {
    align-items: flex-start;
  }
  .report-form__project {
    padding: 14px;
  }
  /* На вузькому екрані рядок не липне, а стоїть: притиснутий до низу вікна
     на всю його ширину, він просто перекриває підвал — гортати під ним
     нема чого. Тому ні полів з боків, ні кутів, ні бічної рамки: рядок і
     край екрана — те саме. Порядок той самий, що на десктопі: підсумок
     зліва, кнопка справа */
  .report-form__foot {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 12px 14px;
    border: none;
    border-top: 1px solid var(--c-border);
    border-radius: 0;
  }
  /* Відступ від останньої картки до підвала: на мобільному .page знизу не
     має нічого, а тут під підвалом ще й стоїть рядок кнопки — впритул до
     картки він читався б як її частина */
  .page-report-add .page {
    padding-bottom: 24px;
  }
}


/* ============ Внесення оплати ============ */
/* Сторінка payment-add.php: ті самі проекти й гілки, що на «Фінансах», але
   форма. Спільного з «Фінансами» тут майже все — картка проекту, таблиця,
   сітка колонок (див. секцію .branches), — тож нижче лишається саме те, чого
   на «Фінансах» немає: той, кому платимо, у шапці, поля сум у рядках і
   рядок переказу внизу */
.page-payment-add .page__title-text {
  display: flex;
  align-items: center;
  gap: 6px;
  color: inherit;
}
.page-payment-add .page__title-text:hover {
  color: var(--c-primary);
  text-decoration: none;
}
.page-payment-add .page__title-text:hover .page__title-back {
  color: inherit;
}

/* Той, кому платимо, — на місці фільтрів решти розділів. Пара «аватарка —
   ім'я» тут та сама, що в колонці гілок, а сторона стоїть тихою міткою:
   вона не назва людини, а те, ким вона в цих гілках рахується */
.pay-who {
  display: flex;
  align-items: center;
  gap: 10px;
}
.pay-who__side {
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--c-bg);
  font-size: 12px;
  font-weight: 600;
  color: var(--c-text-soft);
}

.pay-form {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* Проекти тут не згортаються, тож каретки в шапці немає, і правий край
   тримає сама сума. Кінчатися вона має там само, де «Валюта» під нею, —
   а за «Валютою» стоїть іще колонка полів: 132 її ширини мінус 12 правого
   паддінга шапки */
@media (min-width: 1101px) {
  .page-payment-add .project__client {
    width: auto;
    flex: 1;
  }
  .page-payment-add .project__due {
    margin-right: 120px;
    padding-right: 12px;
  }
}

/* Поле суми в рядку гілки. Валюта стоїть при ньому, а не тільки в сусідній
   колонці: у полі саме число, і підпис до нього має бути в тому ж рядку,
   куди дивишся, коли набираєш.
   Число в полі — по правому краю, як і всі гроші в таблиці: так суми в
   стовпчику читаються одна під одною, а не розповзаються від лівого краю
   полів */
.pay-sum {
  display: flex;
  align-items: center;
  gap: 6px;
}
.pay-sum__input {
  width: 100%;
  min-width: 0;
  padding: 5px 8px;
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.pay-sum__cur {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--c-text-soft);
}

/* Чому форму не прийняли — одним рядком над рядком переказу: суми, дата й
   коментар — один переказ, і відмова йому теж одна. Колір і кегль ті самі,
   що в помилок входу (.auth__error) */
.pay-form__error {
  margin: 10px 0 0;
  padding: 0 18px;
  color: var(--c-red);
  font-size: 13px;
  line-height: 1.4;
}

/* Рядок самого переказу — на місці підсумку «Фінансів». Прилипає до низу
   вікна, як рядок кнопок у «Додаванні звітів»: форма буває довшою за
   екран, і кнопка не має чекати, поки її догортають */
.pay-form__foot {
  position: sticky;
  bottom: 16px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 2px;
  padding: 14px 18px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
/* Коментар забирає всю вільну ширину рядка: дата й підсумок міряються
   своїм вмістом, а в коментар пишуть речення */
.pay-form__note {
  flex: 1;
  min-width: 0;
}
.pay-form__total {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-shrink: 0;
  font-size: 13px;
  color: var(--c-text-soft);
}
/* Валют у підсумку буває кілька — курсу тут немає, і скласти їх нема як.
   Ідуть вони одна за одною в рядок, розділені тонким плюсом: так само
   стоять суми в шапці проекту й у підсумку «Фінансів» */
.pay-form__sums {
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.pay-form__sum {
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
}
.pay-form__sum + .pay-form__sum::before {
  content: "+";
  margin-right: 6px;
  font-weight: 400;
  color: var(--c-text-soft);
}
/* Порожня форма — нуль замість сум: у рядку має лишатися число, інакше
   підсумок читався б як зламаний */
.pay-form__sums:empty::after {
  content: "0";
  font-size: 16px;
  font-weight: 700;
  color: var(--c-text-soft);
}

/* --- мобільна версія «Внесення оплати» --- */
@media (max-width: 1100px) {
  /* Таблиця розкладається в картки (див. секцію .branches), і поле суми стає
     останнім рядком картки — під «До оплати», як і в таблиці. Підпис
     колонки приходить з data-label тим самим правилом, що й у решти */
  .page-payment-add .branches td.branches__sum {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr);
    align-items: center;
    gap: 0 10px;
    margin-top: 6px;
    padding: 6px 0 0;
    border-top: 1px solid var(--c-border);
  }
  .page-payment-add .branches td.branches__sum::before {
    content: attr(data-label);
    font-size: 12px;
    font-weight: 500;
    color: var(--c-text-soft);
  }
}

@media (max-width: 700px) {
  /* Той, кому платимо, іде під заголовок окремим рядком — так само, як
     фільтри решти розділів і дата в «Додаванні звітів» */
  .page-payment-add .page__head {
    align-items: flex-start;
  }
  /* Дата з коментарем у рядок, підсумок і кнопка під ними: учотирьох вони
     в рядок мобільного екрана не стають, а кнопку тиснути не можна */
  .pay-form__foot {
    flex-wrap: wrap;
    padding: 12px;
  }
  .pay-form__date {
    flex: 1;
    min-width: 0;
  }
  .pay-form__note {
    flex-basis: 100%;
  }
  .pay-form__total {
    margin-right: auto;
  }
}

/* ============ Клієнти ============ */
/* Розділу немає в прототипі: у public/demo під нього немає ні шаблона, ні
   стилів, і прототип такої сторінки не знає. Тому все, з чого він зібраний, —
   чуже й уже готове: таблиця .branches з її колонками, плитка .client,
   підсумок .totals. Своїм тут лишається рівно те, що нижче: обгортка списку
   й сітка цих п'яти колонок.

   Це єдиний список CRM без карток. Скрізь інде рядок — гілка, а картка над
   ним — проект, до якого вона належить; тут рядок — клієнт, і його проекти вже
   згорнуті в цифри рядка. Розгортати нічого, тож і спільної шапки колонок над
   картками (.branches-head) немає — шапка стоїть у самій таблиці */
.clients {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 14px;
  /* горизонтальний скрол на вузькому десктопі — як у .project__branches.
     Він же обрізає кути під радіус картки, інакше сірий фон шапки колонок
     заквадратив би два верхні */
  overflow-x: auto;
}
/* останній рядок межі не має: під нею одразу рамка картки, і лінія читалась
   би подвійною */
.clients .branches tbody tr:last-child td {
  border-bottom: none;
}

/* Порожній список — та сама смуга, що в звітах (.reports__empty) і в оплатах
   проекту: фільтр, який нікого не знайшов, мусить це сказати, інакше сама
   лише шапка сторінки читалась як недовантажена */
.clients__empty {
  padding: 24px;
  text-align: center;
  color: var(--c-text-soft);
}

/* У колонці питань тут стоїть число проектів, а не кружечки, — тож по
   правому краю, як решта чисел рядка. Так само активні проекти й дата
   реєстрації повної статистики */
.page-clients .branches :is(
  th.branches__col-issues, td.branches__issues,
  th.branches__col-active, td.branches__active,
  th.branches__col-reg, td.branches__reg
) {
  text-align: right;
}
.page-clients .branches td.branches__reg {
  white-space: nowrap;
}

/* Гроші клієнта — рядок на валюту, один під одним і без плюса між ними.
   Плюс стоїть там, де сума одна й читається впоперек широкого рядка (підсумок
   унизу, «Внести оплату»); тут це вузька колонка таблиці, яку читають згори
   вниз, і два числа в один рядок у неї просто не влазять */
.clients__money {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.clients__sum {
  white-space: nowrap;
}

/* Ім'я клієнта веде у «Фінанси», уже відфільтровані по ньому. Лінка тут не
   синя: у рядку списку в неї та сама вага, що в звичайного імені поруч, —
   підкреслення на наведенні й колір посилання говорять достатньо */
.client__name--link {
  color: inherit;
  text-decoration: none;
}
.client__name--link:hover,
.client__name--link:focus-visible {
  color: var(--c-primary);
  text-decoration: underline;
}

/* Сітка колонок: ім'я гумове, решта тримає свої пікселі. Таблиць дві.
   Коротка: 564 = клієнт 220 + активні 120 + винен 120 + оновлено 104.
   Повна: 884 = клієнт 220 + реєстрація 110 + проекти 90 + активні 120
   + оплачено 120 + винен 120 + оновлено 104.
   Ширші за «Фінанси» грошові колонки — там у клітинці сума однієї гілки, тут
   увесь рахунок клієнта, та ще й із валютою при числі («16 500 UAH»), бо
   колонки валюти в цій таблиці немає */
@media (min-width: 1101px) {
  body.page-clients .branches {
    min-width: 564px;
  }
  body.page-clients .clients--full .branches {
    min-width: 884px;
  }
  body.page-clients .branches__col-name {
    width: auto;
    min-width: 220px;
  }
  body.page-clients .branches__col-reg {
    width: 110px;
  }
  body.page-clients .branches__col-issues {
    width: 90px;
    min-width: 0;
  }
  body.page-clients .branches__col-active,
  body.page-clients .branches__col-paid,
  body.page-clients .branches__col-pay {
    width: 120px;
  }
}

/* --- мобільна версія «Клієнтів» --- */
@media (max-width: 1100px) {
  /* у картках рамка зайва — рядки й так відділені лініями, а вона додала б
     до них ще й межу списку */
  .clients {
    border: none;
    border-radius: 0;
    box-shadow: none;
    overflow-x: visible;
  }

  /* Нижні клітинки картки — підпис ліворуч, значення праворуч, кожна своїм
     рядком. Скільки їх, залежить від статистики (дві в короткій, п'ять у
     повній), тож номера рядка сітки жодна не має: grid-row: auto кладе їх
     під ім'я в порядку розмітки. Підпис грошових приходить із data-label
     спільним правилом .branches td.branches__paid::before, решті дописуємо
     його тут: у колонці питань підпису не буває, там кружечки говорять самі
     за себе */
  .page-clients .branches :is(
    td.branches__reg,
    td.branches__issues,
    td.branches__active,
    td.branches__paid,
    td.branches__pay
  ) {
    grid-column: 1 / -1;
    grid-row: auto;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 6px;
    padding-bottom: 0;
    border-bottom: none;
  }
  .page-clients .branches :is(
    td.branches__reg,
    td.branches__issues,
    td.branches__active
  )::before {
    content: attr(data-label);
    font-size: 12px;
    font-weight: 500;
    color: var(--c-text-soft);
  }

  /* Два селекти стоять у рядку самі, тож кнопки, що їх згортає, у розмітці
     немає — а поля показуємо одразу, без стану --open, як у «Команді». Вони
     ділять рядок навпіл, а не йдуть стовпчиком на всю ширину: обидва
     короткі, і стовпчик забрав би пів екрана над списком */
  .page-clients .page__filters {
    display: flex;
    order: 0;
    flex-direction: row;
  }
  .page-clients .page__filters select.input {
    flex: 1;
    min-width: 0;
    width: auto;
  }
}
