/* AdverTele cabinet — design system.
 *
 * [2026-09-28] Colour and shape are nativad.com's (see the block right below):
 * Telegram decides only whether the light or the dark face is shown. Grouped rows
 * with hairline separators stay, drawn the way the site draws its cabinet mock-ups.
 *
 * Rules kept throughout, and each one was broken by the first version:
 *   - one screen, one job: a list row opens a screen, it does not unfold in place;
 *   - a field must look like a field — label, placeholder, its own row;
 *   - nothing tappable under 44px;
 *   - a destructive action never stands in a row with ordinary ones;
 *   - no zeros where there is nothing to count yet.
 */

/* [2026-09-28] The nativad.com style, both faces of it.
   Владелец: «у нас по сути теперь есть стиль на сайте для чёрной и светлой темы… не
   просто палитра, там много чего сделано… даже есть примеры интерфейса, так что вполне
   можно сделать всё ровно, чётко, стильно». Colours, buttons, radii and lists follow
   site/assets/site.css and its cabinet mock-ups (block «Всё на виду»): a white or black
   page, groups in --bg-2, a yellow button with black ink, gold for text accents in the
   light face and yellow in the dark one.
   Until today every colour here was Telegram's theme (--tg-theme-*). Telegram now only
   decides WHICH face: assets/js/theme.js sets data-theme from WebApp.colorScheme inside
   Telegram, and leaves «auto» (the system) in a browser.
   The variable names stay as they were, because 170 rules read them:
     --bg-secondary  the page ground (site --bg)
     --section       a group or a card (site --bg-2)
     --accent        brand colour for text and icons (site --accent)
     --btn/--btn-ink the filled button (site --btn/--btn-ink) */
:root, [data-theme="light"], [data-theme="auto"] {
    --bg: #ffffff;
    --bg-secondary: #ffffff;
    --section: #f5f5f4;
    --seg-on: #ffffff;
    --text: #0a0a0a;
    --text-2: #45443f;
    --text-3: #66655f;
    --hint: #66655f;
    --caption: #66655f;
    --subtitle: #66655f;
    --separator: #e7e6e3;
    --link: #7a5c00;
    --accent: #7a5c00;
    --accent-soft: #fff6d1;
    --accent-text: #0a0a0a;
    --btn: #FFCC00;
    --btn-ink: #0a0a0a;
    --btn-active: #e6b800;
    --ok: #147a39;
    --ok-soft: #e8f6ed;
    --warn: #a15c00;
    --warn-soft: #fdf1df;
    --danger: #c92a2a;
    --danger-soft: #fdecec;
    --focus: #0a0a0a;
    --card-edge: none;
    color-scheme: light;
}
[data-theme="dark"] {
    --bg: #0a0a0a;
    --bg-secondary: #0a0a0a;
    --section: #141414;
    --seg-on: #262626;
    --text: #f5f5f5;
    --text-2: #bdbdbd;
    --text-3: #949494;
    --hint: #949494;
    --caption: #949494;
    --subtitle: #949494;
    --separator: #262626;
    --link: #FFCC00;
    --accent: #FFCC00;
    --accent-soft: #2a2200;
    --ok: #4ade80;
    --ok-soft: #0f2618;
    --warn: #fbbf24;
    --warn-soft: #2a1f05;
    --danger: #ff8787;
    --danger-soft: #2e1414;
    --focus: #FFCC00;
    --card-edge: 0 0 0 1px #262626;
    color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
    [data-theme="auto"] {
        --bg: #0a0a0a;
        --bg-secondary: #0a0a0a;
        --section: #141414;
        --seg-on: #262626;
        --text: #f5f5f5;
        --text-2: #bdbdbd;
        --text-3: #949494;
        --hint: #949494;
        --caption: #949494;
        --subtitle: #949494;
        --separator: #262626;
        --link: #FFCC00;
        --accent: #FFCC00;
        --accent-soft: #2a2200;
        --ok: #4ade80;
        --ok-soft: #0f2618;
        --warn: #fbbf24;
        --warn-soft: #2a1f05;
        --danger: #ff8787;
        --danger-soft: #2e1414;
        --focus: #FFCC00;
        --card-edge: 0 0 0 1px #262626;
        color-scheme: dark;
    }
}
:root {
    /* A quarter of the text colour mixed into a link or a warning keeps it readable on
       either ground: darker on white, lighter on black. */
    --link-strong: color-mix(in srgb, var(--link) 75%, var(--text));
    --danger-strong: color-mix(in srgb, var(--danger) 80%, var(--text));
    /* Site radii: 14 for buttons and lists, 20 for cards. */
    --radius: 14px;
    --radius-card: 20px;
    --safe-bottom: var(--tg-safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
}

/* [2026-09-23] Inter, drawn for screen interfaces rather than for reading prose:
   tall lowercase so 13px captions stay legible, and — the reason it matters here —
   tabular figures, so a column of sums does not jitter as the digits change. Four
   weights, taken from our own payinbot rather than pulled off a CDN: no third-party
   request on every open, nothing to break when somebody else's server does.
   The system stack stays first in the fallback while they load. */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap; src: url('/app/assets/fonts/Inter-Regular.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap; src: url('/app/assets/fonts/Inter-Medium.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap; src: url('/app/assets/fonts/Inter-SemiBold.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap; src: url('/app/assets/fonts/Inter-Bold.woff2') format('woff2'); }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Icons come from the sprite shared with rentoplan (Phosphor, ids i-<name>). They
   are drawn in currentColor, so an icon is always the colour of the text it sits
   beside — one rule instead of a colour per place. */
.ic { width: 22px; height: 22px; flex-shrink: 0; fill: currentColor; vertical-align: -.15em; }
.ic--lg { width: 26px; height: 26px; }

/* Anything the script hides must actually disappear: a display in a class beats
   the browser's own rule for [hidden], and that once left the sign-in screen lying
   on top of a cabinet that had already loaded. */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--bg-secondary);
    color: var(--text);
    font: 16px/1.5 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    font-feature-settings: 'cv11' 1;   /* [2026-09-28] the site's single-storey a */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-text-size-adjust: 100%;
}
button, input, select, textarea { font: inherit; color: inherit; }
/* [2026-09-28] The site's focus ring: ink on the light face, yellow on the dark one. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

.app { display: flex; flex-direction: column; min-height: 100vh; }
.screens { flex-grow: 1; padding-bottom: 24px; }
.screen { padding: 8px 0 0; }
.screen--chat { display: flex; flex-direction: column; min-height: calc(100vh - 56px); }

.screen__title { margin: 8px 16px 4px; font-size: 28px; line-height: 1.12; font-weight: 700; letter-spacing: -.025em; text-wrap: balance; }
/* [2026-09-23] Название канала пишут без пробелов, например
   «Халява,Заработок,Схемы,Обмен,Купи,Продай», и такое «слово» вылезало за край
   экрана: браузеру негде перенести. Рвём где угодно везде, где показываем чужое
   название. */
.screen__title, .itemrow__title, .reprow__title, .row__title, .row__sub, .card__title,
.bubble__header, .bubble__text { overflow-wrap: anywhere; }
.screen__lead { margin: 0 16px 16px; font-size: 15px; line-height: 1.5; color: var(--text-2); max-width: 34em; text-wrap: pretty; }
.screen__title + .section, .screen__title + .list { margin-top: 16px; }

/* --- hints ---------------------------------------------------------------- */

/* A small round question mark next to a caption; tapping it opens two lines of
   plain words. Kept out of sight until asked for: explaining everything at once
   turns a screen into a manual, explaining nothing leaves people guessing. */
.hint {
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0; width: 18px; height: 18px; padding: 0;
    border: 0; border-radius: 50%; background: var(--separator); color: var(--hint);
    font-size: 11px; font-weight: 700; line-height: 1; cursor: pointer;
}
.hint .ic { width: 12px; height: 12px; }
.section__hint {
    margin: 6px 16px 8px; padding: 10px 12px;
    border-radius: 10px; background: var(--section);
    font-size: 13px; line-height: 1.5; color: var(--text-3);
}

/* --- groups --------------------------------------------------------------- */

.section { margin: 0 0 24px; }
/* [2026-09-23] Заголовок группы это флекс со своим значком вопроса: раньше
   кружок сидел на базовой линии текста и съезжал вниз тем сильнее, чем крупнее
   был заголовок. Теперь он центрируется по строке и не зависит от подгонки. */
.section__title { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; padding: 0 16px; font-size: 17px; font-weight: 600; letter-spacing: -.01em; color: var(--text); }
.section__note { margin: 8px 16px 0; font-size: 13px; line-height: 1.5; color: var(--text-3); max-width: 34em; }
.section__note--above { margin: 0 16px 8px; }
.section__action {
    display: flex; align-items: center; gap: 10px;
    width: calc(100% - 32px); min-height: 48px; margin: 8px 16px 0; padding: 12px 16px;
    border: 0; border-radius: var(--radius); background: var(--section);
    color: var(--link-strong); font-size: 16px; font-weight: 600; text-align: left; cursor: pointer;
}

/* [2026-09-22] Side margins. Groups sit inset from the screen edge, the way every
   settings list does — without it the app reads as a wall of text pressed into the
   glass, which is exactly how it looked. */
.rows { margin: 0 16px; background: var(--section); border-radius: var(--radius); overflow: hidden; box-shadow: var(--card-edge); }
/* A list still waiting for its rows must not show up as a stray hairline. */
.rows:empty { box-shadow: none; }

.row {
    display: flex; align-items: center; gap: 10px;
    width: 100%; min-height: 52px; padding: 12px 16px;
    border: 0; background: transparent; color: inherit; text-align: left; cursor: pointer;
}
.row + .row, .row + .field, .field + .field, .field + .row { box-shadow: inset 0 1px 0 var(--separator); }
/* Every tap gets an answer: without it a list feels dead on a phone. */
.row:active, .role:active, .topup:active, .btn:active, .bigbtn:active, .ask__hint:active { filter: brightness(.94); }
.row > .ic:first-child { color: var(--hint); align-self: flex-start; margin-top: 1px; }
.row { align-items: center; }
.row:has(.row__sub) { align-items: flex-start; }
.row:has(.row__sub) .row__chevron, .row:has(.row__sub) .row__value, .row:has(.row__sub) .row__status { margin-top: 2px; }
.row__body { flex-grow: 1; min-width: 0; }
.row__title { display: block; font-size: 16px; font-weight: 500; line-height: 1.35; }
.row__sub { display: block; margin-top: 2px; font-size: 13px; line-height: 1.4; font-weight: 400; color: var(--text-3); }
.row__value { flex-shrink: 0; font-size: 16px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.row__status { flex-shrink: 0; font-size: 13px; color: var(--text-3); }
.row__status.is-active { color: var(--ok); }
.row__status.is-moderation { color: var(--warn); }
.row__status.is-rejected, .row__status.is-banned { color: var(--danger-strong); }
/* [2026-09-23] Непрозрачность поднята после замера. Норма WCAG для графики 3:1,
   а было: стрелка .45 давала 1.81 на белом и 2.40 на тёмном, значок метрики .6
   давал 2.28 и 3.16. На светлой теме это просто бледное пятно, которое глаз
   пропускает. При .8 получается 3.18 и 4.43, то есть норма с запасом, и элемент
   всё ещё тише текста рядом. */
.row__chevron { width: 16px; height: 16px; color: var(--hint); opacity: .8; }
.row__check { flex-shrink: 0; width: 20px; height: 20px; }
.row--pick.is-on .row__check { background: var(--link); -webkit-mask: no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4 10.5l4 4 8-9' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); mask: no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4 10.5l4 4 8-9' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.row--action { justify-content: center; color: var(--link-strong); }
.row--action .row__title { font-size: 16px; font-weight: 600; }
.row--danger { color: var(--danger-strong); }

/* --- switch, the real one ------------------------------------------------- */

.row--switch { cursor: pointer; }
.switch { position: relative; flex-shrink: 0; width: 51px; height: 31px; margin: 0; appearance: none; border-radius: 16px; background: color-mix(in srgb, var(--text) 16%, var(--section)); transition: background .18s; cursor: pointer; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%; background: #FFFFFF; box-shadow: 0 1px 3px rgba(0, 0, 0, .25); transition: transform .18s; }
.switch:checked { background: var(--btn); }
.switch:checked::after { transform: translateX(20px); }
/* [2026-09-23] Переключатель, который нельзя выключить, должен выглядеть так,
   чтобы это было видно до нажатия: включённый и обычный на вид, он только злит,
   когда не поддаётся. Приглушаем и снимаем курсор; почему так, написано строкой
   ниже в самой строке настройки. */
.switch:disabled { opacity: .4; cursor: default; }

/* --- fields --------------------------------------------------------------- */

.field { display: block; padding: 9px 16px 11px; }
.field__label { display: flex; justify-content: space-between; font-size: 13px; font-weight: 500; color: var(--text-3); }
/* [2026-09-28] Where the typing goes is visible, as on the site's form. */
.field:focus-within { box-shadow: inset 0 0 0 2px var(--focus); border-radius: var(--radius); }
.field__counter { color: var(--text-3); }
.field__row { display: flex; align-items: center; gap: 10px; }
/* [2026-09-28] A field that searches as you type: the matches open right under it,
   inside the block (the blocks clip anything that pokes out), and scroll. */
.suggest { max-height: 264px; overflow-y: auto; margin: 6px -16px -11px; border-top: .5px solid var(--separator); }
.suggest__item { display: block; width: 100%; padding: 12px 16px; border: 0; background: transparent; color: var(--text); font-size: 16px; text-align: left; cursor: pointer; }
.suggest__item + .suggest__item { box-shadow: inset 0 .5px 0 var(--separator); }
.suggest__item:active, .suggest__item.is-active { background: var(--bg-secondary); }
.suggest__empty { padding: 12px 16px; font-size: 15px; color: var(--text-3); }
.field__unit { flex-shrink: 0; font-size: 17px; color: var(--text-3); }
.field__btn { flex-shrink: 0; min-height: 36px; padding: 0 12px; border: 1px solid var(--separator); border-radius: 10px; background: var(--bg-secondary); color: var(--text); font-size: 15px; font-weight: 600; cursor: pointer; }
.field__input { width: 100%; min-height: 28px; font-variant-numeric: tabular-nums; margin-top: 3px; padding: 0; border: 0; background: transparent; color: var(--text); font-size: 17px; }
/* [2026-09-24] Подсказка не должна выглядеть значением: «0000 0000 0000 0000» и
   «Как на карте» читались как уже заполненное. Прозрачность как у системного
   placeholderText в iOS — 30% от цвета текста, в любой теме. */
.field__input::placeholder { color: color-mix(in srgb, var(--text) 30%, transparent); opacity: 1; }
.field__input:focus { outline: none; }
.field__input--area { min-height: 66px; resize: none; line-height: 1.35; }

/* --- chips ---------------------------------------------------------------- */

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 16px; padding: 12px 16px; background: var(--section); border-radius: var(--radius); min-height: 56px; box-shadow: var(--card-edge); }
.chips:empty { display: block; }
/* [2026-09-23] Два контейнера с одинаковым фоном, стоящие вплотную, читаются как
   один сломанный: так слиплись чипы со списком слов и группа с полем под ними.
   Правило общее, а не заплатка в одном экране, потому что пара «список и строка
   ввода» встречается у нас в трёх местах. */
.chips + .rows, .rows + .chips, .gallery + .rows { margin-top: 10px; }
/* Сегменты и группа под ними это тоже два блока с общим смыслом и разным фоном. */
.segments + .rows { margin-top: 10px; }
.chips:empty::before { content: attr(data-empty); font-size: 14px; color: var(--text-3); }
.chip { display: inline-flex; align-items: center; gap: 2px; min-height: 34px; padding: 4px 4px 4px 12px; border-radius: 10px; background: var(--bg-secondary); font-size: 15px; font-weight: 500; }
.chip--minus { color: var(--danger); }
.chip__x { width: 28px; height: 28px; border: 0; border-radius: 50%; background: transparent; color: var(--hint); font-size: 17px; line-height: 1; cursor: pointer; }

/* --- pictures of an announcement ------------------------------------------ */

/* [2026-09-23] We collect the pictures off the page ourselves, so the job here is
   not «upload», it is «throw out the wrong one»: a square grid where every item
   carries its own remove button, and the first one is marked because Telegram
   shows the caption under it. */

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin: 0 16px; padding: 12px; background: var(--section); border-radius: var(--radius); box-shadow: var(--card-edge); }
.gallery:empty { display: none; }
.thumb { position: relative; aspect-ratio: 1; border-radius: 10px; overflow: hidden; background: var(--bg-secondary); }
.thumb__img { display: block; width: 100%; height: 100%; object-fit: cover; }
.thumb__x { position: absolute; top: 4px; right: 4px; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: rgba(0, 0, 0, .55); color: #FFFFFF; font-size: 16px; line-height: 28px; cursor: pointer; }
.thumb__tag { position: absolute; left: 4px; bottom: 4px; padding: 2px 6px; border-radius: 6px; background: rgba(0, 0, 0, .55); color: #FFFFFF; font-size: 11px; font-weight: 600; }

.field__btn { flex-shrink: 0; min-height: 36px; padding: 0 14px; border: 1px solid var(--separator); border-radius: 10px; background: var(--bg-secondary); color: var(--text); font-size: 15px; font-weight: 600; cursor: pointer; }

/* --- balance, stats ------------------------------------------------------- */

.balance { margin: 0 16px 24px; padding: 20px 16px 16px; text-align: center; background: var(--section); border-radius: var(--radius-card); box-shadow: var(--card-edge); }
.balance__label { display: block; font-size: 14px; font-weight: 500; color: var(--text-3); }
.balance__value { display: block; margin-top: 4px; font-size: 34px; line-height: 1.1; font-weight: 700; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.balance__hint { display: block; margin-top: 4px; font-size: 14px; color: var(--text-3); min-height: 18px; }
.balance__buttons { display: flex; gap: 8px; margin-top: 16px; }
.balance__note { margin: 12px 0 0; font-size: 13px; color: var(--text-3); }
.topup { flex-grow: 1; min-height: 44px; border: 1px solid var(--separator); border-radius: 12px; background: var(--bg-secondary); color: var(--text); font-size: 15px; font-weight: 600; cursor: pointer; }
.topup--main { border-color: transparent; background: var(--btn); color: var(--btn-ink); }
.topup[disabled] { opacity: .5; }

.stats { display: flex; margin: 0 16px; background: var(--section); border-radius: var(--radius); box-shadow: var(--card-edge); }
/* [2026-09-23] Сводка отчёта липнет к верху при прокрутке: список размещений
   длинный, и цифры, ради которых человек открыл отчёт, уезжали первыми. Фон
   непрозрачный, иначе строки просвечивают насквозь. */
.stats--sticky { position: sticky; top: 0; z-index: 5; }
.stats--sticky::after { content: ''; position: absolute; left: 0; right: 0; bottom: -10px; height: 10px; background: linear-gradient(var(--bg-secondary), transparent); }
.stats__cell { flex-grow: 1; flex-basis: 0; padding: 14px 8px; text-align: center; }
.stats__cell + .stats__cell { box-shadow: inset 1px 0 0 var(--separator); }
.stats__cell--tap { cursor: pointer; }
.stats__cell--tap:active { filter: brightness(.94); }
.stats__cell b { display: block; font-size: 22px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stats__cell span { display: block; margin-top: 2px; font-size: 12px; line-height: 1.3; color: var(--text-3); }

/* --- roles ---------------------------------------------------------------- */

.roles { display: flex; flex-direction: column; gap: 12px; margin: 0 16px 24px; }

/* Icon left, text right — the shape of a row anyone has tapped a thousand times.
   Sitting the icon above the title made it decoration; beside the title it reads
   as what the row is about. */
.role {
    display: flex; align-items: flex-start; gap: 14px; width: 100%; padding: 16px;
    border: 0; border-radius: var(--radius-card); background: var(--section); box-shadow: var(--card-edge);
    text-align: left; color: inherit; cursor: pointer;
}
.role__icon {
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0; width: 42px; height: 42px;
    border-radius: 12px; background: var(--bg-secondary); color: var(--accent);
}
.role__icon .ic { width: 22px; height: 22px; }
.role--earn .role__icon { color: var(--ok); }
.role__body { flex-grow: 1; min-width: 0; }
.role__title { display: block; font-size: 18px; font-weight: 600; letter-spacing: -.01em; line-height: 1.3; }
.role__text { display: block; margin-top: 5px; font-size: 14px; line-height: 1.45; font-weight: 400; color: var(--text-2); }
.role__meta { display: block; margin-top: 8px; font-size: 13px; font-weight: 600; color: var(--link-strong); }
.role--earn .role__meta { color: var(--ok); }
.role .row__chevron { margin-top: 12px; }

/* --- buttons -------------------------------------------------------------- */

.bigbtn {
    display: flex; align-items: center; justify-content: center;
    /* [2026-09-23] 4px сверху не отделяли кнопку от списка над ней: она читалась
       как часть последней карточки. */
    width: calc(100% - 32px); min-height: 56px; margin: 16px 16px 24px;
    /* [2026-09-28] The site's primary button: yellow, black ink, 600 18px, radius 14.
       Black on #FFCC00 is 14.6:1, so the old 19px/700 workaround for Telegram's blue
       is no longer needed. */
    border: 0; border-radius: var(--radius); background: var(--btn); color: var(--btn-ink);
    font-size: 18px; font-weight: 600; letter-spacing: -.01em; text-decoration: none; cursor: pointer;
    transition: background-color .15s, transform .1s;
}
.bigbtn:active { background: var(--btn-active); transform: scale(.985); }
/* One filled primary per screen, so the in-page second action is the site's secondary
   button: the page colour with a hairline, ink text. */
.bigbtn--quiet { border: 1px solid var(--separator); background: var(--bg-secondary); color: var(--text); }
.bigbtn--quiet:active { background: var(--section); }
.btn { flex-grow: 1; min-height: 44px; border: 1px solid var(--separator); border-radius: 12px; background: var(--bg-secondary); color: var(--text); font-size: 15px; font-weight: 600; cursor: pointer; }
.btn--main { border-color: transparent; background: var(--btn); color: var(--btn-ink); }

.empty { margin: 0 16px; padding: 28px 16px; text-align: center; font-size: 15px; line-height: 1.5; color: var(--text-3); background: var(--section); border-radius: var(--radius); box-shadow: var(--card-edge); }
.formerror { margin: 0 16px 16px; padding: 12px 14px; border-radius: 12px; background: var(--danger-soft); color: var(--danger-strong); font-size: 15px; line-height: 1.4; }

/* --- cards (approval) ----------------------------------------------------- */

.list { display: flex; flex-direction: column; gap: 12px; padding: 0 16px; }
.card--pad { padding: 16px; background: var(--section); border-radius: var(--radius); box-shadow: var(--card-edge); }
.card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.card__title { margin: 0; font-size: 17px; font-weight: 600; line-height: 1.3; }
.card__value { flex-shrink: 0; font-size: 15px; color: var(--text-3); }
.card__body { margin: 6px 0 0; font-size: 15px; line-height: 1.4; color: var(--text-2); }
.card__meta { margin: 6px 0 0; font-size: 13px; line-height: 1.4; color: var(--text-3); }
.card__actions { display: flex; gap: 10px; margin-top: 12px; }

/* --- tabs ----------------------------------------------------------------- */

.tabs { position: sticky; bottom: 0; display: flex; background: var(--bg-secondary); box-shadow: inset 0 1px 0 var(--separator); padding-bottom: var(--safe-bottom); }
.tabs__item {
    flex-grow: 1; min-height: 52px; padding: 7px 4px 6px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    border: 0; background: transparent; color: var(--text-3); font-size: 11px; cursor: pointer;
}
.tabs__item .ic { width: 26px; height: 26px; }
.tabs__item.is-active { color: var(--text); font-weight: 600; }
.tabs__item:active { opacity: .6; }

/* --- helper --------------------------------------------------------------- */

.ask { flex-grow: 1; padding: 8px 16px 12px; }
.ask__intro { margin: 0 0 16px; font-size: 14px; line-height: 1.45; color: var(--text-3); }
.ask__pair + .ask__pair { margin-top: 16px; }
.ask__q { margin: 0 0 8px 44px; padding: 10px 14px; border-radius: 16px 16px 4px 16px; background: var(--btn); color: var(--btn-ink); font-size: 16px; line-height: 1.35; }
.ask__a { margin: 0 44px 0 0; padding: 10px 14px; border-radius: 16px 16px 16px 4px; background: var(--section); font-size: 16px; line-height: 1.4; }
.ask__hints { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 16px 12px; }
.ask__hint { min-height: 38px; padding: 8px 14px; border: 1px solid var(--separator); border-radius: 10px; background: var(--bg-secondary); color: var(--text); font-size: 14px; font-weight: 500; cursor: pointer; }
.ask__bar { position: sticky; bottom: 0; display: flex; align-items: center; gap: 8px; padding: 8px 16px calc(8px + var(--safe-bottom)); background: var(--bg-secondary); box-shadow: inset 0 1px 0 var(--separator); }
.ask__input { flex-grow: 1; min-height: 44px; padding: 10px 16px; border: 0; border-radius: 22px; background: var(--section); color: var(--text); font-size: 16px; }
.ask__input:focus { outline: none; }
.ask__send { flex-shrink: 0; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border: 0; border-radius: 50%; background: var(--btn); color: var(--btn-ink); cursor: pointer; }

/* --- gate ----------------------------------------------------------------- */

.gate { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; padding: 24px; background: var(--bg); }
.gate__box { max-width: 300px; text-align: center; }
.gate__brand { display: flex; flex-direction: column; align-items: center; gap: 18px; color: var(--text); }
.gate__mark { display: block; width: 64px; height: 64px; border-radius: 15px; box-shadow: var(--card-edge); }
.gate__word { display: block; width: 128px; height: 25px; fill: currentColor; }
.gate__text { margin: 12px 0 0; font-size: 15px; line-height: 1.45; color: var(--text-3); }
.gate__link { display: block; width: 100%; min-height: 56px; margin-top: 12px; padding: 17px 22px; border: 0; border-radius: var(--radius); background: var(--btn); color: var(--btn-ink); font-size: 18px; font-weight: 600; letter-spacing: -.01em; line-height: 1.2; text-decoration: none; cursor: pointer; }
.gate__link:active { background: var(--btn-active); }
.gate__retry { border: 1px solid var(--separator); background: var(--bg-secondary); color: var(--text); }

/* --- update bar ----------------------------------------------------------- */

/* Sits above everything and stays there while the person reads it: nothing is
   blocked, the cabinet keeps working on the old build until it reloads.
   [2026-09-28] Владелец видел, как человек её игнорирует: «надо сделать красной».
   Красная с белым, кнопка белая с красным; жёлтый занят блоком «Бесплатно». */
.update {
    position: sticky; top: 0; z-index: 10;
    display: flex; align-items: center; gap: 12px;
    padding: 10px 16px calc(10px);
    background: #d92d20; color: #ffffff;
}
.update__text { flex-grow: 1; font-size: 14px; font-weight: 600; line-height: 1.35; }
.update__btn {
    flex-shrink: 0; min-height: 36px; padding: 0 14px;
    border: 0; border-radius: 18px;
    background: #ffffff; color: #d92d20;
    font-size: 14px; font-weight: 700; cursor: pointer;
    font-variant-numeric: tabular-nums;
}

.bulk { display: flex; gap: 8px; margin: 0 16px 12px; }
/* [2026-10-03] The person's name on a gate request opens their Telegram profile. */
.card__title-link { display: inline-flex; align-items: center; gap: 6px; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; text-decoration: underline; text-decoration-color: var(--hint); text-underline-offset: 3px; }
.card__title-link .ic { width: 16px; height: 16px; flex-shrink: 0; color: var(--hint); }
.card__title-link:disabled { opacity: .5; cursor: default; }
/* [2026-10-03] Undo of a gate decision, and its answer, under the row itself. */
.row__undo { display: block; margin-top: 8px; }
.row__undo:disabled { opacity: .6; cursor: default; }
.row__chip { margin-top: 8px; align-self: flex-start; }
.row__say { display: block; margin-top: 6px; font-size: 13px; line-height: 1.35; }
.row__say.is-ok { color: var(--ok); }
.row__say.is-bad { color: var(--danger); }
.bulk__text { flex: 1; min-width: 0; align-self: center; font-weight: 500; overflow-wrap: anywhere; }
.row__switch { align-self: center; margin-left: 4px; }
.row__del { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 36px; height: 36px; margin-left: 2px; padding: 0; border: 0; border-radius: 10px; background: transparent; color: var(--danger-strong); cursor: pointer; }
.row__del .ic { width: 18px; height: 18px; }
.pageback { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin: 4px 8px -4px; padding: 0 8px; border: 0; background: transparent; color: var(--text-2); font-size: 16px; font-weight: 600; cursor: pointer; }
.pageback .ic { width: 20px; height: 20px; }
.savebar { position: sticky; bottom: 60px; z-index: 20; margin: 0 16px 8px; padding: 12px 14px; border-radius: 12px; background: var(--danger-soft); color: var(--danger-strong); font-size: 14px; font-weight: 600; line-height: 1.35; box-shadow: 0 1px 2px rgba(10, 10, 10, .08); }
.field__note { margin: 0; padding: 10px 16px 12px; font-size: 13px; line-height: 1.5; color: var(--text-3); box-shadow: inset 0 .5px 0 var(--separator); }
/* [2026-09-23] Подпись, которая сообщает ПРОБЛЕМУ, не должна выглядеть как
   обычное пояснение: человек читает её тем же серым и проходит мимо, а речь о
   том, что показов не будет вообще. Янтарный это наш цвет ожидания и помехи,
   тот же, что у статуса «на проверке». */
.field__note--warn, .section__note--warn, .row__sub--warn { color: var(--warn); }

.update__btn .ic { width: 16px; height: 16px; margin-right: 6px; }
.row--action { gap: 8px; }
.row--action .ic { width: 20px; height: 20px; color: inherit; }

/* --- preview -------------------------------------------------------------- */

/* What the announcement will look like in somebody's chat. Shown as a message
   bubble, because that is exactly where it ends up — a person judges it far better
   this way than by reading two form fields. */
.preview { margin: 0 16px 10px; padding: 14px 16px; background: var(--section); border-radius: var(--radius); box-shadow: var(--card-edge); }
/* [2026-09-23] Превью показывает ровно то, что встанет в чате: пузырь сообщения
   со ссылкой и пометкой. Ответ в разговоре пишется под беседу, поэтому его пузырь
   объясняет, а не выдумывает текст. */
.preview__kind { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; font-size: 13px; font-weight: 600; color: var(--text-3); }
.preview__kind .ic { width: 14px; height: 14px; }
.bubble { padding: 10px 14px 12px; border-radius: 14px 14px 14px 4px; background: var(--bg-secondary); }
.bubble--quote { border-left: 2px solid var(--link); border-radius: 4px 14px 14px 4px; }
.bubble__img { display: block; width: 100%; max-height: 180px; object-fit: cover; border-radius: 10px; margin-bottom: 8px; }
.bubble__header { display: block; font-size: 15px; font-weight: 600; line-height: 1.3; }
.bubble__text { margin: 2px 0 0; font-size: 15px; line-height: 1.45; }
.bubble__link { display: inline-block; margin-top: 8px; color: var(--link); font-size: 15px; font-weight: 600; }
.bubble__mark { display: block; margin-top: 6px; font-size: 12px; font-style: italic; color: var(--text-3, var(--hint)); }
.preview__text { margin: 0; padding: 10px 14px; border-radius: 14px 14px 14px 4px; background: var(--bg-secondary); font-size: 15px; line-height: 1.45; }

/* --- announcement rows ---------------------------------------------------- */

/* A card, not a line: the state has to be visible before anything is read, and the
   numbers only appear once there are numbers. */
/* [2026-09-23] Each item is its own card with air around it. Stacked inside one
   panel with hairlines between them they read as a single long item: the eye needs
   a gap to know where one thing ends and the next begins. */
.cards { display: flex; flex-direction: column; gap: 10px; margin: 0 16px; }
.itemrow {
    display: block; width: 100%; padding: 16px 16px 15px;
    border: 0; border-radius: var(--radius); background: var(--section); box-shadow: var(--card-edge);
    text-align: left; color: inherit; cursor: pointer;
}
.itemrow__top { display: flex; align-items: center; justify-content: space-between; }
.itemrow__title { display: block; margin-top: 8px; font-size: 17px; font-weight: 600; line-height: 1.3; color: var(--text); }
.itemrow__note { display: block; margin-top: 4px; font-size: 13px; line-height: 1.4; color: var(--text-3); }
.itemrow__stats { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px; }
/* [2026-09-23] Цифры сети под ролью на главной: тот же строй метрик, что в
   карточке объявления, чтобы человек читал их одинаково в обоих местах. */
.metrics { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px; }
.metrics[hidden] { display: none; }

.metric { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--text-3); }
.metric .ic { width: 15px; height: 15px; opacity: .8; }
.metric b { font-size: 14px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }

.chip-status {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 10px 4px 7px; border-radius: 999px;
    background: var(--bg-secondary); color: var(--text-2);
    font-size: 13px; font-weight: 600;
}
.chip-status__ic { display: inline-flex; }
/* [2026-09-28] Where a free feature is on: one green chip per channel under its description. */
.row__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* [2026-09-29] One line per channel with its own switch, in the free-features list. */
.row__chans { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.row__chan { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.row__chan-name { min-width: 0; overflow-wrap: anywhere; font-weight: 500; }
.row__chan-setup { flex-shrink: 0; padding: 0; border: 0; background: none; font: inherit; color: var(--accent); font-weight: 500; cursor: pointer; }
.row__chan-setup.is-quiet { color: var(--hint); font-weight: 400; }
/* A long channel name wraps; a pill three lines tall reads as a blob. */
.row__chips .chip-status { border-radius: 10px; }
.chip-status .ic { width: 13px; height: 13px; }
.chip-status.is-active { background: var(--ok-soft); color: var(--ok); }
.chip-status.is-moderation { background: var(--warn-soft); color: var(--warn); }
.chip-status.is-rejected, .chip-status.is-banned { background: var(--danger-soft); color: var(--danger-strong); }
.chip-status.is-pending { background: var(--warn-soft); color: var(--warn); }
.metric__ic { display: inline-flex; }

/* Icon inside a filled button needs its own breathing room; without it the label
   reads as «+Новое» glued together. */
.bigbtn .ic, .section__action .ic, .update__btn .ic { margin-right: 8px; }
.bigbtn { gap: 0; }

/* --- report --------------------------------------------------------------- */

.reprow { padding: 12px 16px; }
/* [2026-09-23] Строка отчёта открывает своё размещение, значит она нажимаемая
   и должна об этом говорить. */
.reprow--tap { cursor: pointer; }
.reprow--tap:active { filter: brightness(.94); }
.reprow + .reprow { box-shadow: inset 0 .5px 0 var(--separator); }
.reprow__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.reprow__title { font-size: 16px; font-weight: 600; line-height: 1.3; }
.reprow__amount { flex-shrink: 0; font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; }
.reprow__amount.is-earning { color: var(--ok); }
.reprow__meta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 6px; }

/* --- home chips ----------------------------------------------------------- */

.role__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.chip-status.is-draft, .chip-status.is-paused, .chip-status.is-none { background: var(--bg-secondary); color: var(--text-3); }

/* Title and its explanation must not read as one grey mass: the title is ink, the
   line under it is muted and a step smaller. */
.itemrow__title { color: var(--text); }
.itemrow__note { color: var(--text-3); font-weight: 400; }
.itemrow.is-rejected .itemrow__note { color: var(--danger); }

/* A channel name can be a wall of words («Халява,Заработок,Схемы,Обмен,Купи…»).
   One line, cut with an ellipsis: the row must keep its shape whatever the name. */
.reprow__title { flex-grow: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.itemrow__title { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.stats__cell b { white-space: nowrap; }

/* --- segmented filter ----------------------------------------------------- */

.segments { display: flex; gap: 4px; margin: 0 16px 16px; padding: 4px; background: var(--section); border-radius: var(--radius); box-shadow: var(--card-edge); }
/* [2026-09-28] Four long choices do not fit one line on a phone: two by two. */
.segments--wrap { flex-wrap: wrap; }
.segments--wrap .segment { flex: 1 1 40%; }
.segment { flex-grow: 1; min-height: 40px; padding: 0 6px; border: 0; border-radius: 10px; background: transparent; color: var(--text-3); font-size: 14px; font-weight: 600; line-height: 1.2; cursor: pointer; }
.segment.is-on { background: var(--seg-on); color: var(--text); box-shadow: 0 1px 2px rgba(10, 10, 10, .08); }

/* Number fields: the browser's own spinners are tiny targets and look like debris
   next to everything else here. */
.field__input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.field__input[type="number"]::-webkit-outer-spin-button,
.field__input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* --- money blocks --------------------------------------------------------- */

/* Two kinds of money, told apart at a glance: what you spend on showing, and what
   your channels earned. Each block says what it is and offers exactly one action. */
.money { margin: 0 16px 12px; padding: 18px 16px 16px; background: var(--section); border-radius: var(--radius-card); box-shadow: var(--card-edge); }
.money__row { display: flex; }
.money__cell { flex-grow: 1; }
.money__label { display: block; font-size: 14px; font-weight: 500; color: var(--text-3); }
.money__value { display: block; margin-top: 4px; font-size: 34px; line-height: 1.1; font-weight: 700; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.money__value--earn { color: var(--ok); }
.money__hint { display: block; margin-top: 4px; font-size: 13px; color: var(--text-3); }
.money__action {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; min-height: 48px; margin-top: 14px;
    border: 1px solid var(--separator); border-radius: 12px; background: var(--bg-secondary); color: var(--text);
    font-size: 16px; font-weight: 600; cursor: pointer;
}
.money__action .ic { width: 18px; height: 18px; }

/* Status colour does not stop at the chip: the line explaining the state carries a
   muted version of the same colour, so a glance down the list reads as colour, not
   as a wall of grey. */
.itemrow.is-active .itemrow__note { color: color-mix(in srgb, var(--ok) 72%, var(--text-3)); }
.itemrow.is-moderation .itemrow__note, .itemrow.is-pending .itemrow__note { color: color-mix(in srgb, var(--warn) 72%, var(--text-3)); }
.itemrow.is-rejected .itemrow__note, .itemrow.is-banned .itemrow__note { color: color-mix(in srgb, var(--danger) 78%, var(--text-3)); }

/* A destructive row is red in full: text AND icon. Half-red reads as a mistake, and
   a red fill would shout louder than the action deserves inside a settings list. */
/* [2026-09-24] Один красный на строку. Значок был обычным --danger, текст
   усиленным, и владелец увидел ровно это: «два цвета оттенка красного». Усиленный
   держит контраст текста, значку он тем более подходит. */
.row--danger, .row--danger .row__title,
.row--danger > .ic:first-child, .row--danger .ic { color: var(--danger-strong); }

/* --- report days ---------------------------------------------------------- */

/* The day is the unit people think in, so it carries the heading and its own total.
   Inside it the rows are quiet: one line of time, duration and clicks, no icons
   repeating on every line. */
.day { margin: 0 0 20px; }
.day__head { display: flex; align-items: baseline; justify-content: space-between; margin: 0 16px 6px; }
.day__title { font-size: 15px; font-weight: 600; color: var(--text); }
.day__sum { font-size: 13px; font-weight: 600; color: var(--text-3); font-variant-numeric: tabular-nums; }
.reprow__meta { margin-top: 4px; font-size: 13px; line-height: 1.4; color: var(--text-3); font-variant-numeric: tabular-nums; }

.money__actions { display: flex; gap: 8px; margin-top: 14px; }
.money__actions .money__action { margin-top: 0; }
.money__action--main { border-color: transparent; background: var(--btn); color: var(--btn-ink); }

/* --- free features -------------------------------------------------------- */

/* The one block on the home screen that is allowed to stand out: it carries the
   offer the whole plan rests on.
   [2026-09-28] Владелец: «блок голубой сверху с бесплатными ботами нихуя не
   заметен, цвет наш брендовый жёлтый, текст чёрный». Цвета те же, что у кнопок
   на nativad.com (--btn #FFCC00, --btn-ink #0a0a0a): жёлтый в обеих темах, на
   тёмной он виден ещё лучше, чем на светлой. Значок наоборот, чёрный с жёлтым. */
.freebox {
    display: flex; align-items: flex-start; gap: 14px;
    width: calc(100% - 32px); margin: 0 16px 24px; padding: 16px;
    border: 0; border-radius: var(--radius-card);
    background: var(--btn);
    text-align: left; color: var(--btn-ink); cursor: pointer;
}
.freebox:active { background: var(--btn-active); }
.freebox__icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 42px; height: 42px; border-radius: 11px; background: #0a0a0a; color: #FFCC00; }
.freebox__icon .ic { width: 22px; height: 22px; }
.freebox__body { flex-grow: 1; min-width: 0; }
.freebox__title { display: block; font-size: 17px; font-weight: 700; }
.freebox__text { display: block; margin-top: 4px; font-size: 14px; line-height: 1.45; color: #3d3200; }
.freebox .row__chevron { color: #0a0a0a; }

/* --- amounts -------------------------------------------------------------- */

/* Sums are choices, not tabs: each says what it buys, and the chosen one is
   unmistakable. Three cramped segments with the active one barely tinted told
   nobody anything. */
.amounts { display: flex; flex-direction: column; gap: 8px; margin: 0 16px 12px; }
.amount {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    width: 100%; min-height: 52px; padding: 12px 16px;
    border: 1px solid var(--separator); border-radius: var(--radius);
    background: var(--section); color: inherit; text-align: left; cursor: pointer;
}
.amount b { font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }
.amount span { font-size: 13px; color: var(--text-3); }
.amount.is-on { border-color: var(--btn); box-shadow: inset 0 0 0 1px var(--btn); background: var(--accent-soft); }
/* [2026-09-23] Выбранная сумма НЕ красится акцентом: замерено, синий кнопки
   Telegram на тёмном фоне даёт 3.86 при норме 4.5, а это главная цифра экрана.
   Что выбрано, и так видно по рамке и подложке, так что цифра остаётся обычным
   текстом и просто становится тяжелее. */
.amount.is-on b { font-weight: 700; }

/* A quiet way out of a money block: one line, one arrow, no second fat button. */
.money__link {
    display: flex; align-items: center; justify-content: center; gap: 4px;
    width: 100%; min-height: 40px; margin-top: 8px;
    /* [2026-09-23] Текст и стрелка одного цвета: раньше текст был голубой, а
       стрелка серая, и пара выглядела собранной из двух разных элементов.
       Выбор владельца, текст к стрелке. */
    border: 0; background: transparent; color: var(--hint); font-size: 15px; cursor: pointer;
}
.money__link .row__chevron { width: 12px; height: 12px; color: inherit; opacity: .8; }

/* [2026-09-25] QR-код счёта в криптовалюте. Код всегда тёмный на белом, с белым
   полем вокруг, и в тёмной теме тоже: камера кошелька не читает светлый код на
   тёмном. Рисуется по клеткам на canvas, поэтому растягивается без размытия. */
.qr { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 0 16px 20px; }
.qr__code { width: 208px; max-width: 100%; height: auto; aspect-ratio: 1; padding: 12px; border-radius: 12px; background: #FFFFFF; image-rendering: pixelated; }
.qr__note { margin: 0; font-size: 13px; line-height: 1.5; color: var(--text-3); text-align: center; max-width: 26em; }
/* [2026-09-25] Two choices side by side: «for an exchange» and «for a wallet». */
.amounts--row { flex-direction: row; }
.amounts--row .amount { flex: 1 1 0; min-width: 0; }

/* [2026-09-25] Админка владельца: подпись под полем, состояние сохранения. */
.admin-field__sub { display: block; margin-top: 4px; font-size: 13px; line-height: 1.45; color: var(--text-3); }
.admin-field__state { font-size: 13px; color: var(--text-3); }
.admin-field__state.is-ok { color: var(--ok); }
.admin-field__state.is-bad { color: var(--danger, #E53935); }
.admin-field .field__input { min-width: 0; }
/* [2026-09-25] Monitor tabs: five of them do not fit a phone in one row, so they scroll. */
.admin-tabs { overflow-x: auto; scrollbar-width: none; }
.admin-tabs::-webkit-scrollbar { display: none; }
.admin-tabs .segment { flex: 0 0 auto; padding: 0 12px; white-space: nowrap; }
.admin-row { gap: 10px; }
.admin-row .row__title { font-size: 15px; overflow-wrap: anywhere; }
.admin-row .row__sub { overflow-wrap: anywhere; }
.admin-row__chip { flex-shrink: 0; }
.admin-row.is-tappable { cursor: pointer; }
.admin-row.is-tappable:active { filter: brightness(.94); }
.admin-row.is-alarm .row__title { color: var(--danger); }
.admin-row__detail { margin: 8px 0 0; padding: 10px; max-height: 320px; overflow: auto; border-radius: 8px; background: var(--bg-secondary);
    font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre-wrap; word-break: break-word; color: var(--text); }
.admin-actions { display: flex; justify-content: flex-end; margin: 0 16px 10px; }
.admin-search { margin: 0 16px 12px; }
.admin-actions--left { justify-content: flex-start; }
#grant-note.is-ok { color: var(--ok); }
#grant-go.is-danger { color: var(--danger); }
#client-grant .segments { margin-bottom: 10px; }
#client-grant .field { margin: 0 16px 8px; }
/* [2026-09-25] Analytics: figures in tiles, days in bars, the funnel as a thin line. */
.stat-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 0 16px 16px; }
.stat-tile { display: flex; flex-direction: column; gap: 2px; padding: 14px; border-radius: var(--radius); background: var(--section); box-shadow: var(--card-edge); }
.stat-tile__label { font-size: 13px; color: var(--text-3); }
.stat-tile__value { font-size: 24px; line-height: 1.15; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stat-tile__delta, .stat-chart__delta { font-size: 12px; color: var(--text-3); }
.stat-tile__delta.is-up, .stat-chart__delta.is-up { color: var(--ok); }
.stat-tile__delta.is-down, .stat-chart__delta.is-down { color: var(--danger); }
.stat-chart { padding-bottom: 4px; }
.stat-chart__head { display: flex; align-items: baseline; gap: 8px; margin: 0 16px 6px; }
.stat-chart__sum { font-size: 18px; font-variant-numeric: tabular-nums; }
.stat-chart__plot { margin: 0 16px; padding: 10px 12px 6px; border-radius: var(--radius); background: var(--section); box-shadow: var(--card-edge); }
.stat-bars { display: block; width: 100%; height: 90px; fill: var(--btn); }
.stat-chart.is-errors .stat-bars { fill: var(--danger); }
.stat-chart__axis { display: flex; justify-content: space-between; gap: 8px; margin: 4px 16px 0; font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.stat-funnel { display: block; height: 3px; margin-top: 6px; border-radius: 2px; background: var(--btn); min-width: 2px; }
/* [2026-09-25] The owner inside a client's cabinet: impossible to miss, one tap back. */
.actbar { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 50; display: flex; align-items: center; gap: 10px; padding: 8px 16px; background: var(--danger, #E53935); color: #fff; font-size: 13px; line-height: 1.35; }
.actbar__text { flex: 1; min-width: 0; }
.actbar__exit { flex-shrink: 0; min-height: 32px; padding: 0 12px; border: 0; border-radius: 8px; background: rgba(255, 255, 255, .22); color: #fff; font-size: 14px; font-weight: 600; cursor: pointer; }
