﻿/* maximum — приборная панель телеметрии.
   Визуальный язык: материалы вместо рамок, крупная типографика, мягкая глубина.
   Числа набраны моноширинным с табличными цифрами — они не должны прыгать при
   обновлении данных. Палитра графиков проверена на CVD-разделимость в обеих темах. */

:root {
    color-scheme: light;

    /* фон холоднее поверхностей: карточки всплывают над ним без жирных обводок */
    --page: #f5f5f7;
    --page-top: #f5f5f7;
    --surface: #ffffff;
    --surface-sunken: #f2f2f4;
    --surface-hover: #f5f5f7;
    --surface-veil: rgba(255, 255, 255, 0.72);

    /* непрозрачная опора сайдбара — по ней строится шторка над полотном лент */
    --sidebar-solid: #f6f7fa;
    --sb-banner-opacity: 0.26;

    /* свечение у первичных кнопок — только в тёмной теме, тут выключено */
    --btn-glow: 0 0 0 0 transparent;

    /* верхний ореол на фоне — только в тёмной теме, в светлой прозрачен */
    --page-glow: transparent;

    --ink: #1d1d1f;
    --ink-secondary: #55555b;
    --ink-muted: #86868b;

    --line: rgba(0, 0, 0, 0.07);
    --line-strong: rgba(0, 0, 0, 0.14);
    --grid: rgba(0, 0, 0, 0.06);

    /* стеклянная кромка карточек: в светлой теме почти незаметна, в тёмной —
       ловит верхний блик, как поверхности macOS. Градиент-подсветка поверх фона. */
    --card-tint-top: transparent;
    --card-tint-bottom: transparent;
    --card-edge: rgba(255, 255, 255, 0.5);

    --accent: #0071e3;
    --accent-hover: #0077ed;
    --accent-ink: #ffffff;
    --accent-wash: rgba(0, 113, 227, 0.10);

    --good: #1d9d47;
    --warning: #f0a30a;
    --serious: #d1730a;
    --critical: #d92d20;
    --good-ink: #17803a;

    --series-1: #0071e3;
    --series-2: #e8590c;
    --series-3: #16a06a;
    --series-4: #d29200;
    --series-5: #d9569b;
    --series-6: #2a7d2a;
    --series-7: #6247c7;
    --series-8: #d64545;

    /* скругления крупнее привычных: карточка должна читаться как физический объект */
    --radius-sm: 8px;
    --radius: 11px;
    --radius-lg: 18px;
    --radius-pill: 980px;

    --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI Variable Text",
            "Segoe UI", Inter, system-ui, sans-serif;
    --mono: "SF Mono", ui-monospace, "Cascadia Mono", "JetBrains Mono", Consolas, monospace;

    /* тень из двух слоёв: близкий контакт и мягкий ореол — как у окон macOS */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 1px rgba(0, 0, 0, 0.02);
    --shadow: 0 1px 3px rgba(0, 0, 0, 0.05), 0 12px 28px -12px rgba(0, 0, 0, 0.16);
    --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.06), 0 32px 64px -24px rgba(0, 0, 0, 0.32);

    /* фирменная кривая: быстрый старт, долгое мягкое торможение */
    --ease: cubic-bezier(0.32, 0.72, 0, 1);
}

/* тёмная тема — «графит»: нейтральный сине-серый, не глубокий navy. Грунты
   подняты по светимости, чтобы карточки читались, а не тонули в темноте.
   Значения продублированы для системной темы и ручного переключателя. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --page: #171a21;
        --surface: #1e2029;
        --surface-sunken: #17191f;
        --surface-hover: #2c2f3a;
        --surface-veil: rgba(26, 28, 36, 0.68);

        --ink: #eef0f4;
        --ink-secondary: #abb0bc;
        --ink-muted: #7e8493;

        --line: rgba(255, 255, 255, 0.09);
        --line-strong: rgba(255, 255, 255, 0.17);
        --grid: rgba(255, 255, 255, 0.08);

        --card-tint-top: rgba(255, 255, 255, 0.04);
        --card-tint-bottom: rgba(0, 0, 0, 0.14);
        --card-edge: rgba(255, 255, 255, 0.06);

        /* фон «дышит»: верх чуть светлее плюс холодный ореол-источник света */
        --page-top: #1f232c;
        --page-glow: color-mix(in srgb, var(--accent) 8%, transparent);

        /* мягкое свечение первичных кнопок на тёмном */
        --btn-glow: 0 6px 20px -6px color-mix(in srgb, var(--accent) 55%, transparent);

        /* сине-стальной подтон левого меню */
        --sidebar-bg: rgba(20, 29, 43, 0.80);
        --sidebar-line: rgba(120, 160, 240, 0.16);
        --sidebar-solid: #141d2b;
        --sb-banner-opacity: 0.6;

        --accent: #0a84ff;
        --accent-hover: #3d9bff;
        --accent-wash: rgba(61, 155, 255, 0.18);

        --good: #30d158;
        --warning: #ffd60a;
        --serious: #ff9f0a;
        --critical: #ff453a;
        --good-ink: #32d74b;

        --series-1: #3d9bff;
        --series-2: #ff9f0a;
        --series-3: #30d158;
        --series-4: #ffd60a;
        --series-5: #ff6482;
        --series-6: #66d4cf;
        --series-7: #bf5af2;
        --series-8: #ff453a;

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45);
        --shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 12px 28px -12px rgba(0, 0, 0, 0.75);
        --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.6), 0 32px 64px -24px rgba(2, 5, 16, 0.9);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --page: #171a21;
    --surface: #1e2029;
    --surface-sunken: #17191f;
    --surface-hover: #2c2f3a;
    --surface-veil: rgba(26, 28, 36, 0.68);

    --ink: #eef0f4;
    --ink-secondary: #abb0bc;
    --ink-muted: #7e8493;

    --line: rgba(255, 255, 255, 0.09);
    --line-strong: rgba(255, 255, 255, 0.17);
    --grid: rgba(255, 255, 255, 0.08);

    --card-tint-top: rgba(255, 255, 255, 0.04);
    --card-tint-bottom: rgba(0, 0, 0, 0.14);
    --card-edge: rgba(255, 255, 255, 0.06);

    /* фон «дышит»: верх чуть светлее плюс холодный ореол-источник света */
    --page-top: #1f232c;
    --page-glow: color-mix(in srgb, var(--accent) 8%, transparent);

    /* мягкое свечение первичных кнопок на тёмном */
    --btn-glow: 0 6px 20px -6px color-mix(in srgb, var(--accent) 55%, transparent);

    /* сине-стальной подтон левого меню */
    --sidebar-bg: rgba(20, 29, 43, 0.80);
    --sidebar-line: rgba(120, 160, 240, 0.16);
    --sidebar-solid: #141d2b;
    --sb-banner-opacity: 0.6;

    --accent: #0a84ff;
    --accent-hover: #3d9bff;
    --accent-wash: rgba(61, 155, 255, 0.18);

    --good: #30d158;
    --warning: #ffd60a;
    --serious: #ff9f0a;
    --critical: #ff453a;
    --good-ink: #32d74b;

    --series-1: #3d9bff;
    --series-2: #ff9f0a;
    --series-3: #30d158;
    --series-4: #ffd60a;
    --series-5: #ff6482;
    --series-6: #66d4cf;
    --series-7: #bf5af2;
    --series-8: #ff453a;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 12px 28px -12px rgba(0, 0, 0, 0.75);
    --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.6), 0 32px 64px -24px rgba(2, 5, 16, 0.9);
}

* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
}

/* Горизонтальный обрез держим только на html: он передаётся окну и так же
   отсекает широкое содержимое. На body тот же overflow-x делал из него
   собственный контейнер прокрутки — и липкий сайдбар переставал липнуть,
   потому что «прокручивался» уже не тот элемент, к которому он прижат.
   Место под вертикальный скроллбар резервируем всегда: иначе при переходе
   между длинной и короткой страницами вся сетка вместе с сайдбаром
   сдвигается на ширину скроллбара */
html {
    overflow-x: hidden;
    scrollbar-gutter: stable;
}

body {
    background-color: var(--page);
    /* холодный ореол-источник сверху + верх чуть светлее, гаснущий к --page.
       В светлой теме оба слоя прозрачны/плоски — фон остаётся ровным */
    background-image:
        radial-gradient(120% 65% at 50% -12%, var(--page-glow), transparent 60%),
        linear-gradient(180deg, var(--page-top), transparent 520px);
    background-attachment: fixed;
    color: var(--ink);
    font-family: var(--sans);
    font-size: 14px;
    line-height: 1.5;
    letter-spacing: -0.01em;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

a {
    color: var(--accent);
    text-decoration: none;
    text-underline-offset: 2px;
}

a:hover {
    text-decoration: underline;
}

:focus-visible {
    outline: 3px solid color-mix(in srgb, var(--accent) 45%, transparent);
    outline-offset: 2px;
    border-radius: 6px;
}

h1,
h2,
h3 {
    margin: 0;
    font-weight: 600;
}

h1 {
    font-size: 30px;
    line-height: 1.12;
    letter-spacing: -0.024em;
}

h2 {
    font-size: 16px;
    letter-spacing: -0.014em;
}

h3 {
    font-size: 13px;
    letter-spacing: -0.008em;
}

/* контент проявляется, а не выпрыгивает — но только если движение не отключено */
.main > * {
    animation: rise 0.34s var(--ease) both;
}

@keyframes rise {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .main > * { animation: none; }
}

/* ── Каркас ───────────────────────────────────────────────────────────── */

.shell {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    min-height: 100vh;
}

/* боковая панель — полупрозрачный материал: под ней просвечивает фон страницы */
.sidebar {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 24px 16px 18px;
    /* в тёмной теме сайдбар получает сине-стальной подтон (--sidebar-*),
       в светлой падает на общий полупрозрачный материал */
    background: var(--sidebar-bg, var(--surface-veil));
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border-right: 1px solid var(--sidebar-line, var(--line));

    /* меню выше экрана на невысоких окнах и телефонах: без прокрутки футер
       с балансами, аккаунтом и выходом просто обрезался и был недоступен */
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Полотно из лент значка РСЯ в шапке сайдбара, раскладка «веер». Абсолютный
   слой считается от padding-box, поэтому лента доходит до самых краёв панели.
   Лежит под содержимым, гаснет к меню и закрыта снизу тонкой кромкой */
.sb-banner {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 134px;
    z-index: 0;
    pointer-events: none;
}

.sb-banner svg {
    display: block;
    width: 100%;
    height: 100%;
    opacity: var(--sb-banner-opacity);
}

/* шторка: название и статус всегда стоят на спокойном фоне, а не на ленте */
.sb-banner::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--sidebar-solid) 44%, transparent) 0%,
        color-mix(in srgb, var(--sidebar-solid) 74%, transparent) 58%,
        color-mix(in srgb, var(--sidebar-solid) 96%, transparent) 88%,
        var(--sidebar-solid) 100%);
}

/* кромка закрывает полотно снизу — иначе оно растворяется пятном */
.sb-banner-edge {
    position: absolute;
    left: 16px;
    right: 16px;
    bottom: 0;
    height: 1px;
    z-index: 1;
    background: linear-gradient(90deg, transparent,
        var(--sidebar-line, var(--line)), transparent);
}

/* содержимое панели — поверх полотна */
.sidebar > *:not(.sb-banner) {
    position: relative;
    z-index: 1;
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 12px 22px;
    text-decoration: none;
}

.brand:hover {
    text-decoration: none;
}

/* знак — кривая набора просмотров: ровно то, чем занят сервис.
   Плитка не имитирует стекло, а работает как стекло: размывает подложку,
   ловит блик по верхней кромке и роняет тень внутрь */
.brand-glyph {
    position: relative;
    width: 38px;
    height: 38px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 11px;
    color: var(--accent);
    background: linear-gradient(150deg,
        color-mix(in srgb, var(--surface) 78%, transparent),
        color-mix(in srgb, var(--surface) 42%, transparent));
    backdrop-filter: saturate(150%) blur(6px);
    -webkit-backdrop-filter: saturate(150%) blur(6px);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.9),
        inset 0 0 0 1px color-mix(in srgb, var(--ink) 9%, transparent),
        0 4px 14px -6px rgba(0, 0, 0, 0.35);
}

/* блик по верхней кромке — то, что делает поверхность стеклянной, а не матовой */
.brand-glyph::after {
    content: "";
    position: absolute;
    inset: 1px 1px auto;
    height: 45%;
    border-radius: 10px 10px 60% 60% / 10px 10px 100% 100%;
    background: linear-gradient(to bottom,
        rgba(255, 255, 255, 0.55),
        rgba(255, 255, 255, 0));
    pointer-events: none;
}

:root[data-theme="dark"] .brand-glyph,
:root:not([data-theme="light"]) .brand-glyph {
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.22),
        inset 0 0 0 1px rgba(255, 255, 255, 0.12),
        0 4px 14px -6px rgba(0, 0, 0, 0.7);
}

:root[data-theme="dark"] .brand-glyph::after,
:root:not([data-theme="light"]) .brand-glyph::after {
    background: linear-gradient(to bottom,
        rgba(255, 255, 255, 0.16),
        rgba(255, 255, 255, 0));
}

.brand-glyph svg {
    position: relative;
    z-index: 1;
    width: 21px;
    height: 21px;
    filter: drop-shadow(0 1px 1px color-mix(in srgb, var(--accent) 45%, transparent));
}

/* когда знак — готовая картинка, своё стекло рисовать не нужно: оно уже внутри */
.brand-glyph.is-image {
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
}

.brand-glyph.is-image::after {
    display: none;
}

.brand-glyph img {
    width: 100%;
    height: 100%;
    display: block;
    /* на тёмном фоне светлое стекло без тени выглядит наклейкой */
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.25));
}

.brand-mark {
    font-family: var(--mono);
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--ink);
    line-height: 1.15;
}

.brand-status {
    display: flex;
    align-items: center;
    gap: 5px;
}

.brand-sub {
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-muted);
    white-space: nowrap;
}

/* индикатор живого поллера: пульс, который затихает при reduced-motion */
.pulse {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--good);
    flex: none;
    animation: pulse 2.6s var(--ease) infinite;
}

.pulse.is-idle {
    background: var(--ink-muted);
    animation: none;
}

.pulse.is-bad {
    background: var(--critical);
    animation: none;
}

@keyframes pulse {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 45%, transparent); }
    70% { box-shadow: 0 0 0 6px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .pulse { animation: none; }
}

.nav-section {
    margin-top: 10px;
    padding: 14px 13px 6px;
    border-top: 1px solid var(--line);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

/* над первым разделом черты не нужно — он идёт сразу под брендом */
.nav-section:first-of-type {
    margin-top: 2px;
    border-top: none;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 10px 13px;
    border-radius: var(--radius-sm);
    color: var(--ink-secondary);
    font-size: 14.5px;
    text-decoration: none;
    transition: background 0.18s var(--ease), color 0.18s var(--ease);
}

.nav-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nav-icon {
    width: 20px;
    height: 20px;
    flex: none;
    display: grid;
    place-items: center;
    color: var(--ink-muted);
    transition: color 0.18s var(--ease);
}

.nav-icon svg {
    width: 20px;
    height: 20px;
}

.nav-link:hover {
    background: color-mix(in srgb, var(--ink) 6%, transparent);
    color: var(--ink);
    text-decoration: none;
}

/* активный пункт: сплошная заливка и более тяжёлое начертание —
   признак не только цветовой, различим и в оттенках серого */
/* активный пункт — мягкая акцентная подложка и полоска-индикатор слева,
   а не сплошная кричащая заливка */
.nav-link.active {
    background: var(--accent-wash);
    color: var(--accent);
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--accent);
}

.nav-link.active:hover {
    background: color-mix(in srgb, var(--accent) 24%, transparent);
    color: var(--accent);
}

.nav-link:hover .nav-icon,
.nav-link.active .nav-icon {
    color: currentColor;
}

.nav-avatar {
    width: 22px;
    height: 22px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--surface-sunken);
    border: 1px solid var(--line);
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
}

.nav-count {
    flex: none;
    min-width: 21px;
    padding: 1px 7px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 8%, transparent);
    font-family: var(--mono);
    font-size: 11px;
    line-height: 1.55;
    text-align: center;
    color: var(--ink-secondary);
    font-variant-numeric: tabular-nums;
}

/* счётчик, требующий внимания, отличается не только цветом, но и весом */
.nav-count.is-alert {
    color: #fff;
    background: var(--critical);
    font-weight: 600;
}

.nav-link.active .nav-count {
    background: color-mix(in srgb, var(--accent) 22%, transparent);
    color: var(--accent);
}

.sidebar-footer {
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* балансы сервисов: две строки в одной утопленной плашке — стеклянной, как карточки */
.balances {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 9px 11px;
    border-radius: var(--radius-sm);
    background:
        linear-gradient(var(--card-tint-top), var(--card-tint-bottom)),
        var(--surface-sunken);
    box-shadow: inset 0 1px 0 var(--card-edge);
    text-decoration: none;
    color: inherit;
    transition: background 0.18s var(--ease);
}

.balances:hover {
    text-decoration: none;
    background:
        linear-gradient(var(--card-tint-top), var(--card-tint-bottom)),
        var(--surface-hover);
}

.balance {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    line-height: 2;
}

.balance-dot {
    width: 7px;
    height: 7px;
    flex: none;
    border-radius: 50%;
    background: var(--tone, var(--accent));
}

.balance-name {
    color: var(--ink-muted);
}

.balance-value {
    margin-left: auto;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    color: var(--ink);
    letter-spacing: -0.01em;
    white-space: nowrap;
}

/* мало денег — красным, но приглушённо: это подсказка, а не тревога */
.balance-value.is-low {
    color: var(--critical);
}

/* иконки-действия у баланса: обновить и пополнить — проявляются, не мельтеша */
.balance-btn {
    flex: none;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--ink-muted);
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s var(--ease), color 0.15s var(--ease);
}

.balance-btn svg {
    width: 14px;
    height: 14px;
}

.balance-btn:hover {
    background: color-mix(in srgb, var(--ink) 8%, transparent);
    color: var(--ink);
    text-decoration: none;
}

.balance-btn:disabled {
    cursor: default;
    opacity: 0.5;
}

.balance-btn .spin {
    animation: spin 0.8s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .balance-btn .spin { animation: none; }
}

/* на широком мониторе колонка контента не растягивается бесконечно —
   строка длиннее ~110 символов уже плохо читается, — но и не жмётся влево:
   свободное место делится поровну */
.main {
    min-width: 0;
    width: 100%;
    padding: 22px 34px 80px;
    max-width: 1560px;
    margin-inline: auto;
}

.mobile-bar {
    display: none;
}

.nav-scrim {
    display: none;
}

/* ── Шапка страницы ───────────────────────────────────────────────────── */

/* крупный значок раздела слева от заголовка (лого РСЯ на «Рекламе») */
.page-glyph {
    width: 52px;
    height: 52px;
    flex: none;
    border-radius: 14px;
    object-fit: cover;
    box-shadow: var(--shadow-sm), inset 0 1px 0 var(--card-edge);
}

/* шапка страницы уходит вместе с содержимым: место на экране дороже, а заголовок
   и кнопки нужны в начале работы, а не всю прокрутку */
.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 20px;
    margin: -22px -34px 24px;
    padding: 22px 34px 18px;
    /* размытие держалось на приклеенной шапке, под которую уезжало содержимое;
       в потоке размывать нечего — остаётся ровный бар во всю ширину и кромка */
    background: color-mix(in srgb, var(--page) 78%, transparent);
    border-bottom: 1px solid var(--line);
    flex-wrap: wrap;
}

/* шапка-подраздел (под лентой вкладок, напр. «Управление каналом»):
   без полноширинного бара — выровнена со вкладками и контентом */
.page-head.is-sub {
    margin: 4px 0 22px;
    padding: 0 0 18px;
    background: none;
}

.eyebrow {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--ink-muted);
    margin-bottom: 6px;
}

.page-subtitle {
    margin-top: 8px;
    color: var(--ink-secondary);
    font-size: 13.5px;
    line-height: 1.45;
    max-width: 64ch;
}

.toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* ── Ленты переключения и фильтров ────────────────────────────────────── */

/* Лента переносится по строкам, а не уезжает вбок. Прежде это была полоса
   с прокруткой и спрятанным скроллбаром: на мышке горизонтальной прокрутки
   нет, подсказки тоже, и последний канал выглядел просто обрезанным по краю. */
.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 18px;
    padding: 4px;
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--ink) 5%, transparent);
}

.tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background: transparent;
    color: var(--ink-secondary);
    font-family: inherit;
    font-size: 13px;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.2s var(--ease), color 0.2s var(--ease),
                box-shadow 0.2s var(--ease);
}

.tab:hover {
    color: var(--ink);
    text-decoration: none;
}

/* активная вкладка — приподнятая пластина, как сегмент-контрол в iOS */
.tab.is-active {
    background: var(--surface);
    color: var(--ink);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}

.tab.is-active:hover {
    background: var(--surface);
    color: var(--ink);
}

.tab.is-plain {
    color: var(--ink-muted);
}

.tab-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex: none;
    background: currentColor;
}

.tab-dot.is-active { background: var(--good); }
.tab-dot.is-paused { background: var(--ink-muted); }
.tab-dot.is-error { background: var(--critical); }
.tab-dot.is-new { background: var(--accent); }

.tab-title {
    max-width: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* на узком экране полное название съедает строку целиком — режем короче,
   чтобы в строку помещалось две вкладки, а не полторы */
@media (max-width: 560px) {
    .tab-title { max-width: 12ch; }
}

.tab-badge {
    font-family: var(--mono);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 8%, transparent);
    color: var(--ink-muted);
}

.tab.is-active .tab-badge {
    background: var(--accent-wash);
    color: var(--accent);
}

/* ── Лента каналов на странице управления ────────────────────────────────
   Тот же класс обслуживает две разные вещи: на «Каналах» это сегмент-контрол
   из двух кнопок, где серая капсула вокруг уместна, а здесь — навигация из
   десятка чипов, которые переносятся по строкам. Общая подложка под ними на
   неполной последней строке читалась не капсулой, а пустотой, поэтому у ленты
   свой режим: подложки нет, границу держит тонкая линия под ней. Она отделяет
   навигацию от содержимого и не зависит от того, сколько чипов в последнем ряду. */
.tabs.is-rail {
    align-items: center;
    gap: 7px;
    padding: 0 0 14px;
    border-radius: 0;
    background: none;
    border-bottom: 1px solid var(--line);
}

.tabs.is-rail .tab {
    gap: 8px;
    padding: 5px 13px 5px 6px;
    border-radius: var(--radius-pill);
    border-color: var(--line);
}

.tabs.is-rail .tab:hover {
    background: var(--surface-hover);
    border-color: var(--line-strong);
}

/* единственное яркое пятно ленты — канал, в котором мы сейчас */
.tabs.is-rail .tab.is-active {
    background: var(--surface);
    border-color: var(--line-strong);
    box-shadow: var(--shadow-sm);
}

/* без кольца значки каналов растворяются в фоне на своих 22 пикселях */
.tabs.is-rail .avatar {
    box-shadow: 0 0 0 1px var(--line-strong);
}

/* «Все каналы» — выход из ленты, а не ещё один канал: отделён чертой
   и держится текстом, без плашки вокруг */
.tab-sep {
    width: 1px;
    height: 16px;
    flex: none;
    margin: 0 3px;
    background: var(--line-strong);
}

.tabs.is-rail .tab.is-plain {
    padding-left: 11px;
    border-color: transparent;
    background: none;
    color: var(--ink-muted);
}

.tabs.is-rail .tab.is-plain:hover {
    border-color: transparent;
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* «авто» было словом в пилюле у каждого канала: девять одинаковых серых пилюль
   звучали громче названий, а сообщали одно и то же. Точка говорит то же самое */
.tab-auto {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    flex: none;
    background: var(--good);
    box-shadow: 0 0 0 2.5px color-mix(in srgb, var(--good) 16%, transparent);
}

/* ── Карточки ─────────────────────────────────────────────────────────── */

.card {
    background:
        linear-gradient(var(--card-tint-top), var(--card-tint-bottom)),
        var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    /* верхняя кромка ловит свет — поверхность читается как стекло, а не как заливка */
    box-shadow: var(--shadow-sm), inset 0 1px 0 var(--card-edge);
    overflow: hidden;
}

/* карточка, которая появилась по действию пользователя — приподнята и заметна */
.card.is-raised {
    box-shadow: var(--shadow);
    border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}

.card + .card {
    margin-top: 18px;
}

/* ── Обзор: амбиентное сияние на фоне ─────────────────────────────────── */

/* мягкие цветные пятна под контентом: страница перестаёт быть плоской,
   но остаётся спокойной — свет ловится в зазорах между карточками */
.dash-aura {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(58% 50% at 82% -8%,
            color-mix(in srgb, var(--accent) 24%, transparent), transparent 68%),
        radial-gradient(46% 44% at -6% 4%,
            color-mix(in srgb, var(--series-7) 20%, transparent), transparent 66%),
        radial-gradient(70% 60% at 110% 108%,
            color-mix(in srgb, var(--series-6) 16%, transparent), transparent 70%);
    opacity: 0.4;
}

/* на светлой теме цветной туман по белому заметнее — приглушаем сильнее */
:root[data-theme="light"] .dash-aura {
    opacity: 0.32;
}

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) .dash-aura {
        opacity: 0.32;
    }
}

@media (prefers-reduced-motion: no-preference) {
    .dash-aura {
        animation: aura-breathe 18s ease-in-out infinite alternate;
    }
}

@keyframes aura-breathe {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to { transform: translate3d(0, -1.5%, 0) scale(1.06); }
}

/* две карточки в ряд (события + очередь реакций) */
.dash-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    margin-top: 18px;
}

/* обе карточки одной высоты, а длинный список прокручивается внутри тела —
   так нет ни разной высоты, ни пустого места под коротким списком */
.dash-split .card {
    display: flex;
    flex-direction: column;
    max-height: 520px;
}

.dash-split .card-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.dash-split .card + .card,
.dash-split .card {
    margin-top: 0;
}

.dash-split + .card {
    margin-top: 18px;
}

@media (max-width: 900px) {
    .dash-split {
        grid-template-columns: 1fr;
    }

    .dash-split .card + .card {
        margin-top: 18px;
    }
}

/* очередь реакций: компактный список эмодзи · пост · канал · время.
   Все запланированные помещаются в скролл, чтобы карточка не росла бесконечно */
.react-queue {
    list-style: none;
    margin: 0;
    padding: 0;
}

.react-queue li {
    display: flex;
    align-items: center;
    gap: 10px;
    /* тот же вертикальный ритм, что у строк «Последних событий» рядом */
    padding: 8px 16px;
    border-bottom: 1px solid var(--line);
}

/* строки соседних виджетов — строго одной высоты: единая высота ячейки,
   нулевой вертикальный паддинг у обоих, контент по центру */
.dash-split .react-queue li,
.dash-split table.data td {
    height: 64px;
    padding-top: 0;
    padding-bottom: 0;
}

.dash-split table.data td {
    vertical-align: middle;
}

.dash-split .react-queue li {
    align-items: center;
}

/* в этих виджетах текст занимает всю доступную ширину, а не режется на 38 символах */
.dash-split .truncate {
    max-width: 100%;
}

.react-queue li:last-child {
    border-bottom: none;
}

.react-emoji {
    flex: none;
    width: 22px;
    text-align: center;
    font-size: 15px;
    line-height: 1;
}

.react-emoji.is-neg {
    filter: grayscale(0.2);
    opacity: 0.9;
}

.react-time {
    flex: none;
    margin-left: auto;
    font-variant-numeric: tabular-nums;
}

/* уже отправленные — приглушены и с зелёной галочкой: виден прогресс */
.react-queue li.is-done {
    background: color-mix(in srgb, var(--good) 6%, transparent);
}

.react-queue li.is-done .truncate {
    color: var(--ink-secondary);
}

/* отправленная капля: время + зелёная галочка */
.react-sent {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--good-ink);
    font-size: 12px;
}

.react-sent svg {
    width: 14px;
    height: 14px;
    flex: none;
}

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--line);
}

.card-body {
    padding: 20px;
}

.card-body.tight {
    padding: 0;
}

.card-note {
    font-size: 12.5px;
    color: var(--ink-muted);
}

/* ── Плитки со статистикой ────────────────────────────────────────────── */

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(184px, 100%), 1fr));
    gap: 14px;
    margin-bottom: 20px;
}

.tile {
    background:
        linear-gradient(var(--card-tint-top), var(--card-tint-bottom)),
        var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 16px 18px 18px;
    box-shadow: var(--shadow-sm), inset 0 1px 0 var(--card-edge);
    transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.tile:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow), inset 0 1px 0 var(--card-edge);
}

@media (prefers-reduced-motion: reduce) {
    .tile:hover { transform: none; }
}

.tile-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--ink-muted);
}

.tile-value {
    margin-top: 10px;
    font-size: 30px;
    line-height: 1.05;
    font-weight: 600;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}

/* второстепенная часть числа — копейки, знак валюты: мельче и приглушённо */
.tile-unit {
    font-size: 16px;
    font-weight: 500;
    letter-spacing: -0.015em;
    color: var(--ink-muted);
    white-space: nowrap;
}

.tile-meta {
    margin-top: 7px;
    font-size: 12.5px;
    color: var(--ink-secondary);
}

/* шкала лимита: сколько дневного бюджета уже израсходовано */
.tile-gauge {
    margin-top: 12px;
    height: 5px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 9%, transparent);
    overflow: hidden;
}

.tile-gauge-bar {
    display: block;
    height: 100%;
    min-width: 3px;
    border-radius: var(--radius-pill);
    background: var(--accent);
    transition: width 0.5s var(--ease), background 0.3s var(--ease);
}

.tile-gauge-bar.is-warning { background: var(--warning); }
.tile-gauge-bar.is-critical { background: var(--critical); }

.tile-value.is-good { color: var(--good-ink); }
.tile-value.is-bad { color: var(--critical); }

/* Прирост за сегодня рядом с крупным числом: мельче, но крупнее подписи —
   иначе у 30-пиксельной цифры он теряется */
.tile-delta {
    margin-left: 8px;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* ── Таблицы ──────────────────────────────────────────────────────────── */

.table-wrap {
    overflow-x: auto;
}

table.data {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

table.data th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface);
    text-align: left;
    padding: 12px 20px;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: -0.005em;
    color: var(--ink-muted);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}

table.data td {
    padding: 14px 20px;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

table.data tbody tr:last-child td {
    border-bottom: none;
}

table.data tbody tr {
    transition: background 0.15s var(--ease);
}

table.data tbody tr:hover {
    background: var(--surface-hover);
}

table.data td.num,
table.data th.num {
    text-align: right;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

table.data tr.is-selected {
    background: var(--accent-wash);
}

/* ── Посты: широкая таблица превращается в карточки на узком экране ────── */

/* фикс-раскладка: колонки не разъезжаются под длинным текстом, таблица всегда
   помещается в карточку, а длинное превью обрезается многоточием */
.data-fixed {
    table-layout: fixed;
}

.posts-cards {
    display: none;
}

@media (max-width: 1200px) {
    .posts-wide {
        display: none;
    }

    .posts-cards {
        display: flex;
        flex-direction: column;
    }

    .post-card {
        display: flex;
        flex-direction: column;
        gap: 10px;
        padding: 15px 16px;
        border-bottom: 1px solid var(--line);
    }

    .post-card:last-child {
        border-bottom: none;
    }

    .post-card-head {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: 10px;
    }

    .post-card-head .row-title {
        font-weight: 600;
    }

    .post-card-body {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 14px;
    }
}

/* ── Реклама: широкая таблица превращается в карточки ─────────────────────
   Порог тот же, что у списка постов (1200px): при открытом сайдбаре
   контенту остаётся меньше 850px, и даже ужатая таблица туда не входит. */

.ads-cards {
    display: none;
}

@media (max-width: 1200px) {
    .ads-wide {
        display: none;
    }

    .ads-cards {
        display: flex;
        flex-direction: column;
    }

    .ad-card {
        display: flex;
        flex-direction: column;
        gap: 12px;
        padding: 15px 16px 16px;
        border-bottom: 1px solid var(--line);
    }

    .ad-card:last-child {
        border-bottom: none;
    }

    /* ── Якорь карточки ──────────────────────────────────────────────
       Пять метрик равного веса не давали ответа на единственный вопрос,
       ради которого сюда заходят с телефона: стопать кампанию или нет.
       CTR вынесен в медальон, заливка повторяет зону вилки, вилка живёт
       прямо под числом — сравнивать приходится не через всю карточку. */
    .ad-card-top {
        display: flex;
        align-items: flex-start;
        gap: 12px;
    }

    .ad-ctr {
        flex: none;
        width: 98px;
        padding: 10px 6px 9px;
        border-radius: 13px;
        text-align: center;
        background: color-mix(in srgb, var(--ink-muted) 9%, transparent);
    }

    .ad-ctr.is-mid { background: color-mix(in srgb, var(--good-ink) 13%, transparent); }
    .ad-ctr.is-high { background: color-mix(in srgb, var(--warning) 15%, transparent); }

    .ad-ctr-num {
        font-size: 22px;
        font-weight: 700;
        line-height: 1;
        letter-spacing: -0.03em;
        font-variant-numeric: tabular-nums;
    }

    .ad-ctr.is-mid .ad-ctr-num { color: var(--good-ink); }
    .ad-ctr.is-high .ad-ctr-num { color: var(--warning); }

    .ad-ctr-pct {
        margin-left: 2px;
        font-size: 11px;
        font-weight: 500;
        letter-spacing: 0;
        color: var(--ink-muted);
    }

    .ad-ctr-none { color: var(--ink-muted); }

    /* вилка внутри медальона — тот же рабочий контрол, ужатый под ширину
       плашки: показать её текстом значило бы завести второй экземпляр
       тех же чисел, а редактировать всё равно надо */
    .ad-ctr-fork { margin-top: 7px; }

    .ad-ctr-fork .ctr-fork {
        gap: 0;
        padding: 1px 3px;
        background: transparent;
    }

    .ad-ctr-fork .ctr-fork input[type="number"] {
        width: 31px;
        padding: 1px 0;
        font-size: 11px;
    }

    .ad-ctr-fork .ctr-fork-sep { font-size: 10.5px; }
    .ad-ctr-fork .ctr-fork-unit { display: none; }

    .ad-card-ident { min-width: 0; padding-top: 1px; }

    .ad-card-ident .row-title {
        font-weight: 600;
        font-size: 15px;
        line-height: 1.32;
    }

    .ad-card-sub {
        margin-top: 4px;
        font-size: 12px;
        color: var(--ink-muted);
    }

    /* метрики второго плана: значение сверху, подпись под ним мелким —
       так подпись не крадёт строку у числа, как в прежней сетке 2×2 */
    .ad-card-metrics {
        display: flex;
        flex-wrap: wrap;
        gap: 9px 18px;
    }

    .ad-metric {
        display: flex;
        flex-direction: column;
        gap: 1px;
    }

    .ad-metric b {
        font-size: 13.5px;
        font-weight: 600;
        font-variant-numeric: tabular-nums;
    }

    .ad-metric > span {
        font-size: 10.5px;
        color: var(--ink-muted);
    }

    .ad-metric-cap { color: var(--ink-muted); font-weight: 500; }

    /* состояние отвечает «идёт или стоит» цветом и точкой: прежде это был
       мелкий текст в общей строке, неразличимый при прокрутке */
    .ad-card-foot {
        display: flex;
        align-items: center;
        gap: 9px;
        flex-wrap: wrap;
    }

    .ad-run {
        display: inline-flex;
        align-items: center;
        gap: 5px;
        padding: 3px 10px;
        border-radius: var(--radius-pill);
        font-size: 11.5px;
        font-weight: 600;
        color: var(--ink-muted);
        background: color-mix(in srgb, var(--ink-muted) 11%, transparent);
    }

    .ad-run.is-play {
        color: var(--good-ink);
        background: color-mix(in srgb, var(--good-ink) 14%, transparent);
    }

    .ad-run.is-alert {
        color: var(--warning);
        background: color-mix(in srgb, var(--warning) 15%, transparent);
    }

    .ad-run-dot {
        flex: none;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: currentColor;
    }

    .ad-card-slot {
        font-family: var(--mono);
        font-size: 11.5px;
        color: var(--ink-muted);
    }

    /* действие во всю ширину: в прежней строке кнопка стояла между ссылкой
       и статусом и была самой мелкой целью на карточке */
    .ad-card-action {
        width: 100%;
        justify-content: center;
    }

    .ad-card-action.is-stop {
        border-color: color-mix(in srgb, var(--warning) 45%, var(--line));
        color: var(--warning);
    }
}

/* планшет и узкий ноутбук: карточка во всю ширину полупустая — ставим по две
   в ряд. Левая карточка отбивается справа, нижняя черта снимается у всего
   последнего ряда — и когда он полный, и когда в нём одна карточка */
@media (min-width: 761px) and (max-width: 1200px) {
    .ads-cards {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .ad-card:nth-child(odd) {
        border-right: 1px solid var(--line);
    }

    .ad-card:nth-last-child(2):nth-child(odd) {
        border-bottom: none;
    }
}

/* Плитки на телефоне вставали в столбик во всю ширину: пять штук съедали
   экран целиком, и до списка приходилось листать. Порог сужен — встают
   по две; правило общее для всех страниц, им это тоже на пользу. */
@media (max-width: 480px) {
    .tiles {
        grid-template-columns: repeat(auto-fit, minmax(min(148px, 100%), 1fr));
        gap: 10px;
    }

    .tile { padding: 13px 14px 15px; }
    .tile-value { margin-top: 7px; font-size: 25px; }
    .tile-unit { font-size: 14px; }

    /* «Доход за сегодня» пятый и остался бы в ряду один: отдаём ему всю
       ширину — у него подпись с разбивкой по аккаунтам, ей нужно место */
    .tiles-ads .tile:last-child { grid-column: 1 / -1; }
}

.mono {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

.muted {
    color: var(--ink-muted);
}

.secondary {
    color: var(--ink-secondary);
}

.small {
    font-size: 12.5px;
}

.truncate {
    display: block;
    max-width: min(38ch, 100%);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.delta-up {
    color: var(--good-ink);
}

.delta-flat {
    color: var(--ink-muted);
}

/* ── Пилюли состояния: фон плюс подпись, никогда только цвет ──────────── */

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 8px;
    border-radius: var(--radius-pill);
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.3;
    white-space: nowrap;
}

.chip::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.chip.is-good {
    color: var(--good-ink);
    background: color-mix(in srgb, var(--good) 14%, transparent);
}

.chip.is-info {
    color: var(--accent);
    background: var(--accent-wash);
}

.chip.is-warning {
    color: var(--serious);
    background: color-mix(in srgb, var(--warning) 18%, transparent);
}

.chip.is-critical {
    color: var(--critical);
    background: color-mix(in srgb, var(--critical) 13%, transparent);
}

.chip.is-neutral {
    color: var(--ink-secondary);
    background: color-mix(in srgb, var(--ink) 7%, transparent);
}

.chip.is-muted {
    color: var(--ink-muted);
    background: color-mix(in srgb, var(--ink) 5%, transparent);
}

/* дополнительные тона подписок — чтобы ряд бейджей не был одноцветным */
.chip.is-violet {
    color: var(--series-7);
    background: color-mix(in srgb, var(--series-7) 15%, transparent);
}

.chip.is-teal {
    color: var(--series-6);
    background: color-mix(in srgb, var(--series-6) 16%, transparent);
}

/* быстрый старт: тёплый оттенок, но не тревожный — это режим, а не предупреждение */
.chip.is-amber {
    color: var(--series-2);
    background: color-mix(in srgb, var(--series-2) 15%, transparent);
}

/* «в Яндексе» — жёлто-янтарный, как фирменный цвет РСЯ */
.chip.is-yandex {
    color: var(--serious);
    background: color-mix(in srgb, var(--warning) 20%, transparent);
}

/* у бейджа с иконкой вместо точки-маркера стоит сам значок */
.chip.has-icon {
    padding-left: 7px;
}

.chip.has-icon::before {
    display: none;
}

.chip svg {
    width: 13px;
    height: 13px;
    flex: none;
}

/* растровый значок в бейдже (лого РСЯ) — круглый, чуть крупнее контурных иконок */
.chip-img {
    width: 15px;
    height: 15px;
    flex: none;
    border-radius: 50%;
    object-fit: cover;
}

/* живой статус «мониторится»: маркер мягко пульсирует, как индикатор записи */
.chip.is-live::before {
    animation: chip-pulse 2s var(--ease) infinite;
}

@keyframes chip-pulse {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--good) 55%, transparent); }
    70% { box-shadow: 0 0 0 5px transparent; }
    100% { box-shadow: 0 0 0 0 transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .chip.is-live::before { animation: none; }
}

/* «ссылка» / «скопировано»: тихая иконочная кнопка, зеленеет на успехе */
.copy-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: none;
    padding: 3px 9px 3px 8px;
    border: none;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 6%, transparent);
    color: var(--ink-muted);
    font-size: 11.5px;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s var(--ease), color 0.15s var(--ease);
}

.copy-link svg {
    width: 12px;
    height: 12px;
    flex: none;
}

.copy-link:hover {
    background: color-mix(in srgb, var(--ink) 10%, transparent);
    color: var(--ink);
}

.copy-link.is-done {
    background: color-mix(in srgb, var(--good) 15%, transparent);
    color: var(--good-ink);
}

.row-title {
    font-weight: 600;
    letter-spacing: -0.012em;
    color: var(--ink);
}

a.row-title:hover {
    color: var(--accent);
    text-decoration: none;
}

/* ── Статусы: точка плюс подпись, никогда только цвет ─────────────────── */

.status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    white-space: nowrap;
}

.status::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.status.is-active { color: var(--good-ink); }
.status.is-paused { color: var(--ink-secondary); }
.status.is-archived { color: var(--ink-muted); }
.status.is-discovered { color: var(--accent); }
.status.is-error { color: var(--critical); }
.status.is-warning { color: var(--serious); }
.status.is-progress { color: var(--accent); }

/* ── Аватар канала ────────────────────────────────────────────────────── */

.avatar {
    position: relative;
    flex: none;
    display: inline-grid;
    place-items: center;
    overflow: hidden;
    border-radius: 50%;
    background: color-mix(in srgb, var(--avatar-tone, var(--accent)) 16%, var(--surface));
    color: var(--avatar-tone, var(--accent));
    box-shadow: inset 0 0 0 1px var(--line);
}

.avatar-initial {
    font-weight: 600;
    line-height: 1;
    user-select: none;
}

/* картинка поверх инициала: не загрузилась — заглушка остаётся видна */
.avatar img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.avatar-row {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
}

/* ── Подтверждение действия ───────────────────────────────────────────── */

.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: grid;
    place-items: center;
    padding: 24px;
    background: rgba(0, 0, 0, 0.32);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    animation: fade 0.2s var(--ease) both;
}

.modal {
    width: 100%;
    max-width: 460px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    animation: pop 0.28s var(--ease) both;
    /* на невысоком телефоне окно не должно упираться кнопками за край экрана */
    max-height: calc(100dvh - 32px);
    display: flex;
    flex-direction: column;
}

.modal-body {
    overflow-y: auto;
}

@keyframes fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes pop {
    from { opacity: 0; transform: translateY(10px) scale(0.97); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .modal-backdrop,
    .modal { animation: none; }
}

.modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--line);
}

.modal-body {
    padding: 18px 20px;
    font-size: 13.5px;
    color: var(--ink-secondary);
    line-height: 1.5;
}

.modal-body strong {
    color: var(--ink);
}

.modal-actions {
    display: flex;
    gap: 8px;
    padding: 16px 20px;
    border-top: 1px solid var(--line);
    background: var(--surface-sunken);
}

/* строки «параметр — значение» в подтверждении */
.summary {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 8px 16px;
    margin: 0;
}

.summary dt {
    color: var(--ink-muted);
    font-size: 12.5px;
}

.summary dd {
    margin: 0;
    text-align: right;
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}

/* ── Плитки каналов на обзоре ─────────────────────────────────────────── */

.channel-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    padding: 16px;
}

@media (max-width: 1180px) {
    .channel-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 680px) {
    .channel-grid { grid-template-columns: 1fr; }
}

/* ── Карточка канала на телефоне ────────────────────────────────────────
   Ширина падает вдвое против планшета, и три блока ломаются каждый по-своему:
   плановая панель роняет рекомендации на вторую строку, оставляя висеть
   вертикальный разделитель посреди пустоты; «Прибыль» уходит в ряд одна и
   половина ряда пустует; заголовок подлезает под уголок РСЯ. Разбираем
   по отдельности, а не общим уменьшением шрифтов. */
@media (max-width: 560px) {
    .channel-grid {
        gap: 12px;
        padding: 12px;
    }

    .channel-card {
        gap: 12px;
        padding: 15px 15px 0;
    }

    /* уголок «в РСЯ» висит абсолютом в правом верхнем углу: на узкой карточке
       заголовок доезжает до него и читается впритык под флажком */
    .v-metrics .avatar-row { padding-right: 32px; }

    /* панель встаёт в две строки. Вертикальная черта между половинами теряет
       смысл — кладём её горизонтально, иначе она торчит хвостом у числа */
    .plan-band {
        flex-direction: column;
        align-items: stretch;
        gap: 9px;
        padding: 11px 13px;
    }

    .plan-note { white-space: normal; }

    .plan-sep {
        width: auto;
        height: 1px;
        align-self: auto;
        background: linear-gradient(90deg,
            transparent,
            color-mix(in srgb, var(--ink) 20%, transparent),
            transparent);
    }

    .plan-vals { gap: 3px 14px; }

    /* «Прибыль» — формула с тремя числами, вдвое длиннее соседей. В половине
       ряда она переносится посреди выражения, поэтому отдаём ей строку */
    .v-metrics .channel-metrics.tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .v-metrics .channel-metrics.tiles > div:last-child {
        grid-column: 1 / -1;
    }

    .channel-metrics.tiles > div { padding: 10px 11px 11px; }

    /* половины 50/50: подписи состояния длинные и переносятся, лишний воздух
       между колонками тут дороже, чем ровный ритм */
    .split-row {
        gap: 8px;
        padding: 8px 10px;
    }

    .split-value { font-size: 14px; }

    .card-badges { gap: 5px; }

    /* спарклайн подрезан по краям карточки — отрицательные поля равны её отступам */
    .channel-spark.band { margin-left: -15px; margin-right: -15px; }
}

/* ── Карточка канала, вариант «Метрики вперёд» ────────────────────────── */

.channel-card.v-metrics {
    position: relative;
    gap: 11px;
    padding-bottom: 0;
}

/* уголок-флажок «в РСЯ»: логотип загнутым краем в правом верхнем углу карточки.
   Ч/б — площадки нет, цветной — есть (ставится вручную или авто по показам) */
.yandex-flag {
    position: absolute;
    top: 0;
    right: 0;
    width: 42px;
    height: 42px;
    padding: 0;
    border: none;
    cursor: pointer;
    display: grid;
    place-items: center;
    /* скруглён под верхний-правый угол карточки, левый-нижний — «загиб» */
    border-radius: 0 var(--radius) 0 16px;
    background: var(--surface-hover);
    box-shadow: -3px 3px 10px -4px rgba(0, 0, 0, 0.5), inset 0 1px 0 var(--card-edge);
    filter: grayscale(1);
    opacity: 0.6;
    transition: filter 0.18s var(--ease), opacity 0.18s var(--ease), transform 0.18s var(--ease);
}

.yandex-flag img {
    width: 21px;
    height: 21px;
    border-radius: 50%;
    display: block;
    /* сдвигаем логотип от угла: там встаёт метка аккаунта */
    transform: translate(-3px, -3px);
}

/* буква партнёрского аккаунта поверх логотипа: белая, с тёмным ореолом —
   читается на разноцветном значке и не мешает клику по флажку */
.yandex-acc {
    position: absolute;
    right: 4px;
    bottom: 4px;
    min-width: 15px;
    height: 15px;
    padding: 0 3px;
    display: grid;
    place-items: center;
    border-radius: 8px;
    font-size: 9.5px;
    font-weight: 700;
    line-height: 1;
    color: var(--ink);
    background: color-mix(in srgb, var(--surface) 88%, var(--ink));
    box-shadow: 0 0 0 1.5px var(--surface-hover), 0 1px 3px rgba(0, 0, 0, 0.45);
    pointer-events: none;
}

.yandex-flag:hover {
    opacity: 0.85;
}

.yandex-flag.on {
    filter: none;
    opacity: 1;
}

.v-metrics .title-yandex {
    width: 16px;
    height: 16px;
    flex: none;
    border-radius: 50%;
}

.v-metrics .meta-line {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 3px;
    font-size: 12px;
    color: var(--ink-muted);
}

.v-metrics .meta-line svg {
    width: 13px;
    height: 13px;
    flex: none;
}

.v-metrics .card-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* метрики в утопленных плитках; прижаты к низу — плитки и график соседних
   карточек встают на один уровень, слабину забирает область бейджей сверху */
.channel-metrics.tiles {
    margin-top: auto;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
}

.channel-metrics.tiles > div {
    padding: 10px 11px 11px;
    background: var(--surface-sunken);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
}

/* ── Рекламные посты: сегодня и вчера ────────────────────────────────────
   Широкая ячейка в ряду метрик, в том же материале. Подпись и числа стоят
   в одну строку, а не столбиком, как в узкой плитке: ширина у ячейки есть,
   и тратить на неё вторую строку незачем — весь смысл был ужать карточку. */
.channel-metrics.tiles > .channel-ads {
    grid-column: 1 / -1;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 11px;
}

.channel-ads-k {
    font-size: 11.5px;
    color: var(--ink-muted);
}

.channel-ads-v {
    font-size: 11px;
    color: var(--ink-muted);
    font-variant-numeric: tabular-nums;
}

/* сегодня — то, ради чего сюда смотрят; вчера рядом как мерка */
.channel-ads-v b {
    margin-right: 4px;
    font-size: 16px;
    font-weight: 650;
    letter-spacing: -0.02em;
    color: var(--ink);
}

.channel-ads-v i {
    margin-right: 4px;
    font-style: normal;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-secondary);
}

.channel-ads-sep {
    margin: 0 6px;
    opacity: 0.45;
}

/* ── Половины 50/50, свёрнутые в строку ──────────────────────────────────
   Когда twiboost отключён и оплаченный пакет доиграл, вторая колонка занимала
   треть блока ради слова «отключён», а три строки подряд — имя, число,
   состояние — держали высоту двухколоночного блока. Оставшаяся половина
   укладывается в одну строку и экономит две. */
.split-row.is-single {
    align-items: baseline;
    gap: 9px;
    padding: 7px 12px;
}

.split-row.is-single .split-value { font-size: 13.5px; }

.split-off {
    margin-left: auto;
    font-size: 10.5px;
    color: var(--ink-muted);
}

/* карточка канала на Обзоре — матовое стекло: полупрозрачная поверхность,
   блюр пропускает амбиентное сияние страницы */
.channel-card.v-metrics {
    background:
        linear-gradient(var(--card-tint-top), var(--card-tint-bottom)),
        color-mix(in srgb, var(--surface) 78%, transparent);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
}

/* канал в РСЯ — ровный тёплый жёлтый подтон фона, перекликается с уголком-флажком.
   Через color-mix работает и в тёмной, и в светлой теме */
.channel-card.v-metrics.in-yandex {
    background:
        linear-gradient(var(--card-tint-top), var(--card-tint-bottom)),
        color-mix(in srgb, #ffc93c 6%, color-mix(in srgb, var(--surface) 78%, transparent));
}

/* без «Расхода» плашек три — одним рядом; на узкой карточке переносятся */
.v-metrics .channel-metrics.tiles {
    grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
}

/* статус кампании кликом: кнопка-обёртка вокруг значка, без своей рамки —
   значок и есть управляющий элемент */
.camp-toggle {
    appearance: none;
    border: none;
    background: none;
    padding: 2px;
    margin: 0;
    cursor: pointer;
    border-radius: var(--radius-sm);
    line-height: 0;
    transition: background 0.18s var(--ease), transform 0.18s var(--ease);
}

.camp-toggle:hover:not(:disabled) {
    background: color-mix(in srgb, var(--ink) 8%, transparent);
    transform: scale(1.08);
}

.camp-toggle:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
    outline-offset: 1px;
}

.camp-toggle:disabled {
    opacity: 0.45;
    cursor: default;
}

@media (prefers-reduced-motion: reduce) {
    .camp-toggle { transition: none; }
    .camp-toggle:hover:not(:disabled) { transform: none; }
}

/* ── Строка провайдеров в режиме 50/50 ───────────────────────────────────
   Половины живут по разным правилам: пакет считается постами, подписка —
   днями. Поэтому у каждой свой столбец со своим состоянием */

.split-row {
    display: flex;
    align-items: stretch;
    gap: 10px;
    padding: 9px 12px;
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--ink) 4%, transparent);
    border: 1px solid var(--line);
}

.split-part {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.split-name {
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

.split-value {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 15px;
    font-weight: 700;
    color: var(--ink);
}

/* номер подписки рядом с провайдером: цифрами, чтобы его можно было сверить
   с кабинетом cheatbot, но тише названия — это опознавательный знак, не метрика */
.split-id {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
    text-transform: none;
    opacity: 0.75;
}

/* половина не работает — ноль виден сразу, без чтения подписи */
.split-value.is-none {
    color: var(--critical);
}

.split-meta {
    font-size: 11px;
    color: var(--ink-muted);
}

.split-meta.is-warn { color: var(--serious); }
.split-meta.is-bad { color: var(--critical); }

/* срок подписки cheatbot — баром: доля срока видна сразу, без пересчёта
   «осталось 3,4 дн» в голове. Заполнение — прошедшая часть, как отдаёт API */
.split-gauge {
    display: block;
    height: 4px;
    margin: 5px 0 4px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 9%, transparent);
    overflow: hidden;
}

.split-gauge-bar {
    display: block;
    height: 100%;
    min-width: 3px;
    border-radius: var(--radius-pill);
    background: var(--good);
    transition: width 0.5s var(--ease), background 0.3s var(--ease);
}

.split-gauge-bar.is-warn { background: var(--warning); }
.split-gauge-bar.is-bad { background: var(--critical); }

/* в свёрнутой строке бар стоит в ряд с числами — фиксированной ширины */
.split-row.is-single .split-gauge {
    flex: none;
    width: 64px;
    margin: 0;
    align-self: center;
}

.split-div {
    width: 1px;
    flex: none;
    background: var(--line);
}

/* ── Сегментированный переключатель: один срез из нескольких ─────────────
   Кнопки живут в общей «капсуле», выбранная поднята подложкой */

.seg {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    border-radius: var(--radius-pill);

    /* утопленная капсула, поднятая кнопка: в светлой теме серый фон и белая
       кнопка, в тёмной — наоборот по светимости, но с тем же рельефом */
    background: var(--surface-sunken);
    border: 1px solid var(--line);

    /* на самом узком экране капсула не ломается, а прокручивается вбок */
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
}

.seg::-webkit-scrollbar {
    display: none;
}

/* шапка карточки с переключателем: на узком экране заголовок, сегменты
   и подпись встают в несколько строк вместо переполнения */
.card-head.is-wrap {
    flex-wrap: wrap;
}

.card-head.is-wrap > .row {
    flex-wrap: wrap;
}

.seg button {
    appearance: none;
    border: none;
    background: transparent;
    color: var(--ink-secondary);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 500;
    padding: 5px 12px;
    border-radius: var(--radius-pill);
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.18s var(--ease), color 0.18s var(--ease);
}

.seg button:hover:not(:disabled):not(.is-on) {
    color: var(--ink);
    background: color-mix(in srgb, var(--ink) 7%, transparent);
}

.seg button:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
    outline-offset: 1px;
}

.seg button.is-on {
    background: var(--surface);
    color: var(--ink);
    box-shadow: var(--shadow-sm), inset 0 1px 0 var(--card-edge);
}

.seg button:disabled {
    opacity: 0.55;
    cursor: default;
}

/* ── Пейджер: назад / где мы в списке / вперёд ── */

.pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 12px 16px 14px;
    border-top: 1px solid var(--line);
}

.pager-note {
    font-size: 12.5px;
    color: var(--ink-muted);
    font-variant-numeric: tabular-nums;
    min-width: 120px;
    text-align: center;
}

/* телефон: сегменты и кнопки листания — под палец, не под курсор */
@media (max-width: 760px) {
    .seg {
        width: 100%;
        justify-content: space-between;
    }

    .seg button {
        flex: 1;
        padding: 9px 10px;
        font-size: 13px;
    }

    .pager {
        gap: 10px;
        padding: 12px 14px 14px;
    }

    .pager .btn {
        min-height: 40px;
        padding-left: 20px;
        padding-right: 20px;
    }

    .pager-note {
        min-width: 0;
        flex: 1;
    }
}

/* ── Плановая панель: база просмотров и рекомендации живого профиля ──────
   Слева линза с объёмом на следующий пост, справа — как выглядел бы
   настоящий канал с такими просмотрами. По базе сортируются плитки */

.plan-band {
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 16px;
    padding: 10px 14px;
    border-radius: var(--radius);
    background: linear-gradient(120deg,
        color-mix(in srgb, var(--accent) 11%, transparent),
        color-mix(in srgb, var(--ink) 5%, transparent) 45%,
        color-mix(in srgb, var(--ink) 3%, transparent));
    border: 1px solid color-mix(in srgb, var(--accent) 18%, var(--line));
    box-shadow:
        inset 0 1px 0 var(--card-edge),
        0 12px 26px -18px color-mix(in srgb, var(--accent) 45%, transparent);
}

.plan-lens {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: none;
}

.plan-value {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 25px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--accent);
    filter: drop-shadow(0 2px 8px color-mix(in srgb, var(--accent) 35%, transparent));
}

.plan-note {
    font-size: 10px;
    color: var(--ink-muted);
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.plan-sep {
    width: 1px;
    align-self: stretch;
    flex: none;
    background: linear-gradient(180deg,
        transparent, color-mix(in srgb, var(--ink) 22%, transparent), transparent);
}

.plan-stats {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1;
    min-width: 0;
}

.plan-cap {
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

.plan-vals {
    display: flex;
    flex-wrap: wrap;
    gap: 3px 16px;
}

.plan-vals > div {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.plan-k {
    font-size: 10.5px;
    color: var(--ink-muted);
}

.plan-s {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink-secondary);
    white-space: nowrap;
}

/* спарклайн — широкой полосой во всю ширину карточки, прижат к низу */
.channel-spark.band {
    margin: 13px -18px 0;
    padding: 13px 18px 15px;
    border-top: 1px solid var(--line);
    background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--accent) 6%, transparent));
}

/* тянем по ширине, высота — по соотношению: без пустых полей по бокам */
.channel-spark.band .spark {
    width: 100%;
    height: auto;
}

.channel-card {
    display: flex;
    flex-direction: column;
    gap: 15px;
    padding: 17px 18px;
    /* чуть светлее внешней карточки-контейнера, чтобы не сливаться с её фоном */
    background:
        linear-gradient(var(--card-tint-top), var(--card-tint-bottom)),
        color-mix(in srgb, var(--surface) 88%, var(--hover));
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm), inset 0 1px 0 var(--card-edge);
    color: inherit;
    text-decoration: none;
    transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease),
                border-color 0.25s var(--ease);
}

.channel-card:hover {
    transform: translateY(-1px);
    border-color: var(--line-strong);
    box-shadow: var(--shadow), inset 0 1px 0 var(--card-edge);
}

@media (prefers-reduced-motion: reduce) {
    .channel-card:hover { transform: none; }
}

.channel-card .btn-icon {
    font-size: 11.5px;
    padding: 3px 9px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 6%, transparent);
    white-space: nowrap;
}

/* мета-строка с иконкой (объём просмотров) — привязана значком к своему бейджу */
.channel-note {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 2px;
    font-size: 12px;
    color: var(--ink-muted);
}

.channel-note svg {
    width: 13px;
    height: 13px;
    flex: none;
}

/* возраст и число постов — отдельная строка-«паспорт» канала, отбита от статуса
   и подписок тонкой чертой, чтобы не мешаться с живыми бейджами */
.channel-age {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    padding-top: 8px;
    border-top: 1px solid var(--line);
    font-size: 12px;
    color: var(--ink-muted);
}

.channel-age svg {
    width: 13px;
    height: 13px;
    flex: none;
}

.channel-metrics {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;

    /* низ карточки прижат: шапка с разным числом бейджей растягивает зазор
       над метриками, и графики соседних карточек остаются на одной линии */
    margin-top: auto;
}

.channel-value {
    margin-top: 4px;
    font-size: 19px;
    font-weight: 600;
    letter-spacing: -0.022em;
    font-variant-numeric: tabular-nums;
}

/* Прибыль: доход − расход = итог. Формула мелко, результат крупно и в цвет */
.channel-value.profit {
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 13px;
    letter-spacing: 0;
    line-height: 1.25;
}

.profit-eq {
    color: var(--ink-muted);
    font-weight: 500;
    white-space: nowrap;
}

.profit-net {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -0.022em;
}

.channel-value.profit.is-plus .profit-net { color: var(--good-ink); }
.channel-value.profit.is-minus .profit-net { color: var(--critical); }

.channel-spark {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-top: 13px;
    border-top: 1px solid var(--line);
}

.channel-spark .spark {
    width: 100%;
    height: auto;
}

@media (max-width: 560px) {
    .channel-metrics {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ── Лента текущих задач канала ───────────────────────────────────────── */

.queue {
    list-style: none;
    margin: 0;
    padding: 0;
}

.queue-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 20px;
    border-bottom: 1px solid var(--line);
    font-size: 13.5px;
}

.queue-item:last-child {
    border-bottom: none;
}

.queue-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: none;
    background: var(--ink-muted);
}

.queue-dot.is-active { background: var(--good); }
.queue-dot.is-progress { background: var(--accent); }
.queue-dot.is-warning { background: var(--warning); }
.queue-dot.is-error { background: var(--critical); }

.queue-dot.is-idle {
    background: transparent;
    box-shadow: inset 0 0 0 1.5px var(--line-strong);
}

.queue-title {
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.queue-progress {
    flex: none;
    width: 96px;
    height: 6px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 9%, transparent);
    overflow: hidden;
}

.queue-progress-bar {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    background: var(--accent);
    transition: width 0.4s var(--ease);
}

/* ── Кнопки ───────────────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 34px;
    padding: 7px 16px;
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    background: color-mix(in srgb, var(--ink) 7%, transparent);
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.4;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.2s var(--ease), transform 0.12s var(--ease),
                box-shadow 0.2s var(--ease), opacity 0.2s var(--ease);
}

.btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--ink) 12%, transparent);
    text-decoration: none;
}

/* нажатие отзывается: кнопка чуть проседает под пальцем */
.btn:active:not(:disabled) {
    transform: scale(0.975);
}

.btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.btn-primary {
    background: var(--accent);
    color: var(--accent-ink);
    box-shadow: var(--btn-glow), 0 1px 2px color-mix(in srgb, var(--accent) 30%, transparent);
}

.btn-primary:hover:not(:disabled) {
    background: var(--accent-hover);
    box-shadow: var(--btn-glow), 0 4px 14px -4px color-mix(in srgb, var(--accent) 65%, transparent);
}

.btn-danger {
    color: var(--critical);
    background: color-mix(in srgb, var(--critical) 12%, transparent);
}

.btn-danger:hover:not(:disabled) {
    background: color-mix(in srgb, var(--critical) 18%, transparent);
}

.btn-ghost {
    background: transparent;
    color: var(--ink-secondary);
    font-weight: 400;
}

.btn-ghost:hover:not(:disabled) {
    background: color-mix(in srgb, var(--ink) 7%, transparent);
    color: var(--ink);
}

.btn-sm {
    min-height: 28px;
    padding: 4px 12px;
    font-size: 12.5px;
}

.btn-link {
    border: none;
    background: none;
    padding: 0;
    color: var(--accent);
    font-family: inherit;
    font-size: 13.5px;
    cursor: pointer;
}

.btn-icon {
    border: none;
    background: none;
    color: var(--ink-muted);
    font-family: inherit;
    font-size: 14px;
    line-height: 1;
    padding: 5px;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background 0.18s var(--ease), color 0.18s var(--ease);
}

.btn-icon:hover {
    background: color-mix(in srgb, var(--ink) 9%, transparent);
    color: var(--ink);
}

.footer-actions form {
    display: contents;
}

/* ── Формы ────────────────────────────────────────────────────────────── */

.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 16px;
}

.field label {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--ink-secondary);
}

.field .hint {
    font-size: 12px;
    color: var(--ink-muted);
    line-height: 1.4;
}

/* поля — утопленные плашки без жёсткой обводки: рамку рисует только фокус.
   input без явного type тоже сюда: Blazor InputText его не проставляет */
input:not([type]),
input[type="text"],
input[type="password"],
input[type="number"],
input[type="url"],
input[type="email"],
input[type="search"],
input[type="tel"],
select,
textarea {
    width: 100%;
    min-height: 38px;
    padding: 9px 13px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--surface-sunken);
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
    transition: background 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

input[type="number"],
input.mono {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

input::placeholder,
textarea::placeholder {
    color: var(--ink-muted);
}

input:not([type]):hover:not(:focus),
input:hover:not(:focus),
select:hover:not(:focus),
textarea:hover:not(:focus) {
    background: color-mix(in srgb, var(--ink) 8%, transparent);
}

input:focus,
select:focus,
textarea:focus {
    outline: none;
    background: var(--surface);
    border-color: var(--accent);
    box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* ── Реклама: таблица размещений ──────────────────────────────────────── */

.ads-wide table.data th {
    text-transform: uppercase;
    font-size: 10.5px;
    letter-spacing: 0.07em;
    font-weight: 600;
    color: var(--ink-muted);
    padding-top: 13px;
    padding-bottom: 13px;
    border-bottom: 1px solid var(--line-strong);
}

.ads-wide table.data td {
    padding-top: 15px;
    padding-bottom: 15px;
}

/* заголовок поста использует освободившееся место, а не жёсткие 38 символов */
.ads-wide .row-title.truncate {
    max-width: min(56ch, 32vw);
}

/* мягкая пометка периода в шапке колонки (напр. «Визиты сегодня») */
.th-note {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 500;
    color: var(--ink-dim, var(--ink-muted));
    opacity: 0.75;
}

/* блок РСЯ (клики → CPMV) и ссылки отбиты тонкой линией — данные сгруппированы */
.ads-wide table.data th.col-group,
.ads-wide table.data td.col-group {
    border-left: 1px solid var(--line);
}

/* CTR — ключевая колонка: лёгкая подсветка на всю высоту */
.ads-wide table.data th.col-ctr,
.ads-wide table.data td.col-ctr {
    background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}

.ads-wide table.data tbody tr:hover td.col-ctr {
    background: color-mix(in srgb, var(--accent) 12%, var(--surface));
}

/* штатная остановка кампании (порог CTR достигнут) — спокойный, не тревожный тон */
.camp-ok {
    color: var(--good-ink);
    opacity: 0.85;
}

/* колонка «Статус»: крупный полупрозрачный значок плей/пауза */
.ads-wide table.data th.col-status,
.ads-wide table.data td.col-status {
    width: 1%;
    text-align: center;
    padding-left: 20px;
    padding-right: 8px;
}

/* на мониторе CPMV живёт в своей колонке, подстрочник под доходом не нужен */
.cpmv-inline {
    display: none;
}

/* ── Ноутбук: девять колонок не влезают в ~1000px и правый край срезался ──
   Таблицу не прячем и не отдаём под прокрутку: ужимаем поля ячеек, подписи
   в шапке переносим на вторую строку, заголовок поста режем короче, а CPMV
   переезжает подстрочником под доход — колонок становится восемь. */
@media (max-width: 1600px) {
    .ads-wide table.data {
        font-size: 13px;
    }

    .ads-wide table.data th,
    .ads-wide table.data td {
        padding-left: 12px;
        padding-right: 12px;
    }

    .ads-wide table.data th.col-status,
    .ads-wide table.data td.col-status {
        padding-left: 14px;
        padding-right: 4px;
    }

    /* подпись уходит на вторую строку; остальные заголовки прижаты к низу,
       чтобы стоять с ней на одной линии */
    .ads-wide table.data th {
        vertical-align: bottom;
    }

    .ads-wide .th-note {
        display: block;
        margin-top: 2px;
    }

    .ads-wide .row-title.truncate {
        max-width: min(36ch, 19vw);
    }

    .ads-wide .camp-id {
        max-width: 130px;
    }

    .ads-wide .ctr-fork {
        padding: 3px 6px;
    }

    .ads-wide .ctr-fork input[type="number"] {
        width: 32px;
        font-size: 12px;
    }

    .ads-wide .ctr-value {
        font-size: 14px;
    }

    .ads-wide .col-cpmv {
        display: none;
    }

    .ads-wide .cpmv-inline {
        display: inline;
        white-space: nowrap;
    }
}

.camp-icon {
    width: 26px;
    height: 26px;
    display: inline-block;
    vertical-align: middle;
}

.camp-icon.is-play {
    color: var(--good);
    opacity: 0.5;
}

.camp-icon.is-pause {
    color: var(--ink-muted);
    opacity: 0.45;
}

/* аварийная остановка (скачок сегодняшнего CTR) — красная пауза, заметнее */
.camp-icon.is-alert {
    color: var(--critical);
    opacity: 0.85;
}

.camp-alert {
    color: var(--critical);
    font-weight: 600;
}

/* сегодняшний CTR справочно под средним; краснеет при аварийном скачке */
.ctr-today {
    font-size: 11px;
    font-weight: 500;
    color: var(--ink-dim, var(--ink-muted));
    letter-spacing: 0;
}

.ctr-today.is-hot {
    color: var(--critical);
    font-weight: 700;
}

.ctr-today-label {
    text-transform: uppercase;
    font-size: 9px;
    letter-spacing: 0.06em;
    opacity: 0.7;
    margin-right: 1px;
}

/* ячейка «Кампания»: id слота → статус + время последней сверки */
.camp {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.camp-id {
    font-size: 12px;
    max-width: 200px;
}

.camp-status {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 12.5px;
}

.poll-time {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--ink-dim, var(--ink-muted));
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.poll-time svg {
    width: 12px;
    height: 12px;
    opacity: 0.75;
}

/* визиты за сегодня: значение + приглушённый дневной лимит */
.visits {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.visits-cap {
    color: var(--ink-dim, var(--ink-muted));
    margin-left: 4px;
    font-weight: 400;
}

.ctr-value {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    font-size: 14.5px;
    font-weight: 650;
    letter-spacing: -0.01em;
}

.ctr-value .ctr-pct {
    margin-left: 1px;
    font-size: 11px;
    font-weight: 500;
    color: var(--ink-muted);
}

/* статус-точка: где средний CTR относительно вилки */
.ctr-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: none;
    align-self: center;
    background: var(--ink-muted);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink-muted) 14%, transparent);
}

.ctr-dot.is-mid {
    background: var(--good-ink);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--good-ink) 16%, transparent);
}

.ctr-dot.is-high {
    background: var(--warning);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning) 18%, transparent);
}

.ctr-dot.is-low {
    background: var(--ink-muted);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink-muted) 12%, transparent);
}

/* ── Вилка CTR: два поля в одной пилюле, фокус подсвечивает группу ────── */

.ctr-fork {
    display: inline-flex;
    align-items: center;
    gap: 1px;
    padding: 3px 9px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    transition: background 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

.ctr-fork:hover {
    background: color-mix(in srgb, var(--ink) 8%, transparent);
}

.ctr-fork:focus-within {
    background: var(--surface);
    box-shadow: 0 0 0 1px var(--accent),
        0 0 0 3.5px color-mix(in srgb, var(--accent) 22%, transparent);
}

.ctr-fork input[type="number"] {
    width: 40px;
    min-height: 0;
    padding: 2px 0;
    border: none;
    border-radius: 0;
    background: transparent;
    font-size: 12.5px;
    text-align: center;
    appearance: textfield;
    -moz-appearance: textfield;
}

.ctr-fork input[type="number"]:hover,
.ctr-fork input[type="number"]:focus {
    background: transparent;
    border: none;
    box-shadow: none;
}

.ctr-fork input::-webkit-outer-spin-button,
.ctr-fork input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.ctr-fork-sep {
    color: var(--ink-muted);
    font-size: 12px;
    user-select: none;
}

.ctr-fork-unit {
    color: var(--ink-muted);
    font-size: 11.5px;
    margin-left: 3px;
    user-select: none;
}

.checkbox {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-size: 13.5px;
    margin-bottom: 12px;
}

.checkbox input {
    margin-top: 3px;
    accent-color: var(--accent);
}

/* выбор режима: варианты видны целиком, а не спрятаны в выпадающий список */
.modes {
    display: grid;
    gap: 9px;
    margin-bottom: 16px;
}

.mode {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 13px 15px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
    transition: border-color 0.2s var(--ease), background 0.2s var(--ease),
                box-shadow 0.2s var(--ease);
}

.mode:hover {
    border-color: var(--line-strong);
    background: var(--surface-hover);
}

.mode.is-active {
    border-color: var(--accent);
    background: var(--accent-wash);
    box-shadow: 0 0 0 1px var(--accent) inset;
}

.mode input {
    margin-top: 2px;
    flex: none;
    accent-color: var(--accent);
}

.mode-title {
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.mode-note {
    font-size: 12.5px;
    color: var(--ink-secondary);
    line-height: 1.45;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
    gap: 0 18px;
}

.form-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    padding-top: 8px;
}

/* ── Сообщения ────────────────────────────────────────────────────────── */

.notice {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 14px 17px;
    border-radius: var(--radius);
    background: var(--surface);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-sm);
    font-size: 13.5px;
    line-height: 1.45;
    margin-bottom: 16px;
}

.notice-icon {
    flex: none;
    width: 20px;
    height: 20px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 700;
    color: #fff;
    background: var(--ink-muted);
}

.notice.is-good { background: color-mix(in srgb, var(--good) 7%, var(--surface)); }
.notice.is-good .notice-icon { background: var(--good); }

.notice.is-warning { background: color-mix(in srgb, var(--warning) 10%, var(--surface)); }
.notice.is-warning .notice-icon { background: var(--serious); }

.notice.is-critical { background: color-mix(in srgb, var(--critical) 8%, var(--surface)); }
.notice.is-critical .notice-icon { background: var(--critical); }

.notice.is-info { background: color-mix(in srgb, var(--accent) 7%, var(--surface)); }
.notice.is-info .notice-icon { background: var(--accent); }

.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 56px 20px;
    text-align: center;
    color: var(--ink-muted);
    font-size: 13.5px;
    line-height: 1.6;
    max-width: 52ch;
    margin: 0 auto;
}

/* знак вместо пустоты: место, где ничего нет, всё равно должно выглядеть законченным */
.empty-icon {
    width: 44px;
    height: 44px;
    margin-bottom: 6px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: color-mix(in srgb, var(--ink) 5%, transparent);
    color: var(--ink-muted);
}

.empty-icon svg {
    width: 21px;
    height: 21px;
}

.empty-title {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.012em;
    color: var(--ink);
}

/* полоска профиля в таблице наращивания: форму ряда видно, не выходя в график */
.bar {
    display: inline-block;
    height: 6px;
    min-width: 4px;
    border-radius: var(--radius-pill);
    background: var(--accent);
    opacity: 0.55;
}

tr.is-muted-row {
    opacity: 0.5;
}

/* ── Всплывающие уведомления ──────────────────────────────────────────── */

.toast-host {
    position: fixed;
    right: 22px;
    bottom: 22px;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}

.toast {
    display: flex;
    align-items: center;
    gap: 11px;
    max-width: 420px;
    padding: 13px 14px 13px 16px;
    border-radius: var(--radius);
    background: var(--surface-veil);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-lg);
    font-size: 13.5px;
    line-height: 1.4;
    pointer-events: auto;
    animation: toast-in 0.34s var(--ease) both;
}

.toast-text {
    flex: 1;
    min-width: 0;
}

.toast .notice-icon {
    background: var(--good);
}

.toast.is-critical .notice-icon {
    background: var(--critical);
}

@keyframes toast-in {
    from { opacity: 0; transform: translateY(14px) scale(0.97); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .toast { animation: none; }
}

@media (max-width: 560px) {
    .toast-host {
        right: 12px;
        left: 12px;
        bottom: 12px;
    }
}

/* ── Загрузка ─────────────────────────────────────────────────────────── */

/* обновление данных не должно выглядеть зависанием: содержимое гаснет,
   клики по нему не проходят, пока цифры не пересчитаны */
.is-loading {
    opacity: 0.5;
    pointer-events: none;
    transition: opacity 0.25s var(--ease);
}

.skeleton {
    border-radius: var(--radius);
    background: linear-gradient(100deg,
        color-mix(in srgb, var(--ink) 6%, transparent) 30%,
        color-mix(in srgb, var(--ink) 11%, transparent) 50%,
        color-mix(in srgb, var(--ink) 6%, transparent) 70%);
    background-size: 300% 100%;
    animation: shimmer 1.6s linear infinite;
}

@keyframes shimmer {
    from { background-position: 150% 0; }
    to { background-position: -150% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .skeleton { animation: none; }
}

/* ── Мелкая отделка ───────────────────────────────────────────────────── */

::selection {
    background: color-mix(in srgb, var(--accent) 24%, transparent);
}

* {
    scrollbar-width: thin;
    scrollbar-color: var(--line-strong) transparent;
}

*::-webkit-scrollbar {
    width: 11px;
    height: 11px;
}

*::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border-radius: var(--radius-pill);
    border: 3px solid transparent;
    background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover {
    background: var(--ink-muted);
    background-clip: content-box;
}

*::-webkit-scrollbar-track {
    background: transparent;
}

/* стрелка селекта рисуется фоном: системная выглядит инородно рядом с полями */
select {
    appearance: none;
    padding-right: 32px;
    background-image: linear-gradient(45deg, transparent 50%, var(--ink-muted) 50%),
                      linear-gradient(135deg, var(--ink-muted) 50%, transparent 50%);
    background-position: calc(100% - 16px) center, calc(100% - 11px) center;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    cursor: pointer;
}

/* цифры в таблицах не должны «прыгать» при обновлении данных */
table.data td.num,
.tile-value,
.channel-value,
.mono {
    font-feature-settings: "tnum" 1;
}

/* ── Графики ──────────────────────────────────────────────────────────── */

.chart {
    width: 100%;
    height: auto;
    display: block;
}

/* слой наведения без JS: полоса-цель показывает перекрестье и значение */
.chart .hit .crosshair,
.chart .hit .hit-dot,
.chart .hit .tip {
    opacity: 0;
    transition: opacity 0.15s var(--ease);
    pointer-events: none;
}

.chart .hit:hover .crosshair,
.chart .hit:hover .hit-dot,
.chart .hit:hover .tip {
    opacity: 1;
}

.chart .hit .crosshair {
    stroke: var(--line-strong);
    stroke-width: 1;
    stroke-dasharray: 3 3;
}

.chart .hit .tip rect {
    fill: var(--surface);
    stroke: var(--line-strong);
    stroke-width: 1;
}

.chart .hit .tip text {
    fill: var(--ink-secondary);
    font-size: 11px;
    font-family: var(--sans);
}

.chart .hit .tip .tip-title {
    fill: var(--ink);
    font-weight: 600;
}

.chart .hit .tip .tip-value {
    fill: var(--ink);
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

.chart .grid-line {
    stroke: var(--grid);
    stroke-width: 1;
}

.chart .axis-line {
    stroke: var(--line);
    stroke-width: 1;
}

.chart .tick {
    fill: var(--ink-muted);
    font-size: 10px;
    font-family: var(--mono);
}

.chart .series {
    fill: none;
    stroke-width: 2.25;
    stroke-linejoin: round;
    stroke-linecap: round;
    /* линия прочерчивается при появлении: взгляд идёт по ней слева направо,
       то есть по направлению времени */
    stroke-dasharray: 4000;
    stroke-dashoffset: 4000;
    animation: draw 1.1s var(--ease) forwards;
}

.chart .series-area {
    stroke: none;
    animation: fade 0.9s var(--ease) 0.25s both;
}

@keyframes draw {
    to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .chart .series {
        stroke-dasharray: none;
        stroke-dashoffset: 0;
        animation: none;
    }

    .chart .series-area { animation: none; }
}

.chart .series-fit {
    fill: none;
    stroke-width: 1.5;
    stroke-dasharray: 4 4;
    opacity: 0.8;
}

.chart .marker {
    stroke: var(--surface);
    stroke-width: 2;
}

.legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    padding: 12px 20px 0;
    font-size: 12.5px;
    color: var(--ink-secondary);
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.legend-swatch {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    flex: none;
}

.spark {
    display: block;
}

.spark path {
    fill: none;
    stroke: var(--accent);
    stroke-width: 1.75;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.spark .spark-area {
    fill: var(--accent-wash);
    stroke: none;
}

/* акцентная точка на конце ленты с мягким ореолом — «живой» финал кривой */
.spark-end {
    fill: var(--accent);
}

.spark-end-glow {
    fill: var(--accent);
    opacity: 0.25;
}

.spark.is-flat .spark-end,
.spark.is-flat .spark-end-glow {
    display: none;
}

/* спарк-лента живёт внутри карточки: её линия тоньше, чем у большого графика */
.spark path {
    vector-effect: non-scaling-stroke;
}

.spark.is-flat path {
    stroke: var(--ink-muted);
}

/* ── Вход ─────────────────────────────────────────────────────────────── */

/* вход — единственная страница без данных: её держат свет и воздух */
.login-page {
    position: relative;
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 24px;
    background: var(--page);
    overflow: hidden;
}

/* два пятна разной температуры: одно свечение выглядит плоским фильтром */
.login-page::before,
.login-page::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
    filter: blur(10px);
}

.login-page::before {
    top: -34vh;
    left: 50%;
    width: 96vmax;
    height: 72vmax;
    transform: translateX(-55%);
    background: radial-gradient(closest-side,
        color-mix(in srgb, var(--accent) 26%, transparent),
        transparent 72%);
}

.login-page::after {
    bottom: -40vh;
    right: -10vw;
    width: 74vmax;
    height: 58vmax;
    background: radial-gradient(closest-side,
        color-mix(in srgb, var(--series-7) 16%, transparent),
        transparent 70%);
}

.login-card {
    position: relative;
    max-width: 372px;
    padding: 34px 32px 30px;
    border-radius: 22px;
    /* карточка на светящемся фоне держится матовым стеклом, а не плотной заливкой */
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: saturate(180%) blur(24px);
    -webkit-backdrop-filter: saturate(180%) blur(24px);
    border: 1px solid color-mix(in srgb, var(--surface) 60%, var(--line));
}

.login-head {
    display: flex;
    align-items: center;
    gap: 13px;
    margin-bottom: 22px;
}

.login-glyph {
    width: 46px;
    height: 46px;
    border-radius: 13px;
}

.login-glyph svg {
    width: 25px;
    height: 25px;
}

.login-title {
    font-size: 26px;
    letter-spacing: -0.026em;
    margin-bottom: 24px;
}

.login-card .btn-primary {
    width: 100%;
    min-height: 44px;
    margin-top: 4px;
    font-size: 14.5px;
}

.login-foot {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
    font-size: 12px;
    color: var(--ink-muted);
    text-align: center;
}

.login-card {
    width: 100%;
    max-width: 360px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 30px 28px;
    box-shadow: var(--shadow-lg);
}

.login-brand {
    font-family: var(--mono);
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.02em;
    text-transform: lowercase;
    color: var(--ink);
}

.validation-message,
.error-text,
.text-danger {
    color: var(--critical);
    font-size: 12.5px;
}

/* ── Мелочи ───────────────────────────────────────────────────────────── */

.row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.stack {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.split {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}

/* очень широкий монитор: плитки и карточки становятся крупнее, а не множатся
   в узкие столбики — числа на дашборде читают издалека */
@media (min-width: 1700px) {
    .main {
        padding: 26px 40px 90px;
    }

    .page-head {
        margin: -26px -40px 26px;
        padding: 26px 40px 20px;
    }

    .tiles {
        grid-template-columns: repeat(auto-fit, minmax(min(215px, 100%), 1fr));
        gap: 16px;
    }

    .tile {
        padding: 18px 20px 20px;
    }

    .tile-value {
        font-size: 33px;
    }

    /* на широком экране держим те же три колонки — карточки просто крупнее */
    .channel-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 16px;
        padding: 18px;
    }

    h1 {
        font-size: 33px;
    }

    /* график во всю ширину такой колонки становится слишком низким по пропорции —
       держим его ближе к золотому сечению */
    .chart {
        max-height: 460px;
    }
}

/* мониторы 2K и выше: колонка контента ещё шире, поля остаются симметричными */
@media (min-width: 2100px) {
    .main {
        max-width: 1760px;
    }
}

.pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--ink) 7%, transparent);
    font-size: 11.5px;
    color: var(--ink-secondary);
    font-family: var(--mono);
}

@media (max-width: 980px) {
    .shell {
        grid-template-columns: 1fr;
    }

    /* панель уходит за левый край и выезжает поверх содержимого */
    .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 40;
        width: 280px;
        height: 100dvh;
        transform: translateX(-100%);
        transition: transform 0.32s var(--ease);
        box-shadow: var(--shadow-lg);

        /* на телефонах с домашней полосой нижний пункт иначе оказывается под ней */
        padding-bottom: max(18px, env(safe-area-inset-bottom));
    }

    .sidebar.is-open {
        transform: none;
    }

    @media (prefers-reduced-motion: reduce) {
        .sidebar { transition: none; }
    }

    /* ниже шапки (30): кнопка «Закрыть» должна оставаться нажимаемой при открытом меню */
    .nav-scrim {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 29;
        background: rgba(0, 0, 0, 0.32);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
        animation: fade 0.2s var(--ease) both;
    }

    .mobile-bar {
        position: sticky;
        top: 0;
        z-index: 30;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 10px 16px;
        background: color-mix(in srgb, var(--page) 80%, transparent);
        backdrop-filter: saturate(180%) blur(20px);
        -webkit-backdrop-filter: saturate(180%) blur(20px);
        border-bottom: 1px solid var(--line);
    }

    .mobile-bar .brand {
        padding: 0;
        gap: 10px;
    }

    .mobile-bar .brand-glyph {
        width: 30px;
        height: 30px;
        border-radius: 9px;
    }

    .mobile-bar .brand-glyph svg {
        width: 17px;
        height: 17px;
    }

    .main {
        padding: 18px 16px 60px;
        max-width: none;
    }

    .page-head {
        margin: 0 0 18px;
        padding: 0 0 16px;
        background: transparent;
    }

    h1 {
        font-size: 26px;
    }

    .split {
        grid-template-columns: 1fr;
    }

    .channel-grid {
        padding: 12px;
        gap: 12px;
    }
}

/* телефон: те же блоки, но без разгона по отступам */
@media (max-width: 640px) {
    .main {
        padding: 14px 12px 48px;
    }

    h1 {
        font-size: 23px;
    }

    .page-subtitle {
        font-size: 13px;
    }

    .card-body {
        padding: 14px;
    }

    /* заголовок и подпись в одной строке ломают друг друга: разводим по строкам */
    .card-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
        padding: 14px;
    }

    .card-head h2 {
        white-space: nowrap;
    }

    .modal-head,
    .modal-body,
    .modal-actions {
        padding: 14px 16px;
    }

    table.data th {
        padding: 10px 14px;
    }

    table.data td {
        padding: 12px 14px;
    }

    .legend {
        padding: 10px 14px 0;
    }

    .tiles {
        gap: 10px;
    }

    .tile {
        padding: 14px 15px 15px;
    }

    .tile-value {
        font-size: 26px;
    }

    /* кнопки в строке действий тянутся на всю ширину: попасть пальцем проще */
    .form-actions,
    .modal-actions {
        flex-wrap: wrap;
    }

    .form-actions .btn,
    .modal-actions .btn {
        flex: 1 1 auto;
    }

    .toolbar {
        width: 100%;
    }

    /* палец — не курсор: на телефоне цели нажатия подрастают до пригодных */
    .btn {
        min-height: 42px;
        padding: 9px 18px;
    }

    .btn-sm {
        min-height: 36px;
        padding: 6px 14px;
        font-size: 13px;
    }

    .btn-icon {
        min-height: 36px;
        min-width: 36px;
        padding: 8px;
    }

    .channel-card .btn-icon {
        min-height: 32px;
        padding: 6px 12px;
    }

    .tab {
        min-height: 38px;
        padding: 8px 14px;
    }

    .nav-link {
        padding: 11px 12px;
    }

    /* поля крупнее шрифтом: 16 px не дают iOS зумить страницу при фокусе */
    input:not([type]),
    input[type="text"],
    input[type="password"],
    input[type="number"],
    input[type="url"],
    input[type="email"],
    select,
    textarea {
        min-height: 44px;
        font-size: 16px;
    }
}
