/* ═══════════════════════════════════════════════════════════════════════════
   TABLE (#30) — реєстр/таблиця даних. Найбільший композит UIKit.
   Перевикористовує: checkbox (вибір + select-all/indeterminate), dropdown
   (рядкові дії), badge (статуси), spinner (індикатор у toolbar), skeleton
   (рядки завантаження), empty-state (порожньо/помилка), pagination (смуга).

   Структура:
     .table-wrap[data-table]            — обгортка + JS-корінь + контекст скролу
       > .table-toolbar                 — (опц.) панель масових дій (показ при виборі)
       > table.table                    — семантична таблиця
           > caption.table__caption     — підпис (часто .uris-visually-hidden)
           > thead > tr > th[scope=col]  — шапка; сортовані несуть aria-sort
           > tbody > tr
                > td.table__cell--select   — чекбокс рядка
                > th[scope=row]            — назва (рядковий заголовок)
                > td …                     — дані; числові — .table__cell--numeric
                > td.table__cell--actions  — dropdown дій
       > .pagination-bar                — (опц.) пагінація під таблицею

   Варіанти/модифікатори:
     .table--compact          — щільніші рядки
     .table--wrap-header      — перенесення тексту в шапці (вузькі колонки з довгими назвами)
     .table-wrap--scroll      — горизонтальний скрол (вузькі екрани)
     .table-wrap--sticky      — обмежена висота + липка шапка (довгі списки без пагінації)

   Стани таблиці (різна розмітка tbody): дані · завантаження (skeleton) ·
   порожньо (empty) · помилка (empty-danger). Стани рядка: default · hover ·
   selected (через :has — без JS).

   Стилі базових клітинок задаються селекторами елементів у межах .table
   (а не клас на кожній клітинці) — таблиці мають десятки клітинок, клас на
   кожній був би шумом; модифікатори-класи лишаються для винятків (--numeric,
   --select, --actions, --sortable).

   A11y: семантичний <table>; <caption>; scope на th; aria-sort на сортованих
   колонках; чекбокси й кнопки-сортування — нативні, з клавіатури.
   JS лише доповнює (select-all/indeterminate, події) — без JS статика робоча.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Обгортка ───────────────────────────────────────────────────────────────
   Дефолт: overflow visible → thead липне при скролі СТОРІНКИ, а dropdown-меню
   рядкових дій ніколи не обрізається. Контейнери-скрол — лише opt-in нижче. */
.table-wrap {
  inline-size: 100%;
  font-family: var(--uris-font-family-body);
  -webkit-font-smoothing: antialiased;
  color: var(--uris-color-semantic-text);
}

/* Горизонтальний скрол для широкої таблиці на вузькому екрані (opt-in).
   У цьому режимі page-scroll sticky не вмикається (контейнер стає скрол-портом),
   а меню дій у крайніх рядках може обрізатись — тож вмикати свідомо. */
.table-wrap--scroll {
  overflow-x: auto;
}
/* У скрол-контейнері сторінковий sticky шапки не працює (липнув би до
   скролпорту самої обгортки зі зсувом top — «плавав» би посеред таблиці),
   тому в цьому режимі шапка static; прилипання, де потрібно, емулює
   споживач transform-ом на thead (див. dashboard-core.js updateStuck) —
   relative+z-index тримає зсунуту шапку НАД рядками, що проходять під нею. */
.table-wrap--scroll .table thead th { position: static; }
.table-wrap--scroll thead {
  position: relative;
  z-index: 5;
}

/* Обмежена висота тіла + липка шапка для довгих списків без пагінації (opt-in).
   Меню рядкових дій біля країв контейнера може обрізатись — для великих обсягів
   надавати перевагу пагінації (нижче самої таблиці), а не внутрішньому скролу. */
.table-wrap--sticky {
  overflow: auto;
  max-block-size: var(--uris-component-table-sticky-max-block-size);
}

/* «Картка»-обрамлення (opt-in). Свідомо БЕЗ overflow:clip — інакше обрізалось би
   dropdown-меню рядкових дій; натомість округлюємо верхні кути шапки, щоб сіра
   заливка не виступала за радіус (нижні кути клітинок білі = тло сторінки).
   Внутрішній радіус = зовнішній − 1px рамки: концентричні кути різного
   діаметра мають різний радіус, інакше на стику лишається білий уступ
   (рецепт відпрацьовано в Dashboard «Державна атестація», 2026-07). */
.table-wrap--bordered {
  border: 1px solid var(--uris-color-semantic-border);
  border-radius: var(--uris-radius-lg);
}
.table-wrap--bordered .table thead tr:first-child th:first-child {
  border-start-start-radius: calc(var(--uris-radius-lg) - 1px);
}
.table-wrap--bordered .table thead tr:first-child th:last-child {
  border-start-end-radius: calc(var(--uris-radius-lg) - 1px);
}
/* `<table>` під шапкою має власний (квадратний) білий фон — навіть із
   правильним радіусом на `<th>` у вершечку заокруглення лишався «пікселик»
   квадратного кута table (перевірено elementFromPoint). Заокруглюємо й
   table — комірка і таблиця стають однією концентричною парою з рамкою. */
.table-wrap--bordered .table {
  border-start-start-radius: calc(var(--uris-radius-lg) - 1px);
  border-start-end-radius: calc(var(--uris-radius-lg) - 1px);
}
/* Прилипла шапка (сторінковий скрол, thead th position:sticky): заокруглені
   кутові <th> лишають прозору «виїмку» радіуса, крізь яку видно рядки, що
   скролять позаду. Поки шапка відірвана від верху картки (JS ставить
   data-stuck на обгортку: registry-toolbar.js / dashboard-core.js), кути
   тимчасово прямі; радіус повертається разом із поверненням шапки на місце. */
.table-wrap--bordered[data-stuck] .table thead tr:first-child th:first-child {
  border-start-start-radius: 0;
}
.table-wrap--bordered[data-stuck] .table thead tr:first-child th:last-child {
  border-start-end-radius: 0;
}

/* ── Таблиця ─────────────────────────────────────────────────────────────────
   separate (не collapse): інакше межі липкої шапки «від'їжджають» при скролі —
   при border-collapse межа належить ребру таблиці, а не клітинці. */
.table {
  inline-size: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--uris-text-sm-size);
  line-height: var(--uris-text-sm-line);
  color: var(--uris-color-semantic-text);
  background: var(--uris-color-semantic-surface);
}

/* ── Підпис ─────────────────────────────────────────────────────────────────── */
.table__caption {
  caption-side: top;
  text-align: start;
  padding-block-end: var(--uris-spacing-3);
  font-size: var(--uris-text-sm-size);
  line-height: var(--uris-text-sm-line);
  color: var(--uris-color-semantic-text-muted);
}

/* ── Спільна геометрія клітинок ──────────────────────────────────────────────
   :where() → нульова специфічність базового правила, щоб клас-модифікатори
   (--numeric/--actions/--state-cell) перемагали за порядком у файлі, а не
   програвали кваліфікованому елементом `.table td`. */
.table :where(th, td) {
  padding: var(--uris-spacing-3) var(--uris-spacing-4);
  text-align: start;
  vertical-align: middle;
  border-block-end: 1px solid var(--uris-color-semantic-border);
}

/* ── Шапка ──────────────────────────────────────────────────────────────────── */
.table thead th {
  position: sticky;
  top: 0;
  z-index: 2;                       /* нижче за dropdown-меню (z=100) */
  background: var(--uris-color-semantic-surface-muted);
  color: var(--uris-color-semantic-secondary);   /* gray-700: AA на gray-100 */
  font-weight: var(--uris-font-weight-medium);
  font-size: var(--uris-text-xs-size);
  line-height: var(--uris-text-xs-line);
  white-space: nowrap;
}

/* ── Тіло: рядок ────────────────────────────────────────────────────────────── */
.table tbody tr {
  background: var(--uris-color-semantic-surface);
  transition: background-color var(--uris-duration-fast) var(--uris-ease-default);
}

/* hover (стан рядка) */
.table tbody tr:hover {
  background: var(--uris-color-semantic-surface-muted);
}

/* selected (стан рядка) — чистий CSS через :has; перебиває hover за специфічністю.
   Працює без JS: візуальний стан слідує безпосередньо за чекбоксом рядка. */
.table tbody tr:has(.table__check .checkbox__input:checked) {
  background: var(--uris-color-semantic-info);
}

/* Останній рядок без нижньої межі — її несе сама таблиця-контейнер за потреби */
.table tbody tr:last-child th,
.table tbody tr:last-child td {
  border-block-end: 0;
}

/* Рядковий заголовок (назва публікації) — трохи акцентований */
.table tbody th {
  font-weight: var(--uris-font-weight-medium);
  color: var(--uris-color-semantic-text);
}

/* ── Колонка вибору ─────────────────────────────────────────────────────────── */
.table__cell--select {
  inline-size: 1%;                  /* стиснути до вмісту */
  white-space: nowrap;
  padding-inline-end: var(--uris-spacing-2);
}

/* Чекбокс у клітинці — лише бокс, без тексту; центруємо в рядку */
.table__check {
  gap: 0;
}
.table__check .checkbox__box {
  margin-block-start: 0;
}
.table__check .checkbox__input {
  inset-block-start: 0;
}

/* ── Колонка дій ────────────────────────────────────────────────────────────── */
.table__cell--actions {
  inline-size: 1%;
  white-space: nowrap;
  text-align: end;
  padding-block: var(--uris-spacing-1);
}

/* ── Числова колонка ────────────────────────────────────────────────────────── */
.table__cell--numeric {
  text-align: end;
  font-family: var(--uris-font-family-mono); /* JetBrains Mono — рівні цифрові колонки */
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ── Колонка назви — дозволяємо перенос, обмежуємо ширину ────────────────────── */
.table__cell--title {
  min-inline-size: 220px;
  max-inline-size: 380px;
  white-space: normal;
}

/* ── Кнопка сортування ──────────────────────────────────────────────────────── */
.table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--uris-spacing-1);
  inline-size: 100%;
  padding: var(--uris-spacing-1) var(--uris-spacing-2);
  background: none;
  border: 0;
  border-radius: var(--uris-radius-sm);
  font: inherit;            /* успадковує xs/medium шапки */
  color: inherit;           /* secondary */
  text-align: inherit;
  cursor: pointer;
  transition: background-color var(--uris-duration-fast) var(--uris-ease-default),
              color var(--uris-duration-fast) var(--uris-ease-default);
}

.table__sort:hover {
  background: var(--uris-color-semantic-surface-hover);
}

.table__sort:focus-visible {
  outline: 2px solid var(--uris-color-semantic-focus-ring);
  outline-offset: -2px;     /* inset: не обрізається контейнером скролу */
}

/* Числова колонка: мітка+іконка тиснуться до правого краю */
.table__cell--numeric .table__sort {
  justify-content: flex-end;
}

/* Іконка-сортування: дві стрілки; активний напрям — повна непрозорість.
   16px — консистентно з .dropdown__chevron. */
.table__sort-icon {
  flex-shrink: 0;
  inline-size: var(--uris-component-icon-size-sm);
  block-size: var(--uris-component-icon-size-sm);
  color: var(--uris-color-semantic-text-muted);
}
.table__sort-icon .table__sort-up,
.table__sort-icon .table__sort-down {
  opacity: 0.4;
  transition: opacity var(--uris-duration-fast) var(--uris-ease-default);
}

/* Активна сортована колонка: темніша мітка + підсвічений напрям стрілки */
.table thead th[aria-sort="ascending"] .table__sort,
.table thead th[aria-sort="descending"] .table__sort {
  color: var(--uris-color-semantic-text);
}
.table thead th[aria-sort="ascending"]  .table__sort-icon .table__sort-up   { opacity: 1; }
.table thead th[aria-sort="descending"] .table__sort-icon .table__sort-down { opacity: 1; }
.table thead th[aria-sort="ascending"]  .table__sort-icon,
.table thead th[aria-sort="descending"] .table__sort-icon { color: var(--uris-color-semantic-text); }

/* ── Стан-клітинка (порожньо / помилка / завантаження-повідомлення) ──────────────
   Один td з colspan на всю ширину; padding скидаємо — його дає .empty всередині. */
.table__state-cell {
  padding: 0;
  border-block-end: 0;
}

/* Рядок-скелетон не реагує на hover (він не інтерактивний) */
.table tbody tr.table__row--skeleton:hover {
  background: var(--uris-color-semantic-surface);
}
.table tbody tr.table__row--skeleton .skel {
  /* трохи нижчий за рядок тексту, аби клітинка зберігала висоту */
  block-size: var(--uris-component-skeleton-line-sm);
}

/* ── Щільний варіант ────────────────────────────────────────────────────────── */
.table--compact th,
.table--compact td {
  padding: var(--uris-spacing-2) var(--uris-spacing-3);
}

/* ── Перенесення тексту в шапці (opt-in) ───────────────────────────────────────
   Довгі назви колонок (напр. «Класифікаційна оцінка») інакше форсують ширину
   колонки під один рядок nowrap. Знімаємо nowrap лише для шапки — дані в
   .table__cell--numeric лишаються nowrap (числа не переносяться). */
.table--wrap-header thead th {
  white-space: normal;
  vertical-align: bottom;
}

/* ═══════════════════════════════════════════════════════════════════════════
   TOOLBAR масових дій — ПЕРЕНЕСЕНО до components/table-toolbar/ (#31).
   `.table-toolbar` тепер належить компоненту Table-toolbar (повна панель над
   таблицею), а bulk-бар став її станом `--selecting` / `.table-toolbar__selection`.
   Легасі-форма `.table-toolbar.is-active` (in-wrap bulk-бар із цього демо) лишається
   робочою — її стилі тепер у table-toolbar.css (зворотна сумісність через :has-guard).
   Залежність: підключати table-toolbar.css разом із table.css.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Reduced motion ─────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .table tbody tr,
  .table__sort,
  .table__sort-icon .table__sort-up,
  .table__sort-icon .table__sort-down {
    transition: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ФІЛЬТРИ В КОЛОНКАХ (#39) — кнопка-воронка в th + popover.
   Popover — НЕ APG Menu (усередині чекбокси/інпут, не menuitem):
   звичайний спливний контейнер із aria-expanded на тригері.
   Вміст постачає споживач (сервер-рендер); JS лише відкриття/закриття,
   збирання значень і подія table:filter — дані фільтрує споживач
   (та сама модель, що table:sort / table-toolbar).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Шапка з фільтром: тримає позиціювання popover */
.table thead th:has(.table__filter) {
  position: sticky; /* успадковане правило шапки; для popover — контекст */
}

.table__filter-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* Кнопка-воронка — мова .table__sort */
.table__filter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--uris-spacing-1);
  background: none;
  border: 0;
  border-radius: var(--uris-radius-sm);
  color: var(--uris-color-semantic-text-muted);
  cursor: pointer;
  transition: background-color var(--uris-duration-fast) var(--uris-ease-default),
              color var(--uris-duration-fast) var(--uris-ease-default);
}

.table__filter:hover {
  background: var(--uris-color-semantic-surface-hover);
  color: var(--uris-color-semantic-text);
}

.table__filter:focus-visible {
  outline: 2px solid var(--uris-color-semantic-focus-ring);
  outline-offset: -2px;
}

.table__filter-icon {
  inline-size: var(--uris-component-icon-size-sm);
  block-size: var(--uris-component-icon-size-sm);
}

/* Активний фільтр колонки: воронка стає акцентною + крапка-індикатор */
.table__filter.is-filtered {
  color: var(--uris-color-semantic-accent);
}

.table__filter.is-filtered::after {
  content: '';
  position: absolute;
  inset-block-start: 2px;
  inset-inline-end: 2px;
  inline-size: var(--uris-component-badge-dot-size);
  block-size: var(--uris-component-badge-dot-size);
  border-radius: var(--uris-radius-full);
  background: var(--uris-color-semantic-accent);
}

/* ── Popover ────────────────────────────────────────────────────────────── */
.table__filter-pop {
  position: absolute;
  top: calc(100% + var(--uris-spacing-2));
  inset-inline-start: 0;
  z-index: var(--uris-component-dropdown-z-index);
  min-inline-size: 220px;
  padding: var(--uris-spacing-4);
  background: var(--uris-color-semantic-surface);
  border: 1px solid var(--uris-color-semantic-border);
  border-radius: var(--uris-radius-md);
  box-shadow: var(--uris-shadow-lg);
  /* Скидання типографіки шапки (xs/medium/uppercase контексту th) */
  font-size: var(--uris-text-sm-size);
  line-height: var(--uris-text-sm-line);
  font-weight: var(--uris-font-weight-regular);
  color: var(--uris-color-semantic-text);
  white-space: normal;
  text-align: start;
}

/* Крайня права колонка: розкривати вліво, щоб не обрізатись */
.table__filter-pop--end {
  inset-inline-start: auto;
  inset-inline-end: 0;
}

/* Стос опцій-чекбоксів */
.table__filter-options {
  display: flex;
  flex-direction: column;
  gap: var(--uris-spacing-3);
  max-block-size: 240px;
  overflow-y: auto;
  margin-block-end: var(--uris-spacing-4);
}

/* Футер: скинути / застосувати */
.table__filter-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--uris-spacing-2);
}

/* ═══════════════════════════════════════════════════════════════════════════
   ГРУПУВАННЯ РЯДКІВ (#54) — аналітичні таблиці дашборда атестації:
   «ЗВО/НУ → кілька наукових напрямів», «ГРБК → ЗВО → показники».

   Розмітка — семантичний rowspan (a11y безкоштовно):
     <tr class="table__row--group-start">
       <th scope="rowgroup" rowspan="3" class="table__cell--group">КНУ ім. Шевченка</th>
       <td>Природничо-математичний</td>…
     </tr>
     <tr><td>Суспільний</td>…</tr>          ← без групової комірки
     <tr><td>Гуманітарно-мистецький</td>…</tr>

   Правила:
   - межа МІЖ групами (--group-start) виразніша за межу між рядками групи;
   - групова комірка вирівняна по верху;
   - hover підсвічує РЯДОК (не групу) — задокументоване обмеження;
   - selected через :has() підсвічує рядок; групова комірка належить першому
     рядку групи — при виборі інших рядків вона не підсвічується (README).
   Коли групувати: ≤ ~6 рядків на групу; більші набори — окремі таблиці.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Групова комірка: тягнеться rowspan'ом, значення по верху */
.table .table__cell--group {
  vertical-align: top;
  font-weight: var(--uris-font-weight-medium);
  background: var(--uris-color-semantic-surface); /* не успадковує hover-фон рядка */
}

/* Межа між групами — виразніша (surface-active проти звичайної border) */
.table tbody .table__row--group-start th,
.table tbody .table__row--group-start td {
  border-block-start: 1px solid var(--uris-color-semantic-surface-active);
}

/* Рядки всередині групи — звичайна межа (успадковано від .table :where(th,td)) */
