/* Єдина таблиця стилів дашборда. Джерело візуальних рішень — docs/design/dashboard/,
   порядок робіт — тікет #49.

   Порт завершено: усі чотири сторінки на цій системі, перехідного блоку body.legacy більше немає.

   Теми обидві. Світла — дефолт у :root, темна — перекриття в prefers-color-scheme. Палітра
   темної взята з аркуша токенів; світлої в макетах немає, вона виведена за тими самими ролями
   й підібрана під контраст на світлому тлі. */

@font-face {
    font-family: "IBM Plex Sans";
    font-style: normal;
    font-weight: 100 700; /* variable-файл на весь діапазон ваг */
    font-display: swap;
    src: url("../fonts/ibm-plex-sans-latin.woff2") format("woff2");
}

@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-400-latin.woff2") format("woff2");
}

@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("../fonts/ibm-plex-mono-500-latin.woff2") format("woff2");
}

:root {
    color-scheme: light dark;

    --font-ui: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
    --font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Code", Consolas, monospace;

    --radius-control: 3px;
    --radius-panel: 4px;
    --row-pad: 9px;
    --gutter: 24px;

    /* Світла тема (дефолт) */
    --bg: #f7f9fa;
    --panel: #ffffff;
    --panel-head: #f1f4f7;
    --raised: #eaeef2;

    --line: #d4dbe2;
    --line-panel: #e2e7ec;
    --line-soft: #edf0f3;
    --line-control: #cfd7df;
    --line-input: #bfc9d3;

    --tx: #11161c;
    --tx-2: #2f3a45;
    --tx-dim: #5a6673;
    --tx-faint: #6e7a86;

    --accent: #0f8a86;
    --accent-bg: #e6f5f4;
    --accent-line: #9ed3d0;
    --crash: #c0392b;
    --crash-bg: #fdecea;
    --crash-line: #f0b4ad;
    --warn: #8f6510;
    --warn-bg: #fdf6e6;
    --warn-line: #e0c98f;
    --ok: #2c7a30;
    --ok-bg: #ecf7ed;
    --ok-line: #a8d5aa;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0c0f13;
        --panel: #0f1319;
        --panel-head: #12161c;
        --raised: #161b22;

        --line: #232931;
        --line-panel: #1e242c;
        --line-soft: #171c23;
        --line-control: #262d37;
        --line-input: #2a323d;

        --tx: #e2e7ee;
        --tx-2: #c1c9d4;
        --tx-dim: #8f99a8;
        --tx-faint: #5f6874;

        --accent: #4ec9c4;
        --accent-bg: #14211f;
        --accent-line: #2e5f5c;
        --crash: #f0776a;
        --crash-bg: #1f100e;
        --crash-line: #4a2420;
        --warn: #e8b055;
        --warn-bg: #1e1809;
        --warn-line: #4a3a1c;
        --ok: #7fca7f;
        --ok-bg: #101a0f;
        --ok-line: #27401f;
    }
}

/* --- база --- */

body {
    margin: 0;
    background: var(--bg);
    color: var(--tx);
    font-family: var(--font-ui);
    font-size: 13px;
    line-height: 1.45;
    -webkit-font-smoothing: antialiased;
}

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

.mono { font-family: var(--font-mono); }

.eyebrow {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--tx-faint);
}

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

.topbar {
    display: flex;
    align-items: center;
    gap: 20px;
    height: 48px;
    padding: 0 var(--gutter);
    border-bottom: 1px solid var(--line);
    background: var(--panel);
}

.topbar__mark {
    display: flex;
    align-items: center;
    gap: 9px;
    color: var(--tx);
}

.topbar__mark strong { font-size: 13.5px; font-weight: 600; letter-spacing: 0.055em; }
.topbar__mark svg { color: var(--accent); }

.topbar__project {
    display: flex;
    align-items: center;
    gap: 7px;
    height: 26px;
    padding: 0 4px 0 10px;
    border: 1px solid var(--line-input);
    border-radius: var(--radius-control);
    background: var(--raised);
}

.topbar__project select {
    border: 0;
    background: transparent;
    color: var(--tx);
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 500;
}

.topbar__nav { display: flex; align-items: center; gap: 2px; }

.topbar__nav a {
    padding: 5px 11px;
    border-radius: var(--radius-control);
    color: var(--tx-dim);
    text-decoration: none;
}

.topbar__nav a:hover { color: var(--tx); text-decoration: none; }
.topbar__nav a[aria-current="page"] { background: var(--raised); color: var(--tx); font-weight: 500; }

.topbar__spacer { flex-grow: 1; }
.topbar__meta { display: flex; align-items: center; gap: 16px; color: var(--tx-dim); font-size: 12px; }
.topbar__user { display: flex; align-items: center; gap: 8px; color: inherit; }
.topbar__user:hover { color: var(--tx); text-decoration: none; }
.topbar__logout { display: flex; }

/* --- каркас сторінки --- */

.page { padding: 22px var(--gutter) var(--gutter); }

.page__head { display: flex; align-items: baseline; gap: 14px; }
.page__head h1 { margin: 0; font-size: 20px; font-weight: 600; letter-spacing: -0.01em; }
.page__count { font-family: var(--font-mono); font-size: 12px; color: var(--tx-dim); }

/* --- фільтри --- */

.filterbar { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 16px; }

.filterbar__item {
    display: flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 4px 0 9px;
    border: 1px solid var(--line);
    border-radius: var(--radius-control);
    background: var(--panel-head);
}

.filterbar__item select,
.filterbar__item input {
    border: 0;
    background: transparent;
    color: var(--tx-2);
    font-family: var(--font-mono);
    font-size: 12px;
}

.filterbar__item input { width: 4em; }
.filterbar__item select:focus-visible,
.filterbar__item input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* --- таблиця issue-ів --- */

.itable {
    border: 1px solid var(--line-panel);
    border-radius: var(--radius-panel);
    overflow: hidden;
    background: var(--panel);
}

/* Треки колонок навмисно НЕ залежать від вмісту осередків. Шапка (`irow--head`) і кожен рядок тіла —
   окремі grid-контейнери з тим самим класом, а intrinsic-розміри в CSS Grid рахуються в межах одного
   контейнера: `minmax(104px, max-content)` дав би шапці ширину слова «Platform», а тілу — ширину
   `native, windows, gamecore`, тобто таблиця роз'їхалася б. `clamp()` обидва гриди рахують однаково. */
.irow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) clamp(104px, 12vw, 180px) 92px 82px 164px;
    gap: 16px;
    align-items: center;
    padding: var(--row-pad) 16px;
    border-bottom: 1px solid var(--line-soft);
}

.irow--head {
    height: 32px;
    padding-top: 0;
    padding-bottom: 0;
    border-bottom: 1px solid var(--line);
    background: var(--panel-head);
}

.irow:last-child { border-bottom: 0; }
.irow__num { text-align: right; font-family: var(--font-mono); font-size: 13px; font-variant-numeric: tabular-nums; color: var(--tx-2); }
.irow__num--hot { color: var(--crash); }
/* Прочерк замість числа USERS (#79): не значення, а його відсутність — тому приглушений, і
   курсор підказує, що пояснення лежить у title. Правило спільне для списку й рейла деталей. */
.nodata { color: var(--tx-dim); cursor: help; }
.irow__when { text-align: right; font-family: var(--font-mono); font-size: 12px; color: var(--tx-dim); }

.issue { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.issue__line { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* Обрізання й типу теж: Title легально буває без ": " (Fingerprinter.MakeTitle віддає самий тип),
   і тоді в цей осередок іде весь рядок — у проді вже є заголовки на 127 символів. */
.issue__type {
    font-weight: 600;
    font-size: 13.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.issue__msg,
.issue__culprit {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.issue__msg { color: var(--tx-dim); }
.issue__sub { display: flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 12px; min-width: 0; }
.issue__id { color: var(--accent); flex-shrink: 0; }
.issue__sep { color: var(--line-input); flex-shrink: 0; }
.issue__culprit { color: var(--tx-dim); }

/* Список платформ приходить із даних і росте з кожною консоллю, тож правило переносу тут обов'язкове:
   без нього `native, windows, gamecore` малюється поверх сусідньої колонки. Саме `anywhere`, не
   `break-word`: лише воно знижує min-content-внесок тексту, тобто змушує shrink-to-fit цього
   inline-block'а влізти в колонку, коли жодного пробілу в значенні немає. */
.tag {
    display: inline-block;
    overflow-wrap: anywhere;
    padding: 2px 7px;
    border: 1px solid var(--line-control);
    border-radius: var(--radius-control);
    background: var(--raised);
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--tx-dim);
}

.badge {
    flex-shrink: 0;
    padding: 2px 6px;
    border: 1px solid var(--line-control);
    border-radius: var(--radius-control);
    background: var(--raised);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--tx-dim);
}

.badge--regressed { color: var(--warn); background: var(--warn-bg); border-color: var(--warn-line); }
.badge--unsymbolicated { color: var(--tx-dim); background: var(--raised); border-color: var(--line-control); }
.badge--resolved { color: var(--ok); background: var(--ok-bg); border-color: var(--ok-line); }

.empty { padding: 34px 16px; text-align: center; color: var(--tx-dim); font-size: 12.5px; }
.empty__hint { display: block; margin-top: 6px; font-size: 11.5px; color: var(--tx-faint); }


/* --- спільні примітиви --- */

.panel { border: 1px solid var(--line-panel); border-radius: var(--radius-panel); background: var(--panel); }
.panel--pad { padding: 14px 16px; }
.panel__head {
    display: flex;
    align-items: baseline;
    gap: 12px;
    padding: 11px 16px;
    border-bottom: 1px solid var(--line-panel);
    background: var(--panel-head);
}
.panel__note { font-size: 11.5px; color: var(--tx-faint); }
.panel__label { margin-bottom: 10px; }

.btn {
    height: 30px;
    padding: 0 13px;
    border: 1px solid var(--line-control);
    border-radius: var(--radius-control);
    background: var(--raised);
    color: var(--tx-2);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
}

.btn:hover { color: var(--tx); }
.btn--primary { border-color: var(--accent-line); background: var(--accent-bg); color: var(--accent); font-weight: 500; }
.btn--block { display: block; width: 100%; }
.btn--slim { height: 24px; padding: 0 9px; font-size: 12px; }
.btn:focus-visible, .input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.input {
    height: 30px;
    min-width: 0;
    padding: 0 10px;
    border: 1px solid var(--line-input);
    border-radius: var(--radius-control);
    background: var(--bg);
    color: var(--tx);
    font-size: 12.5px;
}

.banner {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 11px;
    padding: 8px 11px;
    border: 1px solid var(--line-control);
    border-radius: var(--radius-control);
    background: var(--raised);
    font-size: 12.5px;
}

.banner--error { border-color: var(--crash-line); background: var(--crash-bg); color: var(--crash); }
.banner--error svg { flex-shrink: 0; }
.banner--ok { border-color: var(--ok-line); background: var(--ok-bg); color: var(--ok); }
.empty--inline { padding: 0; text-align: left; }

/* `max-content` на ключі лишається свідомо: ключі Overview задає код (`Events`, `First seen`,
   `Releases`, …), а не дані, тож ширина першої колонки тут обмежена й передбачувана. Плутати це з
   панеллю Tags не можна — там ключ приходить із події, і для неї є `.meta.meta--stacked` нижче. */
.meta { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 7px 12px; margin: 0; }
.meta dt { font-size: 12px; color: var(--tx-faint); }
/* `anywhere`, не `break-word` (#76): значення — список релізів, шлях або хеш без жодного пробілу, а
   `break-word` не рве слово, яке не влазить у рядок цілком. Попередній `nowrap + ellipsis` ховав
   саме хвіст, тобто найкориснішу половину: у списку релізів гинули найсвіжіші. */
.meta dd { margin: 0; font-size: 12px; color: var(--tx-2); overflow-wrap: anywhere; }

/* Панель Tags — єдиний <dl> дашборда, де З ПОДІЇ приходять ОБИДВІ половини (Details.cshtml:162),
   тобто довільної довжини і ключ, і значення. Жодна двоколонкова сітка їх не розведе на 372px
   рейла: `recap.main_module_fingerprint` моноширинним з'їв би пів рейла, а 64-символьний хеш
   значення все одно лишився б без місця. Тому ключ НАД значенням, одна колонка.
   Компаунд `.meta.meta--stacked`, а не сам модифікатор: у `.meta--stacked` та сама специфічність
   (0-1-0), що в `.meta` вище, тож перевизначення трималося б лише на ПОРЯДКУ рядків — перенесення
   `.meta` нижче по файлу мовчки повертало б панелі двоколонкову сітку (і `margin: 0` рядкам `dd`).
   Другий клас у предметі робить перемогу незалежною від порядку; сам компаунд пінить existence-факт
   гейта (`DashboardCssTests.StructuralAnchors`), тож відкат до одинарного селектора червоніє. */
.meta.meta--stacked { grid-template-columns: minmax(0, 1fr); gap: 0; }
.meta.meta--stacked dt { overflow-wrap: anywhere; }
.meta.meta--stacked dd { margin-bottom: 9px; }
.meta.meta--stacked dd:last-child { margin-bottom: 0; }

/* --- issue detail --- */

.detail__head { display: flex; flex-direction: column; gap: 7px; }
.detail__id { display: flex; align-items: center; gap: 10px; }
.detail__short { font-size: 12.5px; font-weight: 500; color: var(--accent); }
/* Заголовок це `{Type}: {message}` (`Fingerprinter.MakeTitle`, до 200 символів значення), і обидві
   половини приходять із події: тип C#-винятку буває повним іменем з namespace без жодного пробілу, а
   повідомлення регулярно несе шлях. `.detail__msg` власного правила не має свідомо — це вкладений
   <span> усередині <h1>, а `overflow-wrap` успадковується (нестинг пінить DetailHeadLayoutTests). */
.detail__title { margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -0.015em; line-height: 1.25; overflow-wrap: anywhere; }
.detail__msg { color: var(--tx-dim); font-weight: 400; }
/* Culprit це `{Module} in {Function}`, де модуль штатно буває шляхом образу (`Il2cppUserAssemblies.prx`
   із повним шляхом на консолях), а функція — generic-інстанціацією IL2CPP: пробілів рівно один. */
.detail__culprit { font-size: 12.5px; color: var(--tx-dim); overflow-wrap: anywhere; }
.detail__actions { display: flex; gap: 6px; margin: 16px 0; }

.detail { display: grid; grid-template-columns: minmax(0, 1fr) 372px; gap: 20px; align-items: start; }
.detail__main { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.detail__rail { display: flex; flex-direction: column; gap: 20px; }

/* Значення винятку довільне за побудовою — шляхи, URL, серіалізовані аргументи, — тож перенос по
   пробілах його не рятує: рядок без жодного пробілу малювався б поверх межі панелі (#76). */
.exception__value { margin: 12px 16px 0; font-size: 12.5px; color: var(--tx-2); overflow-wrap: anywhere; }
.stack { display: flex; flex-direction: column; padding: 6px 0; }

/* Фрейм двохрядковий, не трьохколонковий (#76): у колонці 210px найдовший корисний шматок шляху —
   ім'я файла з рядком — гинув першим, бо ellipsis ріже кінець, а `text-align: right` вирівнює
   лінійний бокс, не переповнення. На всю ширину панелі прод-шлях лягає в 1-2 рядки. */
.frame {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 5px 16px;
}

/* In-app виділяється вагою й контрастом, не кольором і не лівою лінійкою: око має падати на
   throw site без декору. */
.frame__site { overflow-wrap: anywhere; }
.frame__sep { font-size: 11.5px; color: var(--tx-faint); }
.frame__module { font-size: 11.5px; color: var(--tx-faint); }
.frame__fn { font-size: 12.5px; color: var(--tx-dim); }
/* `anywhere`, не `break-word`: перший рядок теж нерозривний за побудовою — IL2CPP-generic'и
   (`Dictionary`2<System.String,…>::Insert`) пробілів не мають, як і шлях у другому. */
.frame__loc { font-size: 11.5px; color: var(--tx-faint); overflow-wrap: anywhere; }
.frame--in-app .frame__fn { color: var(--tx); font-weight: 500; }

.crumbs { display: flex; flex-direction: column; }

/* Фіксовані 108/120/74 лишаються свідомо, і `max-content` тут не варіант: шапка (`crumb--head`) і
   КОЖЕН рядок тіла це окремі grid-контейнери з тим самим класом, а intrinsic-розміри рахуються в
   межах одного контейнера — шапка дістала б одну ширину, тіло іншу, і таблиця роз'їхалась би.
   `align-items: baseline` — бо повідомлення тепер багаторядкове (#76): за `stretch` час, категорія
   й рівень тримались би верху свого осередка й «плавали» відносно першого рядка тексту. */
.crumb {
    display: grid;
    grid-template-columns: 108px 120px 74px minmax(0, 1fr);
    gap: 14px;
    padding: 7px 16px;
    align-items: baseline;
    border-bottom: 1px solid var(--line-soft);
}

.crumb--head { border-bottom: 1px solid var(--line); }
.crumb:last-child { border-bottom: 0; }
/* Усі ТРИ ліві осередки приходять із події, а не з коду, тож фіксована ширина колонки жодному з них
   не гарантія — правило переносу тут єдине, що тримає значення у своєму осередку. Категорія:
   `ui.click` влазить у 120px, `sentry.transaction.something` — ні. Час виглядав безпечним і був
   найгіршим із трьох: `ParseBreadcrumbs` віддає РЯДОК із jsonb як є, а туди
   `EventWriter.SerializeBreadcrumbs` пише `DateTimeOffset` у форматі System.Text.Json —
   `2026-09-07T15:36:39.205152+00:00`, 25-33 символи, тобто ~220px у треку 108px. Розриви в ньому є
   лише після дефісів, тож хвіст `07T15:36:39.205152+00:00` малювався б поверх колонки Category (#76).
   Рівень — теж сирий рядок події: закритий набір SDK на нашому боці нічим не підкріплений. */
.crumb__time, .crumb__cat, .crumb__level { font-size: 11.5px; color: var(--tx-faint); overflow-wrap: anywhere; }
.crumb__cat { color: var(--tx-dim); }
.crumb__level--warn { color: var(--warn); }
/* Повідомлення breadcrumb'а довільне за побудовою (шляхи, URL, JSON-хвости), а `nowrap + ellipsis`
   ховав саме кінець рядка — тобто те, заради чого breadcrumb і читають перед крешем (#76). */
.crumb__msg { font-size: 12.5px; color: var(--tx-2); overflow-wrap: anywhere; }

/* URL failed-HTTP події пробілів не має за побудовою, тож перенос по пробілах його не рятує — той
   самий прецедент, що `.secret` нижче. Без правила рядок вилазив за межі рейла (#76). */
.http__line { margin: 0; font-size: 12px; color: var(--tx-2); overflow-wrap: anywhere; }
.jira__attach { display: flex; gap: 7px; margin-bottom: 11px; }
.jira__attach .input { flex-grow: 1; }

/* --- releases --- */

.rrow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 150px 100px 170px 140px 88px 88px 148px 124px;
    gap: 14px;
    align-items: center;
    padding: 10px 16px;
    border-bottom: 1px solid var(--line-soft);
}

/* min-height, а не height: заголовки на кшталт CRASH-FREE SESSIONS переносяться на два рядки, і за
   фіксованої висоти другий рядок вилазив за межі шапки таблиці. */
.rrow--head {
    min-height: 32px;
    padding-top: 6px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--line);
    background: var(--panel-head);
}

.rrow:last-child { border-bottom: 0; }
/* Обрізання обов'язкове: справжні версії FP несуть git-хеш («06.12+6673ce83850648db9a738eccccd5805»),
   і без цього рядок вилазив з осередка й малювався поверх колонки First seen. Повне значення
   лишається доступним у title. */
.rrow__version {
    font-size: 13px;
    font-weight: 500;
    color: var(--tx);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rrow__when { font-size: 11.5px; color: var(--tx-dim); }

.num { text-align: right; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--tx-2); }
.num--dim { color: var(--tx-dim); }
.num--ok { color: var(--ok); }
.num--warn { color: var(--warn); }
.num--none { color: var(--tx-faint); }

.adoption { display: flex; align-items: center; gap: 9px; }
.adoption__track { width: 62px; height: 4px; border-radius: 2px; background: var(--line-panel); overflow: hidden; }
.adoption__fill { display: block; height: 4px; border-radius: 2px; background: var(--accent); }
.adoption__pct { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--tx-2); }

.legend { display: flex; align-items: center; gap: 18px; margin-top: 16px; font-size: 11.5px; color: var(--tx-faint); }
.legend__item { display: flex; align-items: center; gap: 6px; }
.legend__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--tx-2); }
.legend__dot--ok { background: var(--ok); }
.legend__dot--warn { background: var(--warn); }
.legend__note { margin-left: auto; }

/* --- sign in --- */

.signin { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 24px; }
.signin__card { width: 380px; }
.signin__brand { display: flex; align-items: center; gap: 10px; color: var(--tx); }
.signin__brand svg { color: var(--accent); }
.signin__brand strong { font-size: 18px; font-weight: 600; letter-spacing: 0.06em; }
.signin__sub { margin: 9px 0 26px; font-size: 12.5px; color: var(--tx-dim); }

.signin__form {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 24px;
    border: 1px solid var(--line-panel);
    border-radius: 5px;
    background: var(--panel);
}

.field { display: flex; flex-direction: column; gap: 6px; }
.field .input { height: 34px; }

/* --- account --- */

.account { display: flex; flex-direction: column; gap: 20px; max-width: 700px; margin-top: 16px; }
.account__banner { max-width: 700px; margin-top: 16px; }
.account__form { display: flex; flex-direction: column; gap: 13px; padding: 14px 16px; }
.account__form--row { flex-direction: row; align-items: flex-end; gap: 8px; }
.account__grow { flex-grow: 1; }
.account__form + .account__form { padding-top: 0; }

.secret {
    display: block;
    padding: 9px 11px;
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-control);
    background: var(--bg);
    color: var(--accent);
    font-size: 12.5px;
    overflow-wrap: anywhere;
}

.tokens { display: flex; flex-direction: column; border-top: 1px solid var(--line-panel); }

.trow {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr) max-content max-content max-content;
    align-items: center;
    gap: 14px;
    padding: 9px 16px;
    border-bottom: 1px solid var(--line);
    font-size: 12.5px;
}

.trow--head { padding: 8px 16px; background: var(--panel-head); border-bottom: 1px solid var(--line-panel); }
.trow:last-child { border-bottom: 0; }
.trow__prefix { color: var(--accent); }
/* Єдине поле #76, чиє значення пише ЛЮДИНА через форму, а не конвеєр із події: ім'я токена (до 64
   символів, `IndexModel.MaxTokenNameLength`), а в списку адмінки в цей самий осередок їде ще й пошта
   власника (`Admin/Users.cshtml:166` — `@token.Email · @token.Name`). Обрізання хвоста тут коштує
   найдорожче: імена штатно розрізняються саме кінцем (`ci-upload-steam` / `ci-upload-xbox`), тож
   ellipsis робив список нерозрізнюваним рівно в момент «відклич не той». `align-items: center` у
   `.trow`/`.urow` лишається без змін: обидва рядки несуть контроли (Revoke, селектор ролі), і
   перенесене на два рядки ім'я центрує їх відносно рядка, а не притискає до першого рядка тексту —
   на відміну від `.crumb` (Task 4), який суто текстовий і тому пішов на `baseline`. */
.trow__name { color: var(--tx-2); overflow-wrap: anywhere; }
.trow__when { font-family: var(--font-mono); font-size: 11.5px; color: var(--tx-dim); }

/* --- admin accounts --- */

.account--wide { max-width: 980px; }

/* Власна сітка, а не .trow: у списку акаунтів два стовпці інтерактивні (селектор ролі й кнопки),
   тож ширини тут задають контроли, а не текст. */
.urow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) max-content max-content max-content max-content;
    align-items: center;
    gap: 14px;
    padding: 7px 16px;
    border-bottom: 1px solid var(--line);
    font-size: 12.5px;
}

.urow--head { padding: 8px 16px; background: var(--panel-head); border-bottom: 1px solid var(--line-panel); }
.urow:last-child { border-bottom: 0; }
.urow__inline { display: flex; align-items: center; gap: 6px; }
.input--slim { height: 24px; padding: 0 6px; font-size: 12px; }
