/* Inter — свой, а не с чужих доменов (AUDIT-024). Раньше шрифт тянулся с
   fonts.googleapis.com и fonts.gstatic.com: четыре запроса и около 153 КБ с
   двух сторонних доменов, причём таблица стилей блокировала первую отрисовку.
   Теперь файлы лежат рядом с сайтом, попадают под правило долгого кэширования
   для assets/* и не требуют ни отдельных рукопожатий, ни разрешений в CSP.

   Ось веса 400..800 (переменный шрифт), а не отдельные начертания: в стилях
   используются промежуточные значения 550, 650 и 750 — см. AUDIT-022.
   Подмножества и их диапазоны символов взяты ровно те, что отдавал Google
   Fonts, поэтому браузер по-прежнему скачивает только нужные: для русской
   страницы это latin и cyrillic.

   Путь от корня (/assets/...), а не относительный: при раскладке
   prepare-static.py копирует style.css в /assets/releases/<хеш>/, и
   относительная ссылка указывала бы внутрь каталога релиза, где шрифтов нет.
   Проверено на собранном релизе, а не только на исходном каталоге.

   Лицензия — SIL Open Font License 1.1, текст лежит в assets/fonts/OFL.txt. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/inter-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/assets/fonts/inter-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

/* ================================================================
   WB Code Generator · Apple-редизайн v2 (2026-08)
   Дизайн-токены → база → компоненты → модалки → мобильные → print.
   Важно: классы согласованы с app.js — не переименовывать без правки JS.
   ================================================================ */

/* ---------- 1. Токены ---------- */
:root {
  color-scheme: light;
  --bg: #f5f5f7;
  --surface: #ffffff;
  --surface-2: #fbfbfd;
  --fill: #f2f2f7;
  --fill-2: #e8e8ed;
  --line: rgba(60, 60, 67, .10);
  --hairline: rgba(60, 60, 67, .16);
  --text: #1d1d1f;
  --text-2: #6e6e73;
  --text-3: #66666e;
  --accent: #cb11ab;
  --accent-press: #ad0d92;
  --accent-tint: rgba(203, 17, 171, .10);
  --grad-flow: linear-gradient(90deg, #cb11ab, #e83a9c, #ff5e8a, #ff8a3d, #cb11ab);
  --danger: #cc0000;
  --danger-bg: #feecec;
  --success: #117a3d;
  --success-bg: #e8f8ee;
  --warn: #c25a00;
  --warn-bg: #fff3e0;
  --balance-medium: #d2b600;
  --mat-nav: rgba(251, 251, 253, .78);
  /* Более прозрачная подложка для уведомлений с сильным стеклом. */
  --mat-thick: rgba(251, 251, 253, .62);
  --r-s: 10px; --r-m: 14px; --r-l: 20px; --r-xl: 28px; --r-pill: 999px;
  --sh-1: 0 1px 2px rgba(0, 0, 0, .04), 0 4px 16px rgba(0, 0, 0, .05);
  --sh-2: 0 2px 6px rgba(0, 0, 0, .05), 0 12px 36px rgba(0, 0, 0, .09);
  --sh-float: 0 8px 20px rgba(0, 0, 0, .10), 0 24px 70px rgba(0, 0, 0, .16);
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Inter", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ease: cubic-bezier(.25, .1, .25, 1);
  --spring: cubic-bezier(.32, .72, .24, 1);
  --emph: cubic-bezier(.2, .9, .25, 1);
  --t-fast: .18s; --t-med: .32s; --t-slow: .65s;
  --topbar-h: 64px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #000000;
    --surface: #1c1c1e;
    --surface-2: #242426;
    --fill: #2c2c2e;
    --fill-2: #3a3a3c;
    --line: rgba(84, 84, 88, .42);
    --hairline: rgba(84, 84, 88, .62);
    --text: #f5f5f7;
    --text-2: #a1a1a6;
    --text-3: #b4b4be;
    --accent: #e93cc9;
    --accent-press: #f55cd3;
    --accent-tint: rgba(233, 60, 201, .16);
    --danger: #ff453a; --danger-bg: rgba(255, 69, 58, .14);
    --success: #30d158; --success-bg: rgba(48, 209, 88, .14);
    --warn: #ff9f0a; --warn-bg: rgba(255, 159, 10, .14);
    --balance-medium: #ffd60a;
    --mat-nav: rgba(18, 18, 20, .72);
    --mat-thick: rgba(18, 18, 20, .58);
    --sh-1: 0 1px 2px rgba(0, 0, 0, .5), 0 6px 20px rgba(0, 0, 0, .4);
    --sh-2: 0 2px 8px rgba(0, 0, 0, .5), 0 16px 44px rgba(0, 0, 0, .5);
    --sh-float: 0 10px 26px rgba(0, 0, 0, .6), 0 30px 80px rgba(0, 0, 0, .65);
  }
}
[data-theme="dark"] {
  color-scheme: dark;
  --bg: #000000;
  --surface: #1c1c1e;
  --surface-2: #242426;
  --fill: #2c2c2e;
  --fill-2: #3a3a3c;
  --line: rgba(84, 84, 88, .42);
  --hairline: rgba(84, 84, 88, .62);
  --text: #f5f5f7;
  --text-2: #a1a1a6;
  --text-3: #b4b4be;
  --accent: #e93cc9;
  --accent-press: #f55cd3;
  --accent-tint: rgba(233, 60, 201, .16);
  --danger: #ff453a; --danger-bg: rgba(255, 69, 58, .14);
  --success: #30d158; --success-bg: rgba(48, 209, 88, .14);
  --warn: #ff9f0a; --warn-bg: rgba(255, 159, 10, .14);
  --balance-medium: #ffd60a;
  --mat-nav: rgba(18, 18, 20, .72);
  --mat-thick: rgba(18, 18, 20, .58);
  --sh-1: 0 1px 2px rgba(0, 0, 0, .5), 0 6px 20px rgba(0, 0, 0, .4);
  --sh-2: 0 2px 8px rgba(0, 0, 0, .5), 0 16px 44px rgba(0, 0, 0, .5);
  --sh-float: 0 10px 26px rgba(0, 0, 0, .6), 0 30px 80px rgba(0, 0, 0, .65);
}

/* ---------- 2. База ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; touch-action: manipulation; }
html { overflow-x: clip; }
@supports not (overflow: clip) { html { overflow-x: hidden; } }
/* ВАЖНО: overflow-x на body НЕ ставим - он ломает position:sticky шапки
 * на мобильных (прыжки при скролле). Горизонтальный орб клипается на .hero. */
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  font-size: 17px;
  line-height: 1.47;
  letter-spacing: -.01em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background .35s var(--ease), color .35s var(--ease);
  /* Горизонтальный клип только на body (clip, в отличие от hidden, не ломает
   * position:sticky шапки). Орбы плавно уходят за край вьюпорта без панорамы. */
  overflow-x: clip;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; -webkit-appearance: none; appearance: none; }
input, textarea { font: inherit; }
input[type="text"], input[type="tel"], input[type="email"], input[type="password"], textarea { -webkit-appearance: none; appearance: none; }
/* U-LOW-08: number-поля не глушим — спиннеры нужны в админке на десктопе. */

/* U-LOW-08: единый Apple-стиль нативных select (админка + фильтры) */
select {
  --field-bg: var(--fill);
  --field-ring: 0 0 0 0 transparent;
  -webkit-appearance: none; appearance: none;
  height: 40px; padding: 0 34px 0 12px;
  border: .5px solid var(--hairline); border-radius: var(--r-s);
  background-color: var(--field-bg); color: var(--text);
  font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6"><path d="M1 1l4 4 4-4" stroke="%2398989d" stroke-width="1.6" fill="none" stroke-linecap="round"/></svg>');
  background-repeat: no-repeat; background-position: right 12px center;
}
select:focus { --field-bg: var(--surface); --field-ring: 0 0 0 4px var(--accent-tint); outline: none; background-color: var(--field-bg); border-color: var(--accent); box-shadow: var(--field-ring); }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
img { display: block; }
svg.ico { width: 18px; height: 18px; flex: none; }
::selection { background: var(--accent-tint); }
:focus-visible { --field-ring: 0 0 0 4px var(--accent-tint), 0 0 0 1.5px var(--accent); outline: none; box-shadow: var(--field-ring); border-radius: var(--r-s); }
.hidden { display: none !important; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--surface); color: var(--text);
  padding: 10px 16px; border-radius: var(--r-s); box-shadow: var(--sh-2);
}
.skip-link:focus { left: 12px; top: 12px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  /* U-LOW-07: полностью замороженный спиннер выглядит как зависание —
   * дискретные шаги вращения остаются читаемыми и не являются плавным движением. */
  .spinner { animation: spin 1.6s steps(10) infinite !important; }
}

/* ---------- 3. Топбар ---------- */
.topbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20;
  /* U-HIGH-01: при viewport-fit=cover шапка обязана учитывать «чёлку» —
  иначе логотип и «Войти» уезжают под статус-бар на iPhone с Face ID. */
  height: auto;
  min-height: calc(var(--topbar-h) + env(safe-area-inset-top, 0px));
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: calc(12px + env(safe-area-inset-top, 0px))
           max(20px, calc((100% - 1140px) / 2), env(safe-area-inset-right, 0px))
           12px
           max(20px, calc((100% - 1140px) / 2), env(safe-area-inset-left, 0px));
  background: var(--mat-nav);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: .5px solid var(--hairline);
  /* position:sticky на iOS Safari задокументированно подёргивается вместе с
     backdrop-filter при появлении/скрытии адресной строки во время скролла —
     браузер вынужден пересчитывать позицию и блюр на каждом кадре скролла.
     position:fixed этого пересчёта не требует вообще (плюс распорка ниже —
     .topbar-spacer — занимает её место в потоке документа). */
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  will-change: transform;
}
/* Распорка под шапку: раз шапка теперь position:fixed (выведена из потока),
   без неё контент под ней подскочил бы наверх, заехав под шапку. */
.topbar-spacer { height: calc(var(--topbar-h) + env(safe-area-inset-top, 0px)); }
.brand { display: flex; align-items: center; gap: 11px; min-width: 0; }
.brand-logo { display: block; flex: 0 1 auto; width: 214px; min-width: 0; }
.brand-mark { display: block; width: 100%; height: auto; object-fit: contain; }
.brand-on-dark { display: none; }
[data-theme="dark"] .brand-on-light { display: none; }
[data-theme="dark"] .brand-on-dark { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand-on-light { display: none; }
  :root:not([data-theme="light"]) .brand-on-dark { display: block; }
}
.topbar .brand-logo { width: clamp(120px, 24vw, 214px); min-width: 120px; }
.brand-caption { font-size: 13px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
@media (max-width: 1000px) { .brand-caption { display: none; } }
@media (max-width: 600px) { .topbar .brand-logo { width: clamp(120px, 34vw, 180px); } }
.topbar-actions { display: flex; align-items: center; gap: clamp(8px, 2vw, 14px); flex: none; }
.topbar-buttons { display: flex; align-items: center; gap: 8px; }
.account-status { color: var(--text-2); font-size: 13px; font-weight: 600; max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 860px) { .account-status { display: none; } }
.topbar-auth-group { display: flex; flex-direction: row; align-items: center; gap: 10px; }
.topbar-balance { color: var(--text-2); font-size: 11.5px; font-weight: 650; white-space: nowrap; font-variant-numeric: tabular-nums; padding: 5px 11px; background: var(--fill); border-radius: var(--r-pill); }
.topbar-auth {
  border-radius: var(--r-pill);
  background: var(--accent); color: #fff;
  padding: 9px 20px; font-weight: 600; font-size: 14.5px; white-space: nowrap;
  box-shadow: 0 5px 14px rgba(203, 17, 171, .28);
  transition: transform .3s var(--spring), background .18s var(--ease), box-shadow .3s var(--ease);
}
@media (hover: hover) {
  .topbar-auth:hover { background: var(--accent-press); transform: translateY(-1px); box-shadow: 0 8px 20px rgba(203, 17, 171, .34); }
}
.topbar-auth:active { transform: scale(.96); }

/* ---------- 4. Hero ---------- */
.hero { position: relative; padding: clamp(48px, 8vw, 96px) 0 clamp(28px, 5vw, 56px); text-align: center; overflow: visible; }
.orb { position: absolute; border-radius: 50%; filter: blur(70px); opacity: .22; pointer-events: none; z-index: 0; animation: orbFloat 9s var(--ease) infinite alternate; will-change: transform; }
.orb-a { width: 380px; height: 380px; background: #ff5e8a; top: -160px; left: -120px; }
.orb-b { width: 340px; height: 340px; background: #cb11ab; top: -100px; right: -140px; animation-delay: -8s; }
/* Третье пятно из эталонной концепции — в проекте отсутствовало вовсе. */
.orb-c { width: 300px; height: 300px; background: #8324be; bottom: -160px; left: 38%; animation-delay: -11s; opacity: .18; }
[data-theme="dark"] .orb { opacity: .17; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .orb { opacity: .17; } }

/* Пятна на всю длину страницы (не только в шапке) — фиксированные относительно
   экрана, а не страницы: у блоков "Тарифы"/FAQ непрозрачный фон, так что
   секционно-привязанные пятна просто не были бы видны за ним большую часть
   времени. Fixed-позиционирование мягко просвечивает в промежутках между
   блоками при любой прокрутке, независимо от реальной высоты страницы. */
.orb-page { position: fixed; border-radius: 50%; filter: blur(70px); opacity: .16; pointer-events: none; z-index: -1; animation: orbFloatPage 11s var(--ease) infinite alternate; will-change: transform; }
.orb-page-a { width: 260px; height: 260px; background: #ff5e8a; top: 45%; left: -90px; animation-delay: -4s; }
.orb-page-b { width: 220px; height: 220px; background: #8324be; bottom: 8%; right: -70px; animation-delay: -14s; }
[data-theme="dark"] .orb-page { opacity: .13; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .orb-page { opacity: .13; } }

/* Мобильные экраны — те же пропорции, что и на ПК, а не буквально те же
   пиксели: на узком экране пятна такого размера заливали собой всё. */
@media (max-width: 600px) {
  .orb-a { width: 190px; height: 190px; top: -70px; left: -60px; filter: blur(36px); }
  .orb-b { width: 170px; height: 170px; top: -50px; right: -70px; filter: blur(36px); }
  .orb-c { width: 150px; height: 150px; bottom: -70px; filter: blur(32px); }
  /* Радиус размытия был прежним (70px) при уменьшенном размере пятна — на
     узком экране это давало непропорционально большую засветку (та же
     проблема, что мы чинили, только с новыми пятнами). Масштабируем блюр
     вместе с размером и уводим пятна дальше за край экрана. */
  .orb-page-a { width: 130px; height: 130px; left: -80px; filter: blur(34px); }
  .orb-page-b { width: 110px; height: 110px; right: -70px; filter: blur(30px); }
}
@keyframes orbFloat {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(48px, -36px) scale(1.1); }
  100% { transform: translate(-32px, 28px) scale(.94); }
}
@keyframes orbFloatPage {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(50px, 40px) scale(1.12); }
  100% { transform: translate(-40px, -30px) scale(.92); }
}
.hero-inner { position: relative; z-index: 1; max-width: 760px; margin: 0 auto; }
.eyebrow, .panel-kicker {
  color: var(--accent);
  font-size: 11.5px; font-weight: 750;
  letter-spacing: .1em; text-transform: uppercase;
}
.hero h1 {
  margin: 12px 0 14px;
  font-size: clamp(32px, 6vw, 60px);
  line-height: 1.06;
  letter-spacing: -.032em;
  font-weight: 700;
}
.grad-text {
  display: inline-block;
  background: var(--grad-flow);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: gradFlow 8s linear infinite;
}
@keyframes gradFlow { from { background-position: 0% 0; } to { background-position: 300% 0; } }
.hero p { margin: 0 auto; max-width: 520px; color: var(--text-2); font-size: clamp(15px, 2vw, 17.5px); line-height: 1.55; }
.hero-p-short { display: none; color: var(--text-2); font-size: 14px; }
.t-short { display: none; }
/* Точно по концепции: одна строка, без второй "подписи" (её не было в эталоне) */
.signup-bonus {
  display: inline-flex; align-items: center; gap: 9px; text-align: left;
  margin-top: 16px; padding: 10px 16px;
  border-radius: var(--r-pill);
  background: var(--accent-tint); color: var(--accent);
  font-size: 14px; font-weight: 600; line-height: 1.4;
}
.signup-bonus .ico { flex: none; }

/* ---------- 5. Рабочая область ---------- */
.container { width: min(1140px, calc(100% - 40px)); margin: 0 auto; }
.workspace {
  display: grid;
  grid-template-columns: minmax(320px, .9fr) minmax(360px, 1.1fr);
  gap: clamp(14px, 2vw, 20px);
  align-items: start;
}
.panel {
  background: var(--surface);
  border: .5px solid var(--hairline);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-1);
  padding: clamp(18px, 2.6vw, 26px);
}
.panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 22px; }
.panel-head h2 { margin-top: 5px; font-size: 21px; font-weight: 700; letter-spacing: -.02em; }
.icon-button {
  position: relative;
  width: 34px; height: 34px; min-width: 34px; min-height: 34px;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--fill); color: var(--text-2);
  font-size: 20px; line-height: 1;
  transition: background .18s var(--ease), transform .3s var(--spring), color .18s var(--ease);
}
/* U-LOW-01: расширяем хит-зону до ~44px, не увеличивая визуальный размер. */
.icon-button::before { content: ""; position: absolute; inset: -6px; border-radius: 50%; }
@media (hover: hover) { .icon-button:hover { background: var(--fill-2); color: var(--text); } }
.icon-button:active { transform: scale(.9); }
.icon-button svg { width: 17px; height: 17px; }
/* Переключатель темы: JS вешает .is-dark на кнопку; показываем иконку
 * ЦЕЛЕВОЙ темы (в светлой — луна «включить тёмную», и наоборот).
 * Смена иконки — с пружинным поворотом (микроанимация иконок). */
.theme-toggle .ico-sun { display: none; }
.theme-toggle .ico-moon, .theme-toggle .ico-sun { transform-origin: center; }
.theme-toggle.is-dark .ico-sun { display: block; animation: iconIn .5s var(--spring) both; }
.theme-toggle.is-dark .ico-moon { display: none; }
.theme-toggle:not(.is-dark) .ico-moon { display: block; animation: iconIn .5s var(--spring) both; }
@keyframes iconIn {
  from { transform: rotate(-120deg) scale(.3); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/* Поля ввода */
.field-label { display: flex; align-items: baseline; gap: 6px; margin-bottom: 8px; padding-left: 4px; font-size: 13.5px; font-weight: 600; color: var(--text-2); }
.field-optional { font-size: 11px; font-weight: 600; color: var(--text-3); }
.field-wrap { position: relative; }
input, textarea {
  --field-bg: var(--fill);
  --field-ring: 0 0 0 0 transparent;
  width: 100%;
  border: .5px solid transparent;
  border-radius: var(--r-m);
  background: var(--field-bg);
  color: var(--text);
  outline: none;
  transition: background .18s var(--ease), box-shadow .18s var(--ease), border-color .18s var(--ease);
}
input { height: 54px; padding: 0 52px 0 16px; font-size: 16.5px; font-weight: 500; }
textarea { min-height: 110px; padding: 13px 15px; font-size: 16px; line-height: 1.55; resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--text-3); font-weight: 400; }
#code:focus, textarea:focus { --field-bg: var(--surface); --field-ring: 0 0 0 4px var(--accent-tint); background: var(--field-bg); border-color: var(--accent); box-shadow: var(--field-ring); }
input.invalid { --field-bg: var(--danger-bg); border-color: var(--danger); background: var(--field-bg); }
#code.invalid:focus { --field-bg: var(--danger-bg); --field-ring: 0 0 0 4px color-mix(in srgb, var(--danger) 12%, transparent); border-color: var(--danger); background: var(--field-bg); box-shadow: var(--field-ring); }
.field-counter {
  position: absolute; top: 50%; right: 15px; transform: translateY(-50%);
  color: var(--text-3); font-size: 11.5px; font-weight: 650;
  font-variant-numeric: tabular-nums;
  opacity: 0; transition: opacity .2s var(--ease);
}
.field-counter.visible { opacity: 1; }
.error { min-height: 20px; padding-top: 6px; color: var(--danger); font-size: 13px; }

/* Autofill uses the same surface and focus/error state as manual input.
   Important inset paint must also win over #code:focus and browser UA styles. */
:is(input, textarea, select):is(:-webkit-autofill, :autofill) {
  -webkit-text-fill-color: var(--text) !important;
  -webkit-box-shadow: 0 0 0 1000px var(--field-bg) inset, 0 0 0 1000px var(--surface) inset, var(--field-ring) !important;
  box-shadow: 0 0 0 1000px var(--field-bg) inset, 0 0 0 1000px var(--surface) inset, var(--field-ring) !important;
  transition-property: border-color, transform !important;
  caret-color: var(--field-caret, var(--text));
}

/* Кнопки */
.primary-button, .secondary-button {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 50px; padding: 0 26px;
  border-radius: var(--r-pill);
  font-size: 16.5px; font-weight: 600; letter-spacing: -.01em;
  transition: transform .3s var(--spring), background .18s var(--ease), box-shadow .3s var(--ease), opacity .18s var(--ease);
}
.primary-button { background: var(--accent); color: #fff; box-shadow: 0 6px 18px rgba(203, 17, 171, .28); width: 100%; }
.primary-button::after {
  content: ""; position: absolute; top: -10%; bottom: -10%; left: -70%; width: 44%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .38), transparent);
  transform: skewX(-18deg); transition: left .65s var(--ease); pointer-events: none;
}
@media (hover: hover) {
  .primary-button:hover:not(:disabled) { background: var(--accent-press); transform: translateY(-1px); box-shadow: 0 10px 26px rgba(203, 17, 171, .34); }
  .primary-button:hover:not(:disabled)::after { left: 135%; }
}
.primary-button:active:not(:disabled) { transform: scale(.96); }
.secondary-button { background: var(--fill); color: var(--text); min-height: 50px; }
@media (hover: hover) { .secondary-button:hover:not(:disabled) { background: var(--fill-2); transform: translateY(-1px); } }
.secondary-button:active:not(:disabled) { transform: scale(.96); }
.primary-button:disabled, .secondary-button:disabled { opacity: .4; cursor: not-allowed; box-shadow: none; transform: none; }
.button-hero { height: 56px; padding: 0 34px; font-size: 18px; margin-top: 4px; }
.generate-label, .generate-loading { display: inline-flex; align-items: center; justify-content: center; gap: 9px; }
/* Короткая подпись кнопки — только на мобильных (базово скрыта) */
.label-short { display: none; }
.button-hero .ico { transition: transform .25s var(--spring); }
@media (hover: hover) { .button-hero:hover .ico { transform: translateX(4px); } }
/* Галочка «Готово» — пружинный pop при появлении */
.status-ready svg { animation: checkPop2 .45s var(--spring) both; }
@keyframes checkPop2 { from { transform: scale(0) rotate(-30deg); } to { transform: none; } }
.danger-button { background: var(--danger) !important; box-shadow: 0 6px 16px rgba(227, 0, 0, .28) !important; width: auto; }
.danger-button:hover:not(:disabled) { background: #c40000 !important; }
.danger-button-outline {
  width: 100%; margin-top: 10px; padding: 12px 14px;
  border-radius: var(--r-m); border: 1.5px solid var(--danger);
  background: transparent; color: var(--danger); font-weight: 650; font-size: 14.5px;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.danger-button-outline:hover { background: var(--danger); color: #fff; }
.text-button { color: var(--accent); font-size: 14px; font-weight: 550; }
.text-button:hover { text-decoration: underline; }
.text-button:disabled { opacity: .5; }

/* Статусы */
.status { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 13px; border-radius: var(--r-pill); font-size: 13px; font-weight: 650; white-space: nowrap; transition: background .18s var(--ease), color .18s var(--ease); }
.status-idle { background: var(--fill); color: var(--text-2); }
.status-ready { background: var(--success-bg); color: var(--success); }
.status-error { background: var(--danger-bg); color: var(--danger); }
/* Четвёртый статус из концепции (§ Статусы): ожидание — оранжевый + пульс */
.status-warn { background: var(--warn-bg); color: var(--warn); }

/* Превью */
.preview-head { margin-bottom: 18px; }
.preview-stage {
  min-height: clamp(320px, 44vw, 560px);
  display: grid; place-items: center;
  padding: clamp(14px, 2.4vw, 22px);
  border-radius: var(--r-l);
  background: var(--fill);
  overflow: hidden;
}
.canvas-wrap { position: relative; width: min(340px, 100%); aspect-ratio: 5 / 6; display: grid; place-items: center; scroll-margin-top: calc(var(--topbar-h) + 12px); }
.generation-skeleton { position: absolute; inset: 0; overflow: hidden; background: var(--fill-2); border-radius: 16px; }
/* U-LOW-03: fallback пропорции для iOS ≤14 без aspect-ratio — иначе обёртка
 * схлопывается в ноль до первой генерации. */
.canvas-wrap::before { content: ""; display: block; padding-top: 120%; }
@supports (aspect-ratio: 5 / 6) { .canvas-wrap::before { display: none; } }
#sticker {
  width: 100%; height: 100%; display: block; object-fit: contain;
  border-radius: 16px;
}
/* Белый фон и тень — только когда стикер реально нарисован (концепция:
   «до генерации нет ни белого фона, ни тени», см. .empty-state ниже).
   Без .has-content класс #sticker всегда был белым с тенью, и пустое
   состояние текста просто накладывалось поверх этой видимой карточки. */
#sticker.has-content {
  background: #fff;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .16);
}
.empty-state {
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center; gap: 7px;
  padding: 28px; text-align: center;
  color: var(--text-3); pointer-events: none;
  background: transparent;
  border: 1.5px dashed var(--hairline);
  border-radius: 16px;
}
.empty-state svg { width: 40px; height: 40px; margin-bottom: 4px; }
.empty-state strong { color: var(--text-2); font-size: 14px; font-weight: 600; white-space: nowrap; }
.empty-state span { font-size: 12.5px; line-height: 1.5; }
.result-meta { display: grid; gap: 12px; margin-top: 16px; }
.result-meta > div { padding: 12px 14px; border-radius: var(--r-m); background: var(--fill); overflow: hidden; }
.result-meta span { display: block; margin-bottom: 4px; color: var(--text-3); font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; }
.result-meta strong { display: block; overflow: hidden; color: var(--text); font-size: 14.5px; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
.preview-lock-note { display: flex; align-items: center; gap: 7px; margin: 13px 2px 0; color: var(--text-3); font-size: 12px; font-weight: 600; line-height: 1.4; }
.preview-lock-note svg { width: 15px; height: 15px; flex: none; }
.actions { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 10px; margin-top: 14px; }
.actions .primary-button, .actions .secondary-button { width: auto; }
.quick-info { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 16px; }
.info-row { display: flex; gap: 9px; align-items: center; padding: 12px 13px; border-radius: var(--r-m); background: var(--fill); color: var(--text-2); font-size: 12.5px; font-weight: 400; line-height: 1.4; }
.info-row .ico { color: var(--success); }
.info-row:last-child .ico { color: var(--accent); }

/* ---------- 6. Тарифы / FAQ / История ---------- */
.pricing-section, .faq-section {
  margin-top: clamp(36px, 6vw, 64px);
  padding: clamp(18px, 3vw, 28px);
  background: var(--surface);
  border: .5px solid var(--hairline);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-1);
}
.history-section { margin-top: clamp(36px, 6vw, 64px); }
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 20px; }
.section-head h2 { margin-top: 5px; font-size: 21px; font-weight: 700; letter-spacing: -.02em; }
.pricing-note { margin-top: 14px; }
.faq-list { display: grid; gap: 0; overflow: hidden; border: .5px solid var(--hairline); border-radius: var(--r-l); }
.faq-item {
  background: var(--surface);
  border-bottom: .5px solid var(--line);
  padding: 2px 18px;
}
.faq-item:last-child { border-bottom: 0; }
.faq-item summary {
  cursor: pointer; list-style: none;
  padding: 14px 0; font-weight: 600; font-size: 15.5px;
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; color: var(--accent); font-size: 22px; font-weight: 500; transition: transform .25s var(--ease); }
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item p { padding: 0 0 15px; color: var(--text-2); font-size: 14.5px; line-height: 1.6; max-width: 720px; }
.history-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 12px; }
.history-item {
  min-width: 0; padding: 12px; border: .5px solid var(--hairline);
  background: var(--surface); border-radius: var(--r-m); text-align: left;
  transition: transform .3s var(--spring), box-shadow .3s var(--ease), border-color .18s var(--ease);
}
@media (hover: hover) { .history-item:hover { border-color: var(--accent-tint); transform: translateY(-2px); box-shadow: var(--sh-1); } }
.history-thumb { display: grid; width: 100%; aspect-ratio: 5 / 6; place-items: center; margin-bottom: 10px; border-radius: 9px; background: var(--fill); color: var(--text-3); transition: color .18s var(--ease); }
.history-thumb svg { width: 76%; height: 76%; }
/* Узор загорается фирменным цветом при нажатии — тактильная обратная связь,
   которой не хватало карточкам истории (см. также .history-item:active ниже). */
.history-item:active .history-thumb { color: var(--accent); }
.history-code { overflow: hidden; font-size: 13px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
.history-date { display: block; margin-top: 3px; color: var(--text-3); font-size: 11px; line-height: 1.35; }
.package-state { grid-column: 1 / -1; min-height: 154px; padding: 24px; border-radius: var(--r-l); background: var(--fill); color: var(--text-2); text-align: center; }
.package-state .secondary-button { width: auto; margin: 14px auto 0; }
.package-loading { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; padding: 0; background: transparent; }
.package-loading .skeleton { min-height: 154px; }

/* ---------- 7. Футер ---------- */
footer {
  width: min(1140px, calc(100% - 40px));
  margin: 56px auto 0;
  /* Padding stays inside the scrollable document; a last child's bottom
     margin can collapse outside body, especially after the iOS modal lock. */
  padding-bottom: max(36px, calc(env(safe-area-inset-bottom, 0px) + 20px));
  display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(270px, 1fr); gap: 28px 56px;
  color: var(--text-2); font-size: 13px;
}
.footer-brand { display: grid; grid-template-columns: 164px minmax(0, 1fr); align-items: start; gap: 28px; }
.footer-brand-head { display: flex; flex-direction: column; align-items: center; justify-self: start; text-align: center; gap: 8px; font-weight: 650; color: var(--text); }
.footer-brand-head .brand-logo { width: 164px; flex: none; }
.footer-brand p, .footer-brand h2 { margin: 0; max-width: 480px; line-height: 1.5; font-size: 13px; font-weight: 400; color: var(--text-2); }
.footer-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 48px; margin-top: 8px; }
.footer-col { min-width: 0; display: grid; grid-template-rows: auto repeat(5, minmax(32px, 1fr)); row-gap: 2px; }
/* Shared rows keep paired links aligned even when a document title wraps.
   Older browsers retain equal-height rows in both stretched columns. */
@supports (grid-template-rows: subgrid) {
  /* Title + five links, including postcards and the optional install action.
     A five-row subgrid forced the last two links into the same row. */
  .footer-columns { grid-template-rows: auto repeat(5, minmax(32px, auto)); }
  .footer-col { grid-row: 1 / span 6; grid-template-rows: subgrid; }
}
.footer-col > :is(a, button) { box-sizing: border-box; display: flex; align-items: center; justify-content: flex-start; width: 100%; min-width: 0; min-height: 36px; margin: 0; padding: 7px 2px; border: 0; border-radius: 0; appearance: none; background: none; box-shadow: none; font: inherit; line-height: 1.47; color: var(--text-2); text-align: left; overflow-wrap: anywhere; }
.footer-col > .signed-in-only { display: none; }
.is-signed-in .footer-col > .signed-in-only { display: flex; }
@media (max-width: 600px) { .footer-columns { column-gap: 16px; } .footer-col > :is(a, button) { min-height: 40px; padding-block: 8px; } }
.footer-col-title { font-weight: 650; color: var(--text); margin-bottom: 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .03em; }
.footer-col > :is(a, button):hover { color: var(--accent); text-decoration: underline; }
.footer-bottom { grid-column: 1 / -1; padding-top: 16px; border-top: .5px solid var(--line); }
.connection-status { position: fixed; top: env(safe-area-inset-top, 0px); left: 0; right: 0; z-index: 2000; display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 4px 16px; padding: 10px 16px; background: var(--bg); color: var(--text-2); border-bottom: 1px solid var(--hairline); box-shadow: 0 4px 18px rgba(0,0,0,.12); font-size: 13px; overflow-wrap: anywhere; }
.connection-status .text-button { flex: 0 0 auto; min-height: 36px; }
.startup-status { z-index: 2010; }
.startup-status small { display: block; font-size: 11px; }

/* ---------- 8. Модалки: общее ---------- */
.modal { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 20px; }
.modal.hidden { display: none; }
.modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(10, 8, 14, .5);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  opacity: 1;
  transition: opacity .25s var(--ease);
}
.modal.is-closing .modal-backdrop { opacity: 0; }
@keyframes modalIn { from { opacity: 0; transform: translateY(18px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes viewSlideIn { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: none; } }
@keyframes modalOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(12px) scale(.98); } }
.auth-card, .otp-card, .account-card, .confirm-card {
  position: relative; z-index: 1;
  background: var(--surface);
  border: .5px solid var(--hairline);
  box-shadow: var(--sh-float);
  animation: modalIn .42s var(--spring) both;
}
.modal.is-closing .auth-card, .modal.is-closing .otp-card,
.modal.is-closing .account-card, .modal.is-closing .confirm-card { animation: modalOut .28s var(--ease) both; }
.modal-close {
  position: absolute;
  right: 9px; top: 9px; z-index: 5;
  width: 44px; height: 44px; min-width: 44px; min-height: 44px;
  display: grid; place-items: center;
  border-radius: 50%; background: transparent; color: var(--text-2);
  font-size: 20px; line-height: 1;
  transition: background .18s var(--ease), transform .3s var(--spring), color .18s var(--ease);
}
.modal-close > svg { width: 34px; height: 34px; padding: 9px; border-radius: 50%; background: var(--fill); }
@media (hover: hover) { .modal-close:hover > svg { background: var(--fill-2); color: var(--text); } }
.modal-close:active { transform: scale(.9); }
.modal-close:focus-visible, .compact-close:focus-visible { outline: none; box-shadow: none; }

/* Скролл-лок фона (iOS Safari) */
body.modal-open { position: fixed; top: var(--modal-scroll-offset, 0); left: 0; right: 0; width: 100%; overflow: hidden; }

/* ---------- 9. Вход ---------- */
.auth-card { width: min(430px, 100%); max-height: min(90dvh, 860px); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; padding: clamp(22px, 3vw, 30px); border-radius: var(--r-xl); display: grid; gap: 15px; }
.auth-card > *, .auth-form, .field, .field-control { min-width: 0; }
.auth-card h2 { font-size: 25px; font-weight: 700; letter-spacing: -.025em; margin: 6px 0 2px; }
.auth-note { color: var(--text-2); font-size: 13.5px; line-height: 1.5; }
.auth-consent { display: flex; gap: 11px; align-items: flex-start; cursor: pointer; min-height: 44px; padding: 6px 0; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
.auth-consent input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 22px; height: 22px; flex: none; margin-top: 1.5px; padding: 0;
  border: 1.5px solid var(--text-3); border-radius: 7px;
  background: var(--surface); display: grid; place-items: center;
  cursor: pointer; transition: background .18s var(--ease), border-color .18s var(--ease), transform .3s var(--spring);
}
.auth-consent input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); animation: checkPop .3s var(--spring); }
@keyframes checkPop { 50% { transform: scale(1.15); } }
.auth-consent input[type="checkbox"]:checked::after {
  content: ""; width: 11px; height: 6px;
  border-left: 2.5px solid #fff; border-bottom: 2.5px solid #fff;
  transform: rotate(-45deg) translate(1px, -1px);
}
.auth-consent span { min-width: 0; overflow-wrap: anywhere; font-size: 13px; line-height: 1.5; color: var(--text-2); }
.auth-consent a { font-weight: 600; }

.oauth-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.oauth-grid-triple { grid-template-columns: repeat(3, 1fr); }
.oauth-span-full { grid-column: 1 / -1; }
.oauth-button {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  height: 48px; padding: 0 10px;
  border-radius: var(--r-m); background: var(--fill);
  font-size: 15px; font-weight: 600;
  transition: transform .3s var(--spring), background .18s var(--ease);
}
@media (hover: hover) { .oauth-button:hover { background: var(--fill-2); transform: translateY(-1px); } }
.oauth-button:active { transform: scale(.96); }
.oauth-button:disabled { opacity: .45; cursor: not-allowed; }
.oa-ico { width: 18px; height: 18px; flex: none; }
.oauth-button-brand { border: 0; color: #fff; }
.oauth-button-yandex { background: #000; color: #fff; }
.oauth-button-yandex:hover { background: #000; }
.oauth-icon-ya { width: 22px; height: 22px; border-radius: 50%; background: #fc3f1d; color: #fff; font-style: normal; font-size: 13px; font-weight: 800; display: grid; place-items: center; }
.oauth-button-max { background: linear-gradient(135deg, #44ccff, #4f57e8 52%, #9933dd); }
.oauth-button-max:hover { background: linear-gradient(135deg, #44ccff, #4f57e8 52%, #9933dd); filter: brightness(1.06); }
.oauth-button-telegram { background: linear-gradient(135deg, #2aabee, #229ed9); }
.oauth-button-telegram:hover { background: linear-gradient(135deg, #2aabee, #229ed9); filter: brightness(1.06); }
.telegram-login-wrap, .telegram-login-wrap .oauth-button { width: 100%; min-width: 0; }
.telegram-login-wrap { display: flex; }

.max-login-panel {
  margin-top: 2px; padding: 14px; border-radius: var(--r-m);
  background: var(--accent-tint); border: 1px solid var(--accent-tint);
  display: grid; gap: 10px;
}
.max-login-status { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text); line-height: 1.5; }
.spinner { width: 16px; height: 16px; flex: none; border-radius: 50%; border: 2px solid var(--accent-tint); border-top-color: var(--accent); animation: spin .8s linear infinite; }
.primary-button .spinner { border-color: rgba(255, 255, 255, .42); border-top-color: #fff; }
@keyframes spin { to { transform: rotate(360deg); } }

.auth-divider { display: flex; align-items: center; gap: 12px; color: var(--text-3); font-size: 12.5px; }
.auth-divider::before, .auth-divider::after { content: ""; height: .5px; background: var(--hairline); flex: 1; }

/* Сегмент-контрол Телефон/Email (бегунок на :has — без JS) */
/* Concentric corners (принцип Apple): внутренний радиус = внешний минус
   отступ, 16 − 5 = 11. Тогда скругления вложены математически точно и
   бегунок «сидит» в треке без визуального зазора по углам. */
.auth-tabs { position: relative; display: grid; grid-template-columns: 1fr 1fr; background: var(--fill); border-radius: 16px; padding: 5px; gap: 2px; }
.auth-tabs .auth-tab { border-radius: 11px; }
.auth-tab {
  position: relative; z-index: 1;
  padding: 10px; border-radius: 8px;
  font-size: 14px; font-weight: 600; color: var(--text-2);
  transition: color .2s var(--ease);
}
.auth-tab.active { color: var(--text); }
.seg-thumb {
  position: absolute; z-index: 0;
  top: 5px; bottom: 5px; left: 5px; width: calc(50% - 6px);
  border-radius: 11px; background: var(--surface);
  /* Только мягкая тень, без контурной линии: обводка выглядела лишней и
     утяжеляла переключатель. Касается всех трёх — выбора продукта в шаге 1,
     разделов истории в кабинете и телефона/почты в окне входа. */
  box-shadow: 0 2px 8px rgba(0, 0, 0, .10);
  transition: transform .32s var(--spring);
}
/* Сдвиг с поправкой на промежуток между колонками: без неё бегунок
   не доезжал 2px, и справа отступ выглядел больше, чем слева. */
.auth-tabs:has(.auth-tab:nth-child(2).active) .seg-thumb { transform: translateX(calc(100% + 2px)); }
.auth-tabs.auth-tabs-single { grid-template-columns: minmax(0, 1fr); }
#auth-modal .auth-tabs-single .seg-thumb { width: calc(100% - 10px); transform: none; }

.auth-form { display: grid; gap: 14px; }
.auth-form.hidden { display: none !important; }
.auth-form.is-entering, .account-view.is-entering { animation: viewSlideIn .26s var(--spring) both; }
.field { display: grid; gap: 7px; }
.field-control {
  position: relative; display: flex; align-items: center;
  border: .5px solid transparent; border-radius: var(--r-m);
  background: var(--fill);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease), background .18s var(--ease);
}
.field-control:focus-within { background: var(--surface); border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-tint); }
.field-control.field-valid { border-color: var(--success); }
.field-control.field-invalid { border-color: var(--danger); }
.field-icon { display: grid; place-items: center; width: 20px; height: 20px; margin-left: 14px; color: var(--text-3); flex: none; }
.field-icon svg { width: 18px; height: 18px; }
.field-control:focus-within .field-icon { color: var(--accent); }
.field-control input { --field-ring: 0 0 0 0 transparent; flex: 1; min-width: 0; border: 0; background: transparent; height: 54px; padding: 0 18px; font-size: 17px; font-weight: 500; box-shadow: none; border-radius: var(--r-m); }
.field-control button { flex: none; }
.field-control input:focus { box-shadow: none; border: 0; background: transparent; }
.field-control:focus-within input { --field-bg: var(--surface); }
.field-status { width: 20px; margin-right: 12px; flex: none; text-align: center; font-size: 13px; font-weight: 800; opacity: 0; transition: opacity .15s var(--ease); }
.field-control.field-valid .field-status { opacity: 1; color: var(--success); }
.field-control.field-valid .field-status:empty { opacity: 0; }
.field-control.field-invalid .field-status { opacity: 1; color: var(--danger); }
.field-hint { padding-left: 4px; color: var(--text-3); font-size: 13px; line-height: 1.45; }
.field-hint.hint-valid { color: var(--success); }
.field-hint.hint-error { color: var(--danger); }
.forgot-password-link { color: var(--accent); font-weight: 600; }
.password-toggle {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 50%; color: var(--text-3);
  transition: color .18s var(--ease), background .18s var(--ease);
}
/* U-LOW-01: хит-зона 46px при визуальных 38px. */
.password-toggle::before { content: ""; position: absolute; inset: -4px; border-radius: 50%; }
.password-toggle:hover { color: var(--text); background: var(--fill); }
.password-toggle svg { width: 18px; height: 18px; }
.field-control:has(.password-toggle) input { padding-right: 52px; }
.auth-form-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.auth-form-actions.single { grid-template-columns: 1fr; }

/* ---------- 10. OTP ---------- */
.otp-card { width: min(420px, 100%); max-height: min(90dvh, 720px); overflow-y: auto; overscroll-behavior: contain; padding: clamp(22px, 3vw, 30px); border-radius: var(--r-xl); display: grid; gap: 14px; }
.otp-card h2 { font-size: 25px; font-weight: 700; letter-spacing: -.025em; margin: 6px 0 0; }
.otp-subtitle { color: var(--text-2); font-size: 14.5px; line-height: 1.5; }
.otp-subtitle strong { color: var(--text); }
.otp-note { color: var(--text-3); font-size: 13px; line-height: 1.5; }
.otp-digits { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 9px; margin: 8px 0 2px; }
/* U-MED-01: в телефонном режиме код 4-значный — 6 треков оставляли треть
 * строки пустой. Класс ставится из openOtpModal(). */
.otp-digits.digits-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.otp-digit {
  --field-bg: var(--fill); --field-caret: var(--accent);
  width: 100%; height: 64px; padding: 0;
  text-align: center; font-size: 26px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text); background: var(--field-bg);
  border: .5px solid transparent; border-radius: var(--r-m);
  outline: none; caret-color: var(--accent);
  transition: background .18s var(--ease), box-shadow .18s var(--ease), transform .3s var(--spring), border-color .18s var(--ease);
}
.otp-digit:focus { --field-bg: var(--surface); --field-ring: 0 0 0 4px var(--accent-tint); background: var(--field-bg); border-color: var(--accent); box-shadow: var(--field-ring); transform: translateY(-2px); }
.otp-change-number { display: block; width: 100%; text-align: center; }
#otp-resend { display: block; width: 100%; text-align: center; }
#otp-resend.hidden { display: none; }

/* ---------- 11. Личный кабинет ---------- */
.account-card {
  width: min(860px, calc(100vw - 40px));
  max-height: min(92dvh, 900px);
  border-radius: var(--r-xl);
  overflow: hidden;
  display: flex; flex-direction: column;
  /* На iOS/WebKit touch-action не всегда надёжно наследуется через контейнер
     со своей прокруткой внутри position:fixed-листа (см. .account-view ниже) —
     двойной тап по элементам кабинета мог увеличивать масштаб страницы, хотя
     на <html> уже стоит touch-action: manipulation. Задаём явно здесь тоже. */
  touch-action: manipulation;
}
.account-header {
  flex: 0 0 auto;
  padding: clamp(40px, 6vw, 52px) clamp(18px, 4vw, 30px) 0;
  background: linear-gradient(180deg, var(--accent-tint), transparent);
}
.account-title-row { display: flex; justify-content: space-between; gap: 18px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 16px; }
.account-identity { display: flex; align-items: center; gap: 14px; min-width: 0; }
/* Заголовок кабинета для скринридеров — визуально скрыт: концепция сама
   структура кабинета (аватар+баланс) уже несёт этот смысл визуально. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.acc-person-heading { display: flex; align-items: center; gap: 5px; }
.account-settings-btn {
  position: relative; width: 30px; height: 30px; flex: none;
  display: inline-grid; place-items: center;
  border-radius: 50%; background: var(--fill); color: var(--text-2);
  transition: background .2s var(--ease), color .2s var(--ease), transform .3s var(--spring);
}
.account-settings-btn::before { content: ""; position: absolute; inset: -7px; border-radius: 50%; }
.account-settings-btn span { display: none; }
.acc-person-text { min-width: 0; }
.acc-person-name { font-weight: 700; font-size: 15.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acc-person-email { margin: 1px 0 0; color: var(--text-2); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account-settings-btn:hover { background: var(--fill-2); color: var(--accent); }
.account-settings-btn:active { transform: scale(.9); }
.account-settings-btn svg { width: 14px; height: 14px; }
.account-profile-state { margin: 10px 0; }
.account-profile-state .account-state { padding: 0; }
.account-profile-state .account-loading .skeleton { min-height: 24px; }
.balance-icon { flex: none; width: 34px; height: 34px; display: grid; place-items: center; border-radius: 10px; background: var(--accent-tint); color: var(--accent); }
.balance-icon svg { width: 17px; height: 17px; }
.balance-info span { display: block; color: var(--text-2); font-size: 11px; font-weight: 650; white-space: nowrap; }
.balance-info strong { display: block; margin-top: 2px; color: var(--accent); font-size: clamp(22px, 3vw, 27px); font-weight: 700; letter-spacing: -.04em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.account-tabs-scroll { position: relative; margin-top: 22px; }
.account-tabs {
  position: relative; display: grid; grid-template-columns: repeat(4, 1fr);
  padding: 3px; background: var(--fill); border-radius: var(--r-m);
}
.acc-thumb {
  position: absolute; z-index: 0;
  top: 3px; bottom: 3px; left: 3px; width: calc((100% - 6px) / 4);
  border-radius: 11px; background: var(--surface);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .08);
  transition: transform .32s var(--spring);
}
.account-tabs:has(.account-tab:nth-child(2).active) .acc-thumb { transform: translateX(100%); }
.account-tabs:has(.account-tab:nth-child(3).active) .acc-thumb { transform: translateX(200%); }
.account-tabs:has(.account-tab:nth-child(4).active) .acc-thumb { transform: translateX(300%); }
.account-tab {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center; gap: 7px;
  min-width: 0;
  padding: 10px 12px; border-radius: 11px;
  color: var(--text-2); font-size: 12.5px; font-weight: 650; white-space: nowrap;
  transition: color .2s var(--ease);
}
.account-tab svg { width: 16px; height: 16px; flex: none; }
.account-tab.active { color: var(--text); background: transparent; box-shadow: none; }
@media (hover: hover) { .account-tab:hover { color: var(--text); } }
/* Меню-список кабинета: только мобильный sheet (см. §09-блок ниже) */
.account-menu { display: none; }
.account-mobile-cta { display: none; }
.account-view { flex: 1 1 auto; min-height: 0; width: 100%; padding: 20px clamp(18px, 4vw, 30px); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--accent-tint) transparent; transition: opacity .26s var(--ease), transform .26s var(--spring); touch-action: manipulation; }
.account-view.hidden { display: none !important; }
.account-view[hidden] { display: none !important; }
.account-view::-webkit-scrollbar { width: 4px; }
.account-view::-webkit-scrollbar-thumb { background: var(--accent-tint); border-radius: 10px; }
.account-subhead { margin: 18px 0 8px; color: var(--text-3); font-size: 10.5px; font-weight: 750; text-transform: uppercase; letter-spacing: .07em; }
.account-subhead:first-child { margin-top: 0; }
.account-note { color: var(--text-2); font-size: 12.5px; line-height: 1.6; }
.account-message { min-height: 20px; margin-top: 8px; color: var(--text-2); font-size: 12.5px; line-height: 1.5; }
.error-inline { color: var(--danger); }
.positive { color: var(--success); }
.negative { color: var(--text); }
.generation-status { color: var(--accent); }
.payment-link { color: var(--accent); font-weight: 650; }
.report-issue-btn { font-size: 12.5px; }
.empty-account, .account-state { padding: 24px; text-align: center; color: var(--text-3); font-size: 13px; }
.account-loading { display: grid; gap: 9px; padding: 0; }
.account-loading .skeleton { display: block; min-height: 58px; }
.account-loading .skeleton:first-child { min-height: 72px; }
.account-footer { display: none; flex: 0 0 auto; margin-top: 0; padding: 13px clamp(18px, 4vw, 30px) clamp(14px, 3vw, 20px); border-top: .5px solid var(--line); text-align: right; }

/* Пакеты */
/* Раньше колонки подбирались по содержимому (auto-fit) — на обычных узких
   телефонах это давало нужные 2×2, но на непривычно широких экранах
   (например, разложенный телефон-книжка) в ту же ширину помещалось 3-4
   колонки, и все пакеты сжимались в один ряд вместо заложенных двух.
   Явно фиксируем 2 колонки до общего порога «десктоп» — тогда результат не
   зависит от конкретной ширины устройства, только от того, планшет это или
   телефон в широком смысле. */
.packages-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (min-width: 769px) {
  .packages-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
.package-card {
  position: relative;
  display: flex; flex-direction: column;
  padding: 22px 14px 16px;
  border: 1.5px solid var(--hairline); border-radius: var(--r-l);
  background: var(--surface); text-align: center;
  transition: border-color .18s var(--ease), transform .3s var(--spring), box-shadow .3s var(--ease);
}
@media (hover: hover) { .package-card:hover { transform: translateY(-4px); box-shadow: var(--sh-2); } }
.package-card.is-best-value { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-tint); }
.package-card.is-selected { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-tint); }
.package-badge {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  padding: 4px 12px; border-radius: var(--r-pill);
  background: var(--accent); color: #fff;
  font-size: 11px; font-weight: 700; white-space: nowrap; z-index: 1;
  box-shadow: 0 5px 14px rgba(203, 17, 171, .3);
}
.package-generations { font-size: 34px; font-weight: 700; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.package-label { color: var(--text-2); font-size: 12.5px; margin-top: 2px; }
.package-price { margin: 12px 0 14px; font-size: 16px; font-weight: 650; }
/* Кнопка всегда прижата к низу карточки (margin-top:auto) — если у соседней
   плашки появляется доп. строка (бонус от промокода) и она становится выше,
   все карточки в ряду сетки и так растягиваются на одну высоту (Grid,
   align-items:stretch по умолчанию); без этого правила кнопка просто следовала
   бы за контентом и у карточек в одном ряду съезжала бы по высоте. */
.package-buy { min-height: 44px; width: 100%; font-size: 14px; margin-top: auto; }
/* Выбранный пакет — кнопка бледно-акцентная, чтобы отличаться от остальных
   серых «Купить», а не просто меняться текстом. */
.package-card.is-selected .package-buy { background: var(--accent-tint); color: var(--accent); }
.promo-row { display: grid; grid-template-columns: 1fr auto; gap: 10px; margin-top: 14px; }
.promo-row input { height: 48px; padding: 0 14px; font-size: 16px; }
.promo-apply-btn { height: 48px; min-height: 48px; padding: 0 22px; border-radius: var(--r-pill); background: var(--accent); color: #fff; font-size: 14px; font-weight: 650; white-space: nowrap; box-shadow: 0 5px 14px rgba(203, 17, 171, .24); transition: transform .3s var(--spring), background .18s var(--ease); }
@media (hover: hover) { .promo-apply-btn:hover:not(:disabled) { background: var(--accent-press); transform: translateY(-1px); } }
.promo-apply-btn:active:not(:disabled) { transform: scale(.97); }

/* Списки операций */
.account-list { display: grid; gap: 9px; }
.account-list-item {
  display: flex; justify-content: space-between; align-items: center; gap: 14px;
  padding: 13px 15px;
  border: .5px solid var(--hairline); border-radius: var(--r-m);
  background: var(--surface-2);
  transition: border-color .18s var(--ease), transform .3s var(--spring), box-shadow .3s var(--ease);
}
@media (hover: hover) { .account-list-item:hover { border-color: var(--accent-tint); transform: translateY(-1px); box-shadow: var(--sh-1); } }
.account-list-item div { min-width: 0; }
.account-list-item strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; }
.account-list-item span { display: block; margin-top: 3px; color: var(--text-3); font-size: 11.5px; }
.account-list-item b { flex: none; font-size: 13.5px; font-variant-numeric: tabular-nums; }

/* Рефералы */
.referral-box { padding: 18px; border: .5px solid var(--hairline); border-radius: var(--r-l); background: var(--accent-tint); }
.referral-box > span { display: block; color: var(--text-2); font-size: 11.5px; font-weight: 650; }
.referral-box strong { display: block; margin: 8px 0 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-size: 13.5px; }
.referral-box .primary-button { box-shadow: none; }
.referral-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: 9px; margin-top: 12px; }
.referral-stats div { padding: 14px; border-radius: var(--r-m); background: var(--surface); border: .5px solid var(--hairline); text-align: center; }
.referral-stats strong { display: block; font-size: 21px; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.referral-stats span { display: block; margin-top: 3px; color: var(--text-3); font-size: 10.5px; }

/* Поддержка (iMessage) */
.support-intro { display: flex; align-items: center; gap: 12px; padding: 14px; margin-bottom: 15px; border-radius: var(--r-l); background: var(--fill); border: .5px solid var(--line); }
.support-intro-icon { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 10px; background: var(--surface); color: var(--accent); box-shadow: var(--sh-1); flex: none; }
.support-intro-icon svg { width: 17px; height: 17px; }
.support-intro strong { display: block; font-size: 13px; }
.support-intro span { display: block; margin-top: 2px; color: var(--text-2); font-size: 11.5px; }
.ticket-card {
  width: 100%; display: block; text-align: left;
  padding: 15px 17px; border: .5px solid var(--hairline); border-radius: var(--r-m);
  background: var(--surface); color: var(--text);
  transition: transform .3s var(--spring), box-shadow .3s var(--ease);
}
@media (hover: hover) { .ticket-card:hover { transform: translateY(-2px); box-shadow: var(--sh-2); } }
.ticket-card:active { transform: scale(.98); }
.ticket-card-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 7px; }
.ticket-number { color: var(--text-3); font-size: 11px; font-weight: 750; letter-spacing: .05em; }
.ticket-card strong { display: block; font-size: 14.5px; }
.ticket-card > span:not(.ticket-number) { display: block; margin-top: 4px; color: var(--text-3); font-size: 11px; }
.ticket-card-preview { margin-top: 8px; color: var(--text-2); font-size: 12px; line-height: 1.5; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.ticket-thread-view { animation: modalIn .24s var(--ease) both; }
.ticket-thread-head { margin-bottom: 14px; }
.ticket-thread-title { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-top: 10px; }
.ticket-thread-title span { color: var(--text-3); font-size: 11.5px; font-weight: 750; }
.ticket-thread-title strong { font-size: 15.5px; }
.ticket-thread-title b { padding: 4px 9px; border-radius: var(--r-pill); background: var(--accent-tint); font-size: 10px; font-weight: 700; }
.ticket-thread-messages { display: flex; flex-direction: column; gap: 9px; max-height: 46vh; overflow-y: auto; padding: 4px 2px 12px; scrollbar-width: thin; }
.ticket-message {
  max-width: 84%; width: max-content;
  padding: 11px 14px; border-radius: 18px;
  font-size: 14px; line-height: 1.5;
  animation: modalIn .25s var(--spring) both;
  animation-delay: calc(var(--message-index, 0) * 70ms);
}
.ticket-message.is-user { align-self: flex-end; background: linear-gradient(180deg, #d531bd, #bb0da2); color: #fff; border-bottom-right-radius: 6px; }
.ticket-message.is-support { align-self: flex-start; background: var(--fill); color: var(--text); border-bottom-left-radius: 6px; }
.ticket-message-meta { margin-bottom: 4px; color: var(--text-3); font-size: 10px; font-weight: 650; }
.ticket-message.is-user .ticket-message-meta { color: rgba(255, 255, 255, .75); }
.ticket-reply-box { padding-top: 12px; border-top: .5px solid var(--line); }
.ticket-reply-box textarea { width: 100%; min-height: 84px; }
.ticket-reply-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ticket-reply-actions .account-message { flex: 1; }
.ticket-reply-actions .primary-button { width: auto; min-width: 140px; }

/* Настройки / опасная зона */
.settings-card { width: min(520px, 100%); max-height: min(92dvh, 860px); }
.settings-body { padding: 4px clamp(18px, 4vw, 30px) clamp(18px, 4vw, 30px); overflow-y: auto; overscroll-behavior: contain; }
.account-linked-accounts { margin-top: 14px; padding-top: 14px; border-top: .5px solid var(--line); }
.provider-states { margin-top: 10px; }
.provider-states .secondary-button { width: auto; min-height: 36px; padding: 0 14px; font-size: 12.5px; }
.provider-states .is-linked .d { color: var(--success); }
.account-actions-group { margin-top: 22px; }
.account-logout .t { color: var(--text); font-size: 15px; }
.account-logout[aria-busy="true"] { opacity: .65; }
.account-danger-zone { display: grid; gap: 13px; margin-top: 22px; padding: 18px; border: 1px solid var(--danger); border-radius: var(--r-l); background: var(--danger-bg); }
.account-danger-zone .account-subhead { margin: 0; color: var(--danger); }
.account-danger-zone .account-note { margin: 0; }
.account-danger-zone .field-label { display: block; line-height: 1.45; }
.account-danger-zone .field-label b { margin-left: .2em; }
.account-danger-zone .field-control { background: var(--surface); }
.account-danger-zone #delete-account-message { margin-top: 0; }
#delete-account-form { display: grid; gap: 13px; }

/* Подтверждение */
.confirm-modal .confirm-card { width: min(360px, calc(100vw - 40px)); max-height: min(90dvh, 560px); overflow-y: auto; padding: 26px 24px 0; border-radius: var(--r-l); text-align: center; }
.confirm-icon { width: 48px; height: 48px; margin: 0 auto 12px; display: grid; place-items: center; border-radius: 14px; background: var(--danger-bg); color: var(--danger); }
.confirm-icon svg { width: 24px; height: 24px; }
.confirm-card h3 { margin: 0 0 8px; font-size: 18.5px; font-weight: 700; letter-spacing: -.02em; }
.confirm-card p { margin: 0 0 20px; color: var(--text-2); font-size: 13.5px; line-height: 1.5; }
.confirm-actions { display: grid; grid-template-columns: 1fr 1fr; border-top: .5px solid var(--line); }
.confirm-actions .secondary-button, .confirm-actions .primary-button { border-radius: 0; min-height: 52px; box-shadow: none; background: transparent; color: var(--accent); font-size: 16px; }
.confirm-actions .secondary-button:hover:not(:disabled) { background: var(--fill); }
.confirm-actions .danger-button { color: var(--danger); border-left: .5px solid var(--line); background: transparent !important; box-shadow: none !important; }
.confirm-actions .danger-button:hover:not(:disabled) { background: var(--danger-bg) !important; }

/* ---------- 12. Toast ---------- */
#toast-root { position: fixed; top: calc(var(--topbar-h) + env(safe-area-inset-top, 0px) + 12px); left: 0; right: 0; z-index: 300; display: grid; justify-items: center; gap: 10px; pointer-events: none; padding: 0 16px; }
.toast {
  pointer-events: auto;
  display: flex; align-items: center; gap: 12px;
  width: min(400px, 100%);
  padding: 13px 16px; border-radius: 22px;
  background: var(--mat-nav);
  -webkit-backdrop-filter: saturate(180%) blur(22px); backdrop-filter: saturate(180%) blur(22px);
  border: .5px solid var(--hairline); box-shadow: var(--sh-float);
  transform: translateY(-24px) scale(.97); opacity: 0;
  transition: transform .32s var(--spring), opacity .32s var(--ease);
}
.toast.show { transform: none; opacity: 1; }
.toast.hide { transform: translateY(-24px) scale(.97); opacity: 0; }
.toast-ico {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--success-bg); color: var(--success);
}
.toast.err .toast-ico { background: var(--danger-bg); color: var(--danger); }
.toast-body { flex: 1; min-width: 0; }
.toast-close { width: 26px; height: 26px; margin-left: auto; flex: none; background: transparent; }
.toast-body b { display: block; font-size: 14px; }
.toast-body span { display: block; margin-top: 2px; color: var(--text-2); font-size: 12.5px; line-height: 1.45; }

/* ---------- 13. Скроллбары ---------- */
.auth-card, .otp-card, .settings-body, .account-view, .ticket-thread-messages {
  scrollbar-width: thin;
  scrollbar-color: var(--accent-tint) transparent;
}
.auth-card::-webkit-scrollbar, .otp-card::-webkit-scrollbar, .settings-body::-webkit-scrollbar,
.account-view::-webkit-scrollbar, .ticket-thread-messages::-webkit-scrollbar { width: 4px; height: 4px; }
.auth-card::-webkit-scrollbar-thumb, .otp-card::-webkit-scrollbar-thumb, .settings-body::-webkit-scrollbar-thumb,
.account-view::-webkit-scrollbar-thumb, .ticket-thread-messages::-webkit-scrollbar-thumb { background: var(--accent-tint); border-radius: 10px; }

/* ---------- Мобильный CTA-бар и кабинет-sheet (концепт §09) ---------- */
/* Плавающая стеклянная пилюля вместо жёсткой белой полосы */
.mobile-cta-bar {
  display: none;
  position: fixed; left: 0; right: 0; bottom: calc(14px + env(safe-area-inset-bottom, 0px)); z-index: 15;
  display: none; justify-content: center; pointer-events: none;
  padding: 0 16px;
}
.mobile-cta-bar .secondary-button {
  pointer-events: auto;
  width: auto; min-width: 230px; max-width: 100%;
  min-height: 50px; padding: 0 28px;
  background: var(--mat-nav);
  -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
  border: .5px solid var(--hairline);
  box-shadow: var(--sh-2);
  border-radius: var(--r-pill);
}
body.modal-open .mobile-cta-bar { display: none; }
body.generation-loading .mobile-cta-bar { display: none; }
@media (max-width: 768px) {
  .mobile-cta-bar { display: flex; }
}

/* Кабинет = нижний лист на мобильных */
.acc-grabber { display: none; }
.account-back { display: none; }
@media (max-width: 768px) {
  #account-modal { padding: 0; align-items: flex-end; }
  #account-modal .account-card {
    width: 100%; max-width: 100%;
    /* 100dvh пересчитывается прямо во время жеста скролла на iOS (адресная
       строка сворачивается/разворачивается) — окно кабинета могло слегка
       менять высоту прямо посреди свайпа, из-за чего верх контента уезжал
       и обрезался, даже когда прокручивать больше некуда. svh — гарантированно
       наименьшая высота вьюпорта, не меняется во время самого жеста. */
    height: 94svh; max-height: 94svh;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    animation-name: sheetUp;
  }
  #account-modal.is-closing .account-card { animation: modalOut .2s var(--ease) both; }
  .acc-grabber { display: block; flex: none; margin: 8px auto 0; touch-action: none; }
  .account-header { padding-top: 4px; background: none; }
  /* ...но это правило про ШТОРКУ кабинета: у неё сверху есть полоска-ручка,
     которая и создаёт нужный воздух. В окне настроек ручки нет, и тот же
     отступ в 4px прижимал надпись «Аккаунт» вплотную к краю экрана, вдобавок
     подводя её под кнопку закрытия. Возвращаем отступ только этому окну. */
  .settings-card .account-header { padding-top: 22px; }
  /* Меню-список вместо сегмент-вкладок */
  .account-tabs-scroll { display: none; }
  .account-menu { display: block; margin: 20px 14px 24px; }
  /* Пока раздел не открыт — показываем ТОЛЬКО меню (как в концепте) */
  .account-card:not(.in-view) .account-view { display: none !important; }
  .account-mobile-cta { display: inline-flex; width: 100%; min-height: 50px; font-size: 16px; }
  .acc-grabber { width: 44px; height: 5px; border-radius: 99px; background: var(--text-3); opacity: .55; margin: 10px auto 2px; position: relative; }
  /* Полоска нарисована тонкой, но именно на ней висят обработчики
     перетаскивания шторки — попасть пальцем в 5 пикселей трудно. Расширяем
     зону захвата по вертикали, не трогая внешний вид. */
  .acc-grabber::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 56px; height: 28px; transform: translate(-50%, -50%);
  }
  /* .row-i уже задаёт нужный вид (см. общее правило выше) — здесь только
     то, что специфично именно для мобильного списка меню кабинета. */
  .account-menu.group { border-radius: var(--r-l); }
  .row-i.clickable:active { background: var(--fill); }
  /* Открытый раздел скрывает меню, показывает «Назад» */
  .account-card.in-view .account-menu { display: none; }
  .account-card.in-view .account-back { display: inline-block; padding: 10px 16px 2px; }
  .account-view { padding-top: 8px; }
  #account-history { padding-top: 18px; }
  #account-history .group-caption:not(:first-child) { margin-top: 24px; }
  #generations-list .row-i {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) auto;
    align-items: center;
    row-gap: 6px;
  }
  #generations-list .r-icon { grid-column: 1; grid-row: 1 / span 2; align-self: start; }
  #generations-list .grow { grid-column: 2; grid-row: 1; }
  #generations-list .generation-status { grid-column: 3; grid-row: 1; margin: 0; white-space: nowrap; }
  #generations-list .report-issue-btn {
    grid-column: 2 / -1;
    grid-row: 2;
    justify-self: start;
    margin: 0;
    padding: 0;
    line-height: 1.35;
    text-align: left;
  }
  /* Нижний CTA вместо «Выйти» */
  .account-footer { display: grid; gap: 8px; text-align: center; border-top: .5px solid var(--line); }
  .account-mobile-cta { width: 100%; }
  .balance-info strong { font-size: 24px; }
  #account-modal .account-card.is-dragging { transform: translateY(var(--sheet-drag-y, 0)); transition: none; animation: none; }
}
.ticket-message.message-step-1 { animation-delay: 70ms; }
.ticket-message.message-step-2 { animation-delay: 140ms; }
.ticket-message.message-step-3 { animation-delay: 210ms; }
.ticket-message.message-step-4 { animation-delay: 280ms; }
.ticket-message.message-step-5 { animation-delay: 350ms; }
.ticket-message.message-step-6 { animation-delay: 420ms; }
.ticket-message.message-step-7 { animation-delay: 490ms; }
.ticket-message.message-step-8 { animation-delay: 560ms; }
.ticket-message.message-step-9 { animation-delay: 630ms; }
.referral-view { align-content: start; gap: 20px; }
.referral-view #referral-state { display: grid; gap: 20px; }
.referral-view .referral-link-row { gap: 18px; padding: 19px 20px; }
.referral-link-row .grow { min-width: 0; }
.referral-link { user-select: all; overflow-wrap: anywhere; }
.referral-link-row #copy-referral { width: auto; min-height: 42px; padding: 0 18px; flex: none; font-size: 13px; }
.referral-view .referral-stats { margin: 0; gap: 14px; }
.referral-stats .stat { min-height: 104px; padding: 20px 16px; }
.referral-footer { display: grid; gap: 14px; }
.referral-footer .account-note { margin: 0; }
.referral-share { width: 100%; min-height: 50px; gap: 8px; }
.referral-share .ico { width: 16px; height: 16px; }
@media (max-width: 520px) {
  .referral-view, .referral-view #referral-state { gap: 18px; }
  .referral-view .referral-link-row { align-items: stretch; flex-direction: column; gap: 14px; padding: 18px; }
  .referral-link-row #copy-referral { width: 100%; }
  /* Раньше здесь стояла одна колонка на узких телефонах — плашки короткие
     (подпись + число), места достаточно, чтобы все три стояли рядом и на
     самых узких экранах, поэтому больше не сворачиваем в один столбец. */
  .referral-stats .stat { min-height: 86px; padding: 12px 8px; }
  .referral-footer { gap: 16px; padding-bottom: 4px; }
}
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }

/* ---------- Мобильный CTA-бар и кабинет-sheet (конец) ---------- */
@media (max-width: 860px) {
  .container { width: min(100% - 24px, 640px); }
  .workspace { grid-template-columns: 1fr; }
  footer { width: calc(100% - 24px); }
  /* --- Компактный мобильный экран из концепта (§09) --- */
  .t-full, .hero-p-long { display: none; }
  .t-short { display: inline-block; }
  .hero-p-short { display: block; margin-top: 10px; }
  .signup-bonus { display: none; }
  .hero { padding: 18px 0 6px; }
  .hero h1 { font-size: 30px; line-height: 1.12; margin: 8px 0 0; }
  .eyebrow { font-size: 10px; margin-bottom: 2px; }
  .quick-info { display: none; }
  .label-full { display: none; }
  .label-short { display: inline; }
  .button-hero { height: 52px; font-size: 16px; margin-top: 12px; }
  .input-panel { position: relative; z-index: 1; padding: 16px; background: var(--surface); }
  .panel-head { margin-bottom: 14px; }
  .panel-head h2 { font-size: 18px; }
  .preview-stage { min-height: 300px; }
}
@media (max-width: 700px) {
  /* U-HIGH-07: 100dvh пересчитывается прямо во время жеста скролла на iOS —
     когда адресная строка сворачивается/разворачивается, высота меняется
     "на лету", из-за чего окно кабинета может слегка сдвигаться и обрезать
     контент сверху даже когда прокручивать больше некуда. 100svh — это
     гарантированно наименьшая высота вьюпорта, она не меняется во время
     самого жеста, только после его завершения. */
  .account-card { width: calc(100vw - 32px); max-height: calc(100svh - 32px); }
  .account-title-row { flex-direction: column; align-items: stretch; }
  .account-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
  .account-tabs::-webkit-scrollbar { display: none; }
  .account-tab { flex: 0 0 auto; scroll-snap-align: start; padding: 10px 13px; }
  .account-tab:first-child { margin-left: 3px; }
  .account-tab:last-child { margin-right: 3px; }
  .ticket-message { max-width: 92%; }
}
@media (max-width: 600px) {
  .account-status { display: none; }
  .topbar-balance { display: none; }
  .brand-subtitle { display: none; }
  .topbar { gap: 10px; }
  .auth-card { padding: 22px; }
  .topbar-auth { padding: 8px 14px; font-size: 13px; }
}
@media (max-width: 520px) {
  .actions { grid-template-columns: 1fr 1fr; gap: 8px; }
  .actions .primary-button { grid-column: 1 / -1; }
  .promo-row { grid-template-columns: 1fr; }
  .promo-apply-btn { width: 100%; }
  .package-card { padding: 15px 10px; }
  .package-generations { font-size: 26px; }
  .package-loading { grid-template-columns: 1fr; }
  .package-loading .skeleton { min-height: 90px; }
  .history-grid { display: flex; overflow-x: auto; padding: 0 1px 8px; scroll-snap-type: x proximity; }
  .history-item { flex: 0 0 132px; scroll-snap-align: start; }
}
/* Учет safe-area на iPhone */
@supports (padding: max(0px)) {
  .modal { padding: max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); }
  .account-footer { padding-bottom: max(clamp(14px, 3vw, 20px), env(safe-area-inset-bottom)); }
}

/* ---------- 14.1 Появление секций при скролле + pop стикера ----------
 * U-LOW-06: прячем только когда JS точно работает (html.js вешает app.js) —
 * без JS тарифы и FAQ остаются видимыми. */
html.js .reveal { opacity: 0; transform: translateY(22px); transition: opacity .6s var(--ease), transform .6s var(--spring); }
html.js .reveal.d1 { transition-delay: 80ms; }
html.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html.js .reveal.d1 { transition-delay: 0s; }
  .ticket-message, .ticket-thread-view { animation: none; }
  .account-view, .toast, .account-card { transition-duration: 0s; }
}
@keyframes stickerPop {
  0% { opacity: 0; transform: scale(.86) translateY(10px); }
  60% { opacity: 1; transform: scale(1.03) translateY(-2px); }
  100% { opacity: 1; transform: scale(1); }
}

/* --- Анимации из концепции, которых не хватало --- */
/* Тряска поля при ошибке (§ Поля: «ошибка = shake + красная рамка») */
@keyframes shake { 20% { transform: translateX(-6px); } 40% { transform: translateX(5px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(2px); } }
.shake { animation: shake .4s var(--ease); }
/* Подскок цифры OTP при заполнении (§ OTP) */
@keyframes otpPop { 50% { transform: translateY(-4px) scale(1.06); } }
.otp-digit.filled { animation: otpPop .34s var(--spring); }
/* Пульсирующая точка статуса «Ожидаем оплату» (§ Статусы) */
@keyframes pulseDot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.75); } }
.status-warn .pulse-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; animation: pulseDot 1.2s ease-in-out infinite; }
/* Скелетон-загрузка списков (§ Маппинг: «Загрузка…» → скелетоны shimmer) */
@keyframes shimmer { to { transform: translateX(100%); } }
.skeleton { position: relative; overflow: hidden; background: var(--fill); border-radius: var(--r-m); }
.generation-skeleton.skeleton { position: absolute; }
.skeleton::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), transparent);
  animation: shimmer 1.4s var(--ease) infinite;
}
[data-theme="dark"] .skeleton::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .09), transparent); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .skeleton::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .09), transparent); } }
.canvas-wrap.pop #sticker { animation: stickerPop .55s var(--spring) both; }

/* Fallback для старых iOS без dvh (Safari < 15.4) — U-LOW-02: полный список */
@supports not (height: 1dvh) {
  .account-card { max-height: calc(100vh - 32px); }
  .otp-card { max-height: 86vh; }
  .auth-card { max-height: 90vh; }
  .settings-card { max-height: 88vh; }
  .confirm-card { max-height: 80vh; }
  .admin-login { min-height: 100vh; }
}

/* U-INF-03: деградация «матового стекла» на слабых Android без backdrop-filter */
@supports not ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .topbar { background: var(--surface); }
  .toast { background: var(--surface); }
  .modal-backdrop { background: rgba(10, 8, 14, .88); }
}

/* Print profiles preserve intrinsic geometry. Disable printer “fit to page”. */
@page stickerLabel { size:58mm 40mm; margin:0; }
@page boxLabel { size:40mm 60mm; margin:0; }
@media print {
  @page {size:58mm 40mm;margin:0;}
  html,body {margin:0!important;padding:0!important;background:#fff!important;overflow:hidden!important;}
  body {page:stickerLabel;width:58mm!important;height:40mm!important;}
  body * {visibility:hidden!important;}
  #sticker {visibility:visible!important;position:fixed!important;left:11.667mm!important;top:-.8mm!important;width:34.667mm!important;height:41.6mm!important;transform:rotate(-90deg)!important;transform-origin:center!important;border-radius:0!important;box-shadow:none!important;}
  body[data-result-product="qr_return_box"] {page:boxLabel;width:40mm!important;height:60mm!important;}
  body[data-result-product="qr_return_box"] #sticker {left:0!important;top:0!important;width:40mm!important;height:60mm!important;transform:none!important;}
}

/* ===== Группированные списки (концепция § Кабинет): единая карточка с
   hairline-разделителями между строками, а не отдельная рамка/фон у каждой
   строки. Используется в кабинете, истории, рефералах, поддержке. ===== */
.group { background: var(--surface); border-radius: var(--r-l); border: .5px solid var(--hairline); overflow: hidden; }
.row-i {
  display: flex; align-items: center; gap: 14px; min-width: 0;
  padding: 15px 18px; border-bottom: .5px solid var(--line);
  font-size: 15.5px; color: var(--text);
  transition: background var(--t-fast, .18s) var(--ease);
  /* Строки настроек — частая цель двойного тапа (переключатели, кнопки).
     У <label>, оборачивающего чекбокс (как переключатели уведомлений), может
     быть собственное поведение по умолчанию в WebKit даже при touch-action
     на родителях — задаём явно на каждой строке, а не только на контейнере. */
  touch-action: manipulation;
}
.row-i:last-child { border-bottom: 0; }
@media (hover: hover) { .row-i.clickable:hover { background: var(--fill); cursor: pointer; } }
button.row-i { width: 100%; text-align: left; background: none; border: 0; border-bottom: .5px solid var(--line); font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
button.row-i:last-child { border-bottom: 0; }
.row-i .grow { flex: 1; min-width: 0; }
.row-i .t { display: block; font-weight: 550; }
.row-i .d { display: block; font-size: 12.5px; color: var(--text-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-i .val { color: var(--text-2); font-size: 14.5px; font-variant-numeric: tabular-nums; flex: none; }
.row-i .chev { color: var(--text-3); flex: none; transition: transform var(--t-fast, .18s) var(--ease); }
@media (hover: hover) { .row-i.clickable:hover .chev { transform: translateX(3px); } }
.r-icon { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; flex: none; background: var(--fill); color: var(--text-2); }
.r-icon svg { width: 16px; height: 16px; }
.r-icon-accent { background: var(--accent-tint); color: var(--accent); }
.amount-pos { color: var(--success); font-weight: 650; font-variant-numeric: tabular-nums; flex: none; }
.amount-neg { color: var(--text); font-weight: 650; font-variant-numeric: tabular-nums; flex: none; }
.group-caption { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); margin: 0 0 8px 2px; }
.group-caption:not(:first-child) { margin-top: 18px; }

/* Шапка кабинета: аватар+имя слева, count-up баланс справа (концепция § Кабинет,
   мобильный bottom-sheet — именно эта раскладка, без отдельного блока-градиента). */
.acc-header-row { display: flex; align-items: center; gap: 12px; padding: 2px 54px 2px 4px; }
.acc-header-row .avatar { width: 42px; height: 42px; font-size: 16px; }
.acc-balance { margin-left: auto; text-align: right; flex: none; }
.acc-balance .balance-num { font-size: 26px; font-weight: 700; letter-spacing: -.03em; line-height: 1; font-variant-numeric: tabular-nums; }
.acc-balance .balance-cap { font-size: 10.5px; color: var(--text-3); margin-top: 2px; }

.avatar { width: 54px; height: 54px; border-radius: 50%; flex: none; display: grid; place-items: center; background: linear-gradient(135deg, #cb11ab, #8324be); color: #fff; font-size: 20px; font-weight: 700; }

/* Плитки статистики (концепция § Кабинет → Рефералы, § Админка) */
/* Плашки статистики рефералов короткие (подпись + число) — порог в 170px
   был рассчитан на более крупные карточки аналитики и не давал всем трём
   плашкам встать в один ряд на обычных телефонах, не говоря уже о широких
   экранах. Уменьшаем минимум под их реальное содержимое. */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
/* .stat-grid и .referral-stats стоят на одном элементе одновременно —
   этот, более поздний по каскаду, порог 170px незаметно перебивал
   собственный порог .referral-stats (90px, объявлен раньше в файле),
   хотя тот и был рассчитан именно под короткое содержимое этих плашек.
   Фиксируем явно, чтобы порядок объявления в файле больше не решал. */
.referral-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stat { background: var(--surface); border: .5px solid var(--hairline); border-radius: var(--r-l); padding: 16px 18px; }
.stat span { font-size: 12px; font-weight: 600; color: var(--text-2); }
.stat strong { display: block; font-size: 30px; font-weight: 700; letter-spacing: -.03em; margin-top: 6px; font-variant-numeric: tabular-nums; }
.stat em { display: block; font-style: normal; font-size: 12px; color: var(--text-3); margin-top: 3px; }

/* Статус-бейдж (концепция § Поддержка/Админка): решено — зелёный, остальное —
   требует внимания (красный/приглушённый), а не просто цветной текст. */
.badge { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 7px; font-size: 11.5px; font-weight: 700; }
.badge.bdg-ok { background: var(--success-bg); color: var(--success); }
.badge.bdg-no { background: var(--danger-bg); color: var(--danger); }

/* Обычная пара кнопок бок о бок (концепция: окно сброса пароля) — в отличие
   от .confirm-actions (текстовые кнопки macOS-alert для окна удаления
   аккаунта), здесь обычные .secondary-button/.primary-button без переопределений. */
.dual-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 4px; }

/* iOS-тумблер (концепция § Компоненты) — вместо чекбокса с текстом
   "включено"/"выключено", используется и в клиентских настройках, и в админке. */
.switch { position: relative; width: 51px; height: 31px; flex: none; display: inline-block; }
.switch input {
  position: absolute; inset: 0; box-sizing: border-box;
  appearance: none; -webkit-appearance: none; width: 100%; height: 100%; margin: 0; padding: 0; border: 0;
  border-radius: var(--r-pill); background: var(--fill-2);
  transition: background var(--t-med, .32s) var(--ease); cursor: pointer; display: block;
}
.switch input:checked { background: var(--success); }
.switch input::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px;
  border-radius: 50%; background: #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,.25); transition: transform var(--t-med, .32s) var(--spring);
}
.switch input:checked::after { transform: translateX(20px); }
.visually-hidden { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }

/* Промокод: обычное поле — на ПК всегда видно (концепция: «не нужно скрывать
   поле с промокодом» на десктопе); на мобильном вместо него — компактная
   текстовая кнопка, открывающая то же самое в отдельном окне. */
.promo-open-btn { display: none; margin-top: 12px; }
/* Кнопка «Купить генерации» внутри вкладки «Пакеты» — нужна только на ПК:
   на мобильном для этого уже есть закреплённая снизу кнопка в подвале
   кабинета (.account-footer), дублировать её здесь не нужно. */
.packages-buy-cta { display: none; margin-top: 18px; }
@media (min-width: 769px) {
  .packages-buy-cta { display: inline-flex; }
}
@media (max-width: 768px) {
  .promo-row-desktop { display: none; }
  .promo-open-btn { display: inline-flex; }
}

/* Цена с учётом промокода — старая цена зачёркнута, новая — акцентным цветом
   (пересчёт происходит сразу при выборе пакета или применении промокода,
   без необходимости выбирать пакет заново). */
.promo-price-old { color: var(--text-3); font-weight: 500; text-decoration-color: var(--text-3); }
.promo-price-new { color: var(--accent); }
.promo-bonus { display: block; margin-top: 2px; font-size: 12px; font-weight: 650; color: var(--success); }

/* Стильный прелоадер для ожидания ответа сервера (OTP, отправка обращения и
   подобные долгие операции) — вместо просто заблокированных полей без
   объяснения показывает, что именно происходит, и даёт кнопку отмены, чтобы
   не ждать даже сокращённый таймаут. */
.pending-status {
  display: flex; align-items: center; gap: 10px;
  margin-top: 10px; padding: 11px 14px;
  background: var(--accent-tint); border-radius: var(--r-m);
  color: var(--accent); font-size: 13px; font-weight: 600;
  animation: pendingIn .25s var(--ease) both;
}
.pending-status .spinner { border-color: rgba(203, 17, 171, .25); border-top-color: var(--accent); }
.pending-status span.pending-text { flex: 1; }
.pending-status .pending-cancel {
  flex: none; color: var(--accent); font-size: 12.5px; font-weight: 700;
  text-decoration: underline; text-underline-offset: 2px;
}
@keyframes pendingIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* Переливающийся градиентный контур у карточек истории — только на мобильном.
   Один общий градиент на весь экран (background-attachment: fixed) — каждая
   карточка показывает лишь своё "окошко" в одну и ту же подложку, привязанную
   к вьюпорту, а не к себе самой: контур и иконка внутри одной карточки
   показывают один и тот же кусок ленты, поэтому их цвета всегда совпадают.
   border с градиентом не умеет border-radius, поэтому контур рисуется
   псевдоэлементом с маской (вырезаем середину, оставляя только тонкое кольцо).
   Палитра — та же, что и у заголовка «Одна секунда» (--grad-flow), для
   единства с остальным сайтом. Приглушённая прозрачность — эффект «под
   стеклом», серый фон карточки должен просвечивать сквозь цвет. */
.history-item { position: relative; border-color: transparent; background-clip: padding-box; }
.history-item::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  background: linear-gradient(90deg, #cb11ab, #e83a9c, #ff5e8a, #ff8a3d, #cb11ab, #e83a9c, #ff5e8a, #ff8a3d, #cb11ab);
  background-attachment: fixed;
  background-size: 250vw 100vh;
  opacity: .3;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  animation: historyBorderFlow 4.5s linear infinite;
  pointer-events: none;
}
/* Тот же общий градиент, но виден только внутри фигур QR-узора — маска
   строится из самой иконки в JS (см. historyQrIcon/renderHistory в app.js).
   Исходная серая иконка остаётся видна под ней приглушённо — для фактуры. */
.history-thumb { position: relative; }
.history-thumb svg { opacity: .35; }
.history-thumb .grad-mask {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, #cb11ab, #e83a9c, #ff5e8a, #ff8a3d, #cb11ab, #e83a9c, #ff5e8a, #ff8a3d, #cb11ab);
  background-attachment: fixed;
  background-size: 250vw 100vh;
  opacity: .45;
  animation: historyBorderFlow 4.5s linear infinite;
  -webkit-mask-size: 76% 76%; -webkit-mask-position: center; -webkit-mask-repeat: no-repeat;
  mask-size: 76% 76%; mask-position: center; mask-repeat: no-repeat;
}
@keyframes historyBorderFlow { to { background-position: -250vw 0; } }

/* ── Выбор продукта и фильтр истории ──
   Переиспользуют .auth-tabs/.seg-thumb — тот же переключатель, что в окне
   входа между «Телефон» и «Email», чтобы элемент был узнаваемым. */
.product-tabs { margin-bottom: 16px; }
.history-tabs { margin: 14px 0 18px; max-width: 340px; }
/* Префикс TRBX — неизменяемая часть номера коробки: показываем внутри поля,
   человек вводит только цифры. */
.field-prefix {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  font-size: 16px; font-weight: 650; color: var(--text-2); letter-spacing: .02em;
  pointer-events: none; user-select: none;
}
.field-wrap.has-prefix input { padding-left: 74px; }

/* Карточка QR коробки в истории: отличается от товарной тонкой цветной
   меткой, а не другим фоном — так обе выглядят частью одной коллекции. */
.history-item-box { position: relative; }
/* Метка — бейджем в углу миниатюры: не занимает строку в раскладке карточки
   и не толкает номер, которому нужна вся ширина. */
/* Метка «Коробка» — розовая плашка в потоке, прямо над номером. */
.history-tag {
  /* Карточка — не flex-контейнер, поэтому align-self не сработал бы:
     метка встаёт на свою строку через display:block. */
  display: block; width: fit-content;
  margin: 10px 0 5px; padding: 3px 9px;
  border-radius: var(--r-pill);
  background: var(--accent-tint); color: var(--accent);
  font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  pointer-events: none;
}
.history-item-box .history-code { letter-spacing: .01em; }
.history-empty {
  grid-column: 1 / -1; margin: 0; padding: 26px 4px;
  text-align: center; color: var(--text-3); font-size: 13.5px;
}

/* ── Подпись над выбором продукта + кнопка справки ── */
.help-dot {
  width: 13px; height: 13px; min-width: 13px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%; border: 1.2px solid var(--text-3); color: var(--text-3);
  background: none; cursor: pointer; padding: 0;
  position: relative;
  transition: color .18s var(--ease), border-color .18s var(--ease), transform .3s var(--spring);
}
/* Точка нарисована мелкой намеренно — она не должна спорить с заголовком.
   Но нажимать в 13 пикселей пальцем неудобно, и это ниже нормы (минимум
   24x24). Расширяем только область нажатия, вид не меняется. */
.help-dot::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 24px; height: 24px; transform: translate(-50%, -50%);
}
.help-dot svg { width: 8px; height: 8px; }
@media (hover: hover) { .help-dot:hover { color: var(--accent); border-color: var(--accent); transform: scale(1.12); } }
.help-dot:active { transform: scale(.9); }

/* ── Окно справки ── */
.help-card { max-width: 520px; text-align: left; }
.help-item { display: flex; gap: 14px; align-items: flex-start; margin-top: 18px; }
.help-visual {
  flex: none; width: 96px; padding: 10px 8px;
  border-radius: var(--r-m); background: var(--fill); color: var(--text-2);
}
.help-visual svg { width: 100%; height: auto; display: block; }
.help-text h3 { margin: 0 0 5px; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.help-text p { margin: 0 0 6px; font-size: 13px; line-height: 1.5; color: var(--text-2); }
.help-sample { color: var(--text-3) !important; font-size: 12.5px !important; }
.help-sample b { color: var(--text); font-weight: 650; }
.help-note {
  margin: 20px 0 0; padding: 11px 13px;
  border-radius: var(--r-m); background: var(--accent-tint);
  color: var(--accent); font-size: 12.5px; font-weight: 600; line-height: 1.45;
}
@media (max-width: 520px) {
  .help-item { gap: 12px; }
  .help-visual { width: 74px; }
}

/* ── Шапка раздела истории: вкладки и «Очистить» в одну линию ── */
/* Карточка QR коробки шире: номер TRBX+10 цифр должен помещаться целиком */
.history-grid:has(.history-item-box) { grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); }
@media (max-width: 768px) { .history-item-box { flex: 0 0 176px; } }

/* На узком экране заголовок раздела и инструменты не помещаются в одну
   строку — заголовок переносился, а вкладки наезжали. Раскладываем в две
   строки: заголовок сверху, под ним вкладки и «Очистить» на всю ширину. */

/* Заголовок панели с кнопкой справки на одной линии */
/* Кнопка-вопрос должна оставаться рядом с текстом заголовка на любой
   ширине экрана — раньше при нехватке места переносилась на отдельную
   строку. Сам заголовок при этом по-прежнему может переноситься на две
   строки внутри своего блока — min-width:0 разрешает это span'у. */
.panel-title-with-help { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
.panel-title-with-help span { min-width: 0; }
.panel-title-with-help .help-dot { margin-top: 1px; }

/* ── Вкладки истории: иконка + название + счётчик ──
   Счётчик сразу показывает, сколько в каждой категории, — переключатель
   перестаёт быть «слепым»: видно, есть ли там что-то, ещё до клика. */

/* ── Раздел истории: заголовок+«Очистить» в шапке, переключатель ниже ──
   Подложка — фирменный розовый тон (тот же accent-tint, что у плашек
   «+1 генерация»/баланса), а не серый: на сером фоне страницы серая же
   подложка почти сливалась. Активный сегмент — сплошная белая «плашка»,
   приподнятая тенью над розовой подложкой — контраст читается сразу. */
#history-section .section-head { margin-bottom: 10px; }
.history-tabs {
  margin: 0; max-width: 360px;
  /* Белый трек, серый бегунок активной вкладки — тот же порядок цветов,
     что и остальная палитра сайта (--surface/--fill-2), только сама пара
     переставлена местами по сравнению с обычным .auth-tabs. */
  background: var(--surface);
}
/* Крупнее на десктопе — переключатель соразмерен заголовку раздела. */
.history-tabs .auth-tab { display: flex; align-items: center; justify-content: center; gap: 9px; padding: 15px 14px; font-size: 15px; }
.history-tabs .htab-ic { width: 17px; height: 17px; flex: none; opacity: .6; transition: opacity .22s var(--ease); }
.history-tabs .auth-tab.active .htab-ic { opacity: 1; }
/* Бегунок в светлой теме — мягкий, как заливка кнопок в пакетах, а не
   тёмно-серый: он не должен спорить с активным текстом. */
.history-tabs .seg-thumb { background: var(--fill); box-shadow: none; }
@media (prefers-color-scheme: dark) {
  .history-tabs { background: var(--surface); }
}
/* Карточки с кодами — заметно ниже переключателя, а не впритык к нему. */
.history-tabs + .history-grid { margin-top: 22px; }
@media (max-width: 700px) {
  /* На всю ширину панели, но не впритык к её собственным краям — те же
     отступы, что и у карточек истории под переключателем. */
  .history-tabs { max-width: none; width: 100%; }
  .history-tabs .auth-tab { padding: 11px 8px; font-size: 13.5px; }
}

/* На главной активная вкладка — текст и иконка фирменным цветом.
   Окно авторизации (.auth-tabs без этих классов) сохраняет прежний вид.
   Цвет берётся из --accent-text, как у всех остальных надписей фирменного
   цвета: --accent рассчитан на крупный знак, и мелкой подписью на серой
   дорожке переключателя он не добирал до нормы контраста — 4.47 в светлой
   теме и 3.95 в тёмной при требуемых 4.5 (замерено). */
.product-tabs .auth-tab.active,
.history-tabs .auth-tab.active { color: var(--accent-text); }
.history-tabs .auth-tab.active .htab-ic { opacity: 1; color: var(--accent-text); }

/* П.2: на мобильных карточки истории прокручиваются вбок — системная серая
   полоса выглядит инородно. Прячем её и рисуем свою, тонкую и фирменную,
   с отступом от карточек. */
@media (max-width: 768px) {
  .history-grid { scrollbar-width: thin; scrollbar-color: var(--accent-tint) transparent; padding-bottom: 14px; }
  .history-grid::-webkit-scrollbar { height: 3px; }
  .history-grid::-webkit-scrollbar-track { background: transparent; }
  .history-grid::-webkit-scrollbar-thumb { background: var(--accent-tint); border-radius: var(--r-pill); }
  .history-grid::-webkit-scrollbar-thumb:active { background: var(--accent); }
}

/* Кнопка покупки во время создания платежа: приглушена и с «бегущим»
   бликом — видно, что запрос идёт, а не что сайт завис. */
.primary-button.is-loading, .secondary-button.is-loading {
  position: relative; overflow: hidden; cursor: progress; opacity: .85;
}
/* Блик проходит кнопку целиком. Раньше он дополз только до середины и
   пропадал: полоса была шире кнопки (220%), а диапазон сдвига — короче,
   чем нужно для полного прохода. Теперь полоса ровно по ширине кнопки и
   смещается от края до края. */
.primary-button.is-loading::after, .secondary-button.is-loading::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 100%;
  background: linear-gradient(100deg, transparent 35%, rgba(255,255,255,.30) 50%, transparent 65%);
  animation: ctaShimmer 1.25s linear infinite;
  pointer-events: none;
}
@keyframes ctaShimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* Вкладки истории в кабинете — три сегмента вместо двух. */
.hist-seg { grid-template-columns: repeat(3, 1fr); margin-bottom: 16px; }
/* Ширина считается точно: из полной ширины вычитаем внутренние поля (5px
   слева и справа) и два промежутка по 2px, остаток делим на три. Округлённые
   33.333% давали бегунок шире колонки, и на третьей позиции он подъезжал
   вплотную к правому краю. */
.hist-seg .seg-thumb { width: calc((100% - 14px) / 3); }
.hist-seg[data-active="1"] .seg-thumb { transform: translateX(calc(100% + 2px)); }
.hist-seg[data-active="2"] .seg-thumb { transform: translateX(calc(200% + 4px)); }
.hist-pane.hidden { display: none; }

.hist-seg .auth-tab { display: flex; align-items: center; justify-content: center; gap: 6px; }
.hist-seg .hseg-ic { width: 15px; height: 15px; flex: none; opacity: .6; transition: opacity .22s var(--ease); }
.hist-seg .auth-tab.active .hseg-ic { opacity: 1; }
@media (max-width: 420px) {
  /* На узком экране три подписи с иконками не помещаются — прячем текст,
     оставляя иконки: сами вкладки остаются различимыми и нажимаемыми. */
  .hist-seg .auth-tab { gap: 6px; font-size: 12px; padding-left: 4px; padding-right: 4px; }
  .hist-seg .hseg-ic { width: 17px; height: 17px; }
  .hist-seg .auth-tab span { display: none; }
  .hist-seg .auth-tab.active span { display: inline; }
}

/* Ссылка-кнопка «Вернуться к оплате» в сообщении о платеже. */
.link-button {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--accent); font: inherit; font-weight: 650;
  text-decoration: underline; text-underline-offset: 2px;
}
@media (hover: hover) { .link-button:hover { opacity: .8; } }

/* Прелоадер на кнопке «Применить» у промокода: она видна поверх модального
   окна, в отличие от «Купить генерации», которая остаётся под ним. */
.promo-apply-btn.is-loading {
  position: relative; overflow: hidden; cursor: progress; opacity: .85;
}
.promo-apply-btn.is-loading::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 100%;
  background: linear-gradient(100deg, transparent 35%, rgba(255,255,255,.35) 50%, transparent 65%);
  animation: ctaShimmer 1.25s linear infinite; pointer-events: none;
}

/* ── Режим незавершённой оплаты ──
   Не «серый экран», а мягкое приглушение: оплачиваемый пакет остаётся ярким
   и выделенным, остальные уходят на второй план и не нажимаются. Так видно,
   что именно покупается, и нельзя случайно начать второй платёж. */
.package-card.is-dimmed {
  opacity: .38; filter: saturate(.5);
  pointer-events: none; user-select: none;
  transition: opacity .25s var(--ease), filter .25s var(--ease);
}
.package-card.is-locked-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-tint), var(--sh-2);
}
.cancel-payment-row { display: flex; justify-content: center; margin-top: 10px; }
.cancel-payment-row .text-button { color: var(--text-3); font-size: 13.5px; }
@media (hover: hover) { .cancel-payment-row .text-button:hover { color: var(--danger, #ff3b30); } }
.cancel-payment-row.hidden { display: none; }

/* Плашка «Выгоднее всего» выступает над карточкой на 11px. Когда над сеткой
   вплотную стоит кнопка «Меню кабинета», плашка обрезалась её областью —
   добавляем сетке верхний отступ ровно под этот выступ. */
.packages-grid { margin-top: 14px; }

/* Форма привязки email в настройках аккаунта */
.email-link-form { padding: 14px; margin: 4px 0 8px; border-radius: var(--r-m); background: var(--fill); display: grid; gap: 10px; }
.email-link-form.hidden { display: none; }
/* Кнопки друг под другом: основная на всю ширину, «Отмена» под ней —
   простым текстом без рамок, чтобы не спорить с основным действием. */
.email-link-actions { display: grid; gap: 8px; justify-items: stretch; }
.email-link-actions .primary-button { width: 100%; }
.email-link-actions .text-button { justify-self: center; padding: 6px 10px; color: var(--text-3); font-size: 13.5px; }
@media (hover: hover) { .email-link-actions .text-button:hover { color: var(--text-2); } }
.email-link-message { margin: 0; font-size: 12.5px; color: var(--text-3); line-height: 1.45; }
.email-link-message.error-inline { color: var(--danger, #ff3b30); }

/* Предложение установить приложение — снизу, не перекрывает работу. */
.install-hint {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 12px));
  z-index: 90; display: grid; gap: 14px;
  width: min(560px, calc(100% - 24px));
  padding: 12px 14px; border-radius: var(--r-l);
  background: var(--surface); box-shadow: var(--sh-2);
  animation: installIn .4s var(--spring) both;
}
.install-hint-text { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--text-2); }
.install-hint .primary-button { width: 100%; padding: 10px 18px; font-size: 14px; }
@keyframes installIn { from { opacity: 0; transform: translate(-50%, 20px); } to { opacity: 1; transform: translateX(-50%); } }

/* Контакт для чека: только после попытки покупки без email и телефона. */
.contact-hint {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px; margin-bottom: 14px;
  border-radius: var(--r-m); background: var(--accent-tint);
  scroll-margin-block: 12px;
}
.contact-hint.hidden { display: none; }
.contact-hint-text { flex: 1 1 0; min-width: 0; display: grid; gap: 3px; }
.contact-hint-text b { font-size: 14.5px; color: var(--accent); }
.contact-hint-text span { font-size: 12.5px; color: var(--text-2); line-height: 1.45; }
.contact-hint .primary-button { flex: 0 1 25%; width: auto; max-width: 25%; min-width: 0; padding: 11px 12px; font-size: 14px; white-space: normal; }
@media (max-width: 599px) {
  .contact-hint { flex-direction: column; align-items: stretch; }
  .contact-hint-text { flex: auto; }
  .contact-hint .primary-button { flex: none; width: 100%; max-width: none; }
}

/* ── Установка приложения ── */
/* Окно с инструкцией: на iPhone показываем шаги, на Android — кнопку. */
.install-card { max-width: 500px; text-align: left; }
.install-heading, .disclosure-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.install-heading h2 { min-width: 0; margin: 0; font-size: clamp(18px, 4vw, 22px); line-height: 1.25; letter-spacing: -.025em; }
.install-hint .install-heading h2 { font-size: 18px; }
.compact-close { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 44px; min-width: 44px; min-height: 44px; padding: 0; border: 0; background: none; color: var(--text); font: inherit; font-size: 12px; cursor: pointer; }
.close-circle { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--fill); color: var(--text-2); font-size: 21px; line-height: 1; transition: background .2s, transform .2s; }
.close-circle svg { width: 16px; height: 16px; }
.compact-close:hover .close-circle { background: var(--fill-2); }
.compact-close:active .close-circle { transform: scale(.92); }
/* Клавиатурный фокус виден по заливке самого кружка, без внешней обводки. */
/* Фокус больше НЕ выворачивает крестик в чёрный кружок: на светлой теме это
   выглядело как посторонний чёрный элемент поверх светлого окна, причём
   появлялось само — окно при открытии ставит фокус на крестик. Кружок везде
   остаётся серым, а видимость фокуса даёт кольцо фирменного цвета. */
.modal-close:focus-visible > svg, .compact-close:focus-visible .close-circle {
  background: var(--fill-2); color: var(--text);
  box-shadow: 0 0 0 1.5px var(--accent), 0 0 0 5px var(--accent-tint);
}
.install-step-highlight { color: var(--accent); }
.expandable-panel { display: grid; grid-template-rows: 0fr; opacity: 0; visibility: hidden; transition: grid-template-rows .3s var(--ease), opacity .25s var(--ease), visibility 0s .3s; }
.expandable-panel.is-open { grid-template-rows: 1fr; opacity: 1; visibility: visible; transition: grid-template-rows .3s var(--ease), opacity .25s var(--ease), visibility 0s; }
.expandable-inner { min-height: 0; overflow: hidden; }
.delete-account-toggle { justify-self: start; padding: 8px 0; margin-top: 18px; border: 0; background: none; color: var(--danger); }
#delete-account-panel .account-danger-zone { margin-top: 8px; }
.disclosure-heading .account-subhead { min-width: 0; }
@media (prefers-reduced-motion: reduce) { .expandable-panel, .expandable-panel.is-open { transition: none; } }
.install-lead { margin: 6px 0 18px; font-size: 13.5px; line-height: 1.55; color: var(--text-2); }
.install-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.install-steps.hidden { display: none; }
.install-steps li { display: flex; align-items: flex-start; gap: 12px; font-size: 14px; line-height: 1.5; }
.install-num {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  background: var(--accent-tint); color: var(--accent);
  display: grid; place-items: center; font-size: 12.5px; font-weight: 700;
}
.install-inline-ic { width: 17px; height: 17px; vertical-align: -3px; margin-left: 3px; color: var(--accent); }
.install-action { margin-top: 4px; }
.install-action.hidden { display: none; }
.install-action .primary-button { width: 100%; }
.install-note { margin: 14px 0 0; font-size: 13px; color: var(--text-3); line-height: 1.5; }
.install-note.hidden { display: none; }

/* Focused, accessible refinements; G2 branding stays unchanged. */
.package-card.is-best-value:not(.is-selected){border-color:var(--hairline);box-shadow:none;}
.package-card.is-selected{border-width:2px;box-shadow:0 0 0 2px var(--accent-tint);}
.package-badge{box-shadow:none;background:linear-gradient(var(--accent-tint),var(--accent-tint)),var(--surface);color:var(--accent-text);padding:5px 12px;font-size:11.5px;font-weight:650;}
/* Когда «Выгоднее всего» ещё и выбран — бледная плашка на бледной рамке
   выбора визуально терялась. Делаем заливку значка тем же цветом, что и
   рамка карточки (var(--accent)), а текст — белым, чтобы выбор читался
   однозначно, а не сливался с остальными карточками. */
.package-card.is-best-value.is-selected .package-badge{background:var(--accent);color:#fff;}
.history-more{display:block;margin:16px auto;min-height:44px;}
.is-signed-in .hero{padding:36px 0 28px;text-align:center;}
.is-signed-in .hero h1{margin:0;font-size:clamp(30px,4.5vw,52px);line-height:1.12;letter-spacing:-.035em;text-wrap:balance;}
.orb-page{opacity:.45;}
.primary-button,.promo-apply-btn{box-shadow:0 4px 12px rgba(160,15,135,.16);}
[data-theme="dark"] .primary-button,[data-theme="dark"] .topbar-auth,[data-theme="dark"] .promo-apply-btn{background:#ad138f;color:#fff;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]) .primary-button,:root:not([data-theme="light"]) .topbar-auth,:root:not([data-theme="light"]) .promo-apply-btn{background:#ad138f;color:#fff;}}
@media(prefers-reduced-motion:reduce){.account-delete-panel,.users-filters-panel{transition:none!important;}}


/* Text contrast is independent from the brighter G2 brand mark. */
:root{--accent-text:#8b0074;--hint-text:#5c5c64;}
[data-theme="dark"]{--accent-text:#ff83df;--hint-text:#c4c4cd;}
@media(prefers-color-scheme:dark){:root:not([data-theme="light"]){--accent-text:#ff83df;--hint-text:#c4c4cd;}}
#signup-bonus-text,.contact-hint-text b,.package-card.is-selected .package-buy{color:var(--accent-text);}
.contact-hint-text span{color:var(--hint-text);}

/* Согласованные UI-правки 1–7: рабочая главная, компактная шапка и подвал. */
.signed-in-only { display: none; }
.is-signed-in .signed-in-only { display: block; }
.is-signed-in .guest-only,
.is-signed-in .hero-inner, .is-signed-in .hero > .orb,
.is-signed-in #pricing-section, .is-signed-in #faq-section,
.is-signed-in #history-section { display: none; }
.is-signed-in .workspace-balance { display: flex; }
.workspace-balance { align-items: center; justify-content: space-between; gap: 12px; margin: -2px 0 12px; padding: 0 2px; font-size: 13px; color: var(--text-2); }
#generator-balance { min-width: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.balance-value { font-weight: 650; font-variant-numeric: tabular-nums; }
.balance-value[data-balance-level="low"] { color: var(--danger); }
.balance-value[data-balance-level="medium"] { color: var(--balance-medium); }
.balance-value[data-balance-level="high"] { color: var(--success); }
.workspace-balance .text-button { flex: none; min-height: 44px; padding: 8px 0 8px 12px; color: var(--accent-text); }
.recent-files-section { margin-top: 32px; }
.recent-files-section .section-head { align-items: center; gap: 12px; margin-bottom: 14px; }
.recent-files-section h2 { margin: 0; font-size: 21px; letter-spacing: -.02em; }
#recent-files-all { min-height: 44px; flex: none; color: var(--accent-text); }
.recent-files-list { border: .5px solid var(--hairline); background: var(--surface); border-radius: var(--r-l); overflow: hidden; }
.recent-file { display: flex; align-items: center; gap: 14px; padding: 12px 18px; min-width: 0; }
.recent-file + .recent-file { border-top: .5px solid var(--line); }
.recent-file-kind { display: grid; place-items: center; width: 38px; height: 38px; flex: none; border-radius: 11px; background: var(--fill); color: var(--text-2); font-size: 12px; font-weight: 650; }
.recent-file-info { display: grid; gap: 4px; min-width: 0; flex: 1; }
.recent-file-info strong { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.recent-file-info > span { font-size: 12px; color: var(--text-2); }
.recent-file-download { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 0 8px 8px; font-size: 13px; flex: none; color: var(--accent-text); }
.recent-files-note { margin: 0; padding: 20px; border: 1px dashed var(--hairline); border-radius: var(--r-l); color: var(--text-2); font-size: 14px; }
.recent-files-note .text-button { min-height: 44px; color: var(--accent-text); }
@media screen and (min-width: 861px) {
  .customer-page { --topbar-h: 80px; }
  .is-signed-in .workspace { align-items: start; }
  .is-signed-in .preview-stage { min-height: 380px; }
  .is-signed-in .preview-stage:not(:has(#sticker.has-content)) .canvas-wrap { width: min(280px, 100%); }
}
@media (max-width: 1000px) {
  footer { grid-template-columns: 1fr; gap: 24px; }
  .footer-brand { max-width: 640px; }
}
@media (max-width: 860px) {
  .topbar { gap: 12px; padding: calc(8px + env(safe-area-inset-top, 0px)) max(16px, env(safe-area-inset-right, 0px)) 8px max(16px, env(safe-area-inset-left, 0px)); }
  .topbar .brand { flex: 0 1 auto; }
  .topbar .brand-logo { width: clamp(120px, 34vw, 172px); min-width: 0; }
  .topbar .brand-caption { display: none; }
  .topbar .theme-toggle { width: 44px; height: 44px; flex: none; }
  .topbar-auth { min-height: 44px; padding: 8px 14px; font-size: 13px; }
  .is-signed-in .hero { padding: 26px 4px 20px; }
  .recent-files-section { margin-top: 24px; }
  .recent-file { padding: 12px; gap: 10px; }
  .recent-file-download { max-width: 110px; }
  .footer-brand { grid-template-columns: 132px minmax(0, 1fr); gap: 20px; }
  .footer-brand-head .brand-logo { width: 132px; }
}
@media screen and (max-width: 860px) {
  .is-signed-in:not(.generation-loading) .preview-panel:not(:has(#sticker.has-content)) { display: none; }
}
@media (max-width: 600px) {
  .is-signed-in .hero .workspace-heading { font-size: clamp(26px, 6.7vw, 28px); }
}
@media (max-width: 379px) {
  .footer-brand { grid-template-columns: 1fr; gap: 14px; }
  .recent-file-kind { display: none; }
  .recent-files-section h2 { font-size: 19px; }
}

/* Device-scoped push controls; the shared modal manager owns focus and inert. */
.push-settings{margin:24px 0}.push-settings>.account-note{margin:6px 0 12px}.push-switch-row{cursor:pointer;gap:16px}.push-switch-row .grow{min-width:0}
.notification-channel-title{margin-top:22px}.notification-channel-title+.account-note{margin:6px 0 12px}
.push-switch{position:relative;display:inline-flex;flex:0 0 51px;width:51px;height:31px;touch-action:manipulation}.push-switch input{position:absolute;inset:0;opacity:0;width:100%;height:100%;margin:0;cursor:pointer;z-index:1;touch-action:manipulation}.push-switch>span{width:51px;height:31px;background:var(--fill,#d9d9e0);border-radius:99px;transition:background .2s;box-shadow:inset 0 0 0 1px #88889122}.push-switch>span::after{content:"";display:block;width:27px;height:27px;margin:2px;border-radius:50%;background:#fff;box-shadow:0 2px 5px #0003;transition:transform .2s}.push-switch input:checked+span{background:#34c759}.push-switch input:checked+span::after{transform:translateX(20px)}.push-switch input:focus-visible+span{outline:3px solid var(--accent);outline-offset:4px}.push-switch input:disabled{cursor:not-allowed}.push-switch input:disabled+span{opacity:.45}
.push-consent{margin:12px 2px;font-size:12px;line-height:1.55;color:var(--text-2)}.push-consent summary{cursor:pointer;padding:5px 0}.push-consent p{margin:8px 0}.push-settings-actions{display:flex;flex-wrap:wrap;gap:8px 18px}.push-settings-actions button{min-height:36px;font-size:12px}
.push-modal .modal-backdrop{background:#150e2050;backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px)}.push-card{position:relative;z-index:1;width:min(440px,100%);max-height:calc(100dvh - 40px);overflow-y:auto;padding:32px 28px 24px;border:1px solid #ffffff99;border-radius:32px;background:linear-gradient(145deg,#fffffff5,#f7f2ffe8);color:#211a2c;box-shadow:0 24px 90px #27113638,inset 0 1px 0 #fff;backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);text-align:center;animation:modalIn .25s var(--ease)}.push-close{position:absolute;right:10px;top:10px;padding:0;border:0;box-shadow:none}
/* Match the site's neutral close buttons; keyboard focus changes fill, not outline. */
#push-close{outline:0;box-shadow:none}
#push-close .close-circle{border:0;outline:0;box-shadow:none;background:var(--fill);color:var(--text-2);transition:background .2s,color .2s,transform .2s}
#push-close:hover .close-circle,#push-close:focus-visible .close-circle{background:var(--fill-2);color:var(--text)}
.push-close svg{width:19px;height:19px}.push-bell{width:72px;height:72px;margin:5px auto 20px;filter:drop-shadow(0 8px 16px #c52aa833)}.push-bell svg{width:100%;height:100%}.push-card h2{font-size:clamp(23px,5.8vw,29px);line-height:1.12;letter-spacing:-.04em;margin:0 0 14px}.push-card p{font-size:14px;line-height:1.55;color:#62596c;margin:0 0 15px}.push-card #push-prompt-status:empty{display:none}.push-card>button:not(.push-close){display:block;width:100%;min-height:48px}.push-card #push-enable{border-radius:17px;margin-top:20px}
html[data-theme="dark"] .push-card{background:linear-gradient(145deg,#2e2537f5,#1e1a27f0);color:#faf5ff;border-color:#ffffff21;box-shadow:0 24px 90px #0006,inset 0 1px 0 #ffffff12}html[data-theme="dark"] .push-card p{color:#c4b8ce}
@media(max-width:600px){.push-modal{align-items:end;padding:12px 10px max(10px,env(safe-area-inset-bottom))}.push-card{width:100%;border-radius:30px;padding:27px 23px max(22px,env(safe-area-inset-bottom));max-height:calc(100dvh - 24px)}.push-bell{width:65px;height:65px;margin-bottom:17px}}
@media(prefers-reduced-motion:reduce){.push-card{animation:none}.push-switch>span,.push-switch>span::after{transition:none}}
.push-switch-row .t,.push-switch-row .d{white-space:normal;overflow:visible;text-overflow:clip}
.push-switch input:checked+span{background:linear-gradient(135deg,#da0bac,#a12cc9)}
.push-card{animation:pushSheetIn .25s ease-out both}
@keyframes pushSheetIn{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:translateY(0)}}
@media(prefers-reduced-motion:reduce){.push-card{animation:none}}

/* Экран загрузки при первом визите без сохранённой подсказки о входе —
   закрывает страницу целиком, пока не станет известен реальный статус.
   Логотип в стилистике иконки приложения; фон и вариант логотипа следуют
   уже определённой (theme-init.js) теме, чтобы сам экран загрузки не
   создавал собственную вспышку не того цвета. */
.app-preloader {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg);
  transition: opacity .35s var(--ease, ease), visibility .35s var(--ease, ease);
}
.app-preloader.is-hidden { opacity: 0; visibility: hidden; pointer-events: none; }
/* Размер логотипа на заставке. Было жёстко 88px на всех экранах — заметно
   мельче собственного размера макета (140×113) и терялось на больших экранах.
   clamp даёт «немного больше» везде: на узком телефоне нижняя граница 112px
   (против прежних 88), на планшете и десктопе — 148px, что примерно совпадает
   с натуральным размером и не требует апскейла (логотип всё равно SVG). */
.app-preloader-logo { width: clamp(112px, 22vw, 148px); display: block; }
/* display здесь задавать НЕЛЬЗЯ. Внутри лежат два варианта логотипа
   (.brand-on-light и .brand-on-dark), и нужный выбирается правилами
   .brand-on-* выше. Селектор `.app-preloader-logo img` специфичнее
   `.brand-on-dark` и стоит ниже по файлу — поэтому `display: block` здесь
   перебивал скрытие ненужного варианта, и на заставке показывались ОБА
   логотипа сразу, один под другим. Размеры .brand-mark задаёт сам. */
.app-preloader-logo img { width: 100%; height: auto; }
/* Встроенный знак заставки. Цвет слова «WB» переключается по теме теми же
   правилами, что и остальные варианты логотипа (см. .brand-on-* выше), только
   без второго файла: сам рисунок один, меняется currentColor. */
.app-preloader-logo { color: #0E0C13; }
[data-theme="dark"] .app-preloader-logo { color: #FFFFFF; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .app-preloader-logo { color: #FFFFFF; }
}
.app-preloader-mark { width: 100%; height: auto; display: block; }
@media (prefers-reduced-motion: no-preference) {
  .app-preloader-logo { animation: app-preloader-pulse 1.6s ease-in-out infinite; }
}
@keyframes app-preloader-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .55; transform: scale(.94); }
}


/* Полоса «платёж не завершён» — сверху, стеклом, как системное уведомление.
   Оформление взято у .push-card, чтобы не заводить третий вид карточки.
   Ниже модальных окон по z-index: если поверх откроется окно, полоса не
   должна лезть вперёд. */
.pending-banner {
  /* Выше модальных окон (100), но ниже уведомлений-подсказок (300): человек
     возвращается с оплаты чаще всего в открытый кабинет, и полоса, лежащая
     ПОД шторкой, была бы бесполезна — её не видно и на неё не нажать.
     Отступ считается от верха окна, а НЕ от высоты шапки: --topbar-h меняется
     при прокрутке, и полоса из-за этого ползала по экрану. Как системное
     уведомление, она просто лежит сверху — и точно так же убирается. */
  position: fixed; z-index: 150;
  top: calc(env(safe-area-inset-top, 0px) + 12px);
  /* Центрируем отступами, а НЕ transform. Любой transform на предке создаёт
     собственный «корень подложки», и backdrop-filter внутри перестаёт видеть
     страницу — размытие молча превращается в ничто, остаётся только
     полупрозрачная заливка. Именно поэтому увеличение blur не давало эффекта. */
  left: 0; right: 0; margin-inline: auto;
  width: min(460px, calc(100% - 20px));
  pointer-events: none;                 /* кликается только сама карточка */
}
.pending-banner.hidden { display: none; }
/* Материал ровно тот же, что у наших подсказок (.toast): --mat-nav плюс
   размытие с подъёмом насыщенности. Это настоящее стекло — сквозь него видно
   подложку, — а не белая заливка. Оба цвета берутся из токенов, поэтому
   тёмная тема не требует отдельных правил. */
.pending-banner-card {
  pointer-events: auto;
  position: relative;
  display: flex; align-items: center; gap: 13px;
  padding: 13px 14px;
  border-radius: 22px;
  /* Стекло заметно сильнее, чем у подсказок: размытие крупное, подложка
     прозрачнее — сквозь полосу видно, что под ней, но нечётко. */
  background: var(--mat-thick);
  -webkit-backdrop-filter: saturate(220%) blur(90px); backdrop-filter: saturate(220%) blur(90px);
  border: .5px solid var(--hairline);
  box-shadow: var(--sh-float);
  color: var(--text);
  animation: pendingBannerIn .28s var(--ease) both;
  touch-action: pan-x;                  /* вертикальный жест обрабатываем сами */
}
.pending-banner-icon {
  width: 38px; height: 38px; flex: none; display: grid; place-items: center;
  border-radius: 50%; background: rgba(255,159,10,.15); color: #d87900;
}
.pending-banner-icon svg { width: 21px; height: 21px; }
.pending-banner-text { min-width: 0; flex: 1; }
.pending-banner-text strong { display: block; font-size: 15px; line-height: 1.3; }
.pending-banner-text p { margin: 4px 0 0; font-size: 13px; line-height: 1.5; color: var(--text-2); }
.pending-banner-close {
  flex: none; width: 32px; height: 32px; display: grid; place-items: center;
  padding: 0; border: 0; background: none; box-shadow: none;
  color: var(--text-3); cursor: pointer;
}
.pending-banner-close svg { width: 17px; height: 17px; }
@media (hover: hover) { .pending-banner-close:hover { opacity: .7; } }
.pending-banner-close:active { transform: scale(.9); }
.pending-banner-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 50%; }
/* Въезд без transform: он на время анимации тоже гасил бы размытие. */
@keyframes pendingBannerIn {
  from { opacity: 0; margin-top: -14px; }
  to { opacity: 1; margin-top: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .pending-banner-card { animation: none; }
}
.pending-payment-actions { display: grid; gap: 10px; margin-top: 18px; }
.pending-payment-actions .text-button { min-height: 44px; color: var(--text-3); }
@media (hover: hover) {
  .pending-payment-actions .text-button:hover { color: var(--danger, #ff3b30); }
}
@media (max-width: 768px) {
  /* На узком экране это нижняя шторка — и её принято закрывать смахиванием.
     Полоска показывает, что жест доступен. */
  .pending-payment-grabber { display: block; touch-action: none; }
}

/* Отдельная промо-плашка «Мои ПВЗ» над закреплённой шапкой сайта. */
.pvz-site-banner {
  position: relative;
  z-index: 21;
  padding: 12px max(16px, env(safe-area-inset-right, 0px)) 0 max(16px, env(safe-area-inset-left, 0px));
  background: var(--bg);
}
/* Пока блок виден, fixed-шапка стоит непосредственно под ним; затем остаётся у верхнего края. */
body:has(.pvz-site-banner) .topbar { top: var(--pvz-banner-offset, 0px); }
.pvz-site-banner .pvz-promo { max-width: 1140px; margin: 0 auto 12px; }
.pvz-promo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  position: relative;
  isolation: isolate;
  padding: 17px 22px;
  border: 1px solid rgba(170, 155, 209, .24);
  border-radius: 22px;
  overflow: hidden;
  background:
    radial-gradient(ellipse 75% 130% at 100% 5%, rgba(125, 78, 185, .22), transparent 70%),
    linear-gradient(122deg, #211e2b, #14131b 70%, #1c1923);
  box-shadow: 0 15px 32px rgba(28, 17, 47, .17), inset 0 1px 0 rgba(255, 255, 255, .09);
  color: #f7f5fb;
}
.pvz-promo::before {
  content: "";
  position: absolute;
  width: 225px;
  height: 225px;
  right: -35px;
  top: -125px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(204, 140, 255, .21), transparent 68%);
  pointer-events: none;
  z-index: -1;
}
.pvz-promo-copy { min-width: 0; }
.pvz-promo-kicker {
  display: block;
  margin-bottom: 7px;
  color: #cfc0e6;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.pvz-promo h2 {
  max-width: 480px;
  color: #f7f5fb;
  font-size: clamp(16px, 2vw, 20px);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.025em;
}
.pvz-promo p { margin-top: 6px; color: #bbb7c9; font-size: 13px; line-height: 1.45; }
.pvz-promo-button {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  min-width: 163px;
  min-height: 59px;
  padding: 7px 18px 7px 7px;
  position: relative;
  isolation: isolate;
  border: 1px solid rgba(246, 240, 255, .15);
  border-radius: 999px;
  background: linear-gradient(140deg, #35323c, #28252e 55%, #211f27);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .14);
  color: #f7f6fa;
  white-space: nowrap;
  text-decoration: none;
  transition: transform .22s ease, box-shadow .22s ease;
}
.pvz-promo-button:hover {
  color: #fff;
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(0, 0, 0, .5), 0 0 23px rgba(112, 139, 255, .22), inset 0 1px 0 rgba(255, 255, 255, .16);
}
.pvz-promo-button:active { transform: translateY(1px) scale(.98); }
.pvz-promo-button:focus-visible { outline: 2px solid #f7f6fa; outline-offset: 5px; border-radius: 999px; }
.pvz-promo-rim, .pvz-promo-flare, .pvz-promo-halo {
  position: absolute;
  inset: -2px;
  padding: 2px;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
}
.pvz-promo-rim::before, .pvz-promo-flare::before, .pvz-promo-halo::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  /* Rotate the rendered gradient, not a custom angle property: older iOS Safari
     otherwise steps between frames instead of interpolating the angle. */
  /* A square larger than the pill keeps every edge covered as it rotates. */
  width: 200%;
  height: 0;
  padding-bottom: 200%;
  transform: translate(-50%, -50%) rotate(0deg);
  animation: pvz-orbit 4.5s linear infinite;
}
.pvz-promo-rim {
  opacity: .93;
}
.pvz-promo-rim::before {
  background: conic-gradient(#70a5ff, #8ae3ff 8%, #fff8e9 13%, #ffae71 17%, #f45655 22%, #8446f6 27%, #3ab8ff 34%, #fff7dd 45%, #f79857 50%, #9d47d8 57%, #27469d 65%, #58c5ff 71%, #fff6ed 77%, #f99e62 81%, #8846db 88%, #70a5ff 100%);
}
.pvz-promo-halo {
  inset: -5px;
  padding: 6px;
  filter: blur(10px);
  opacity: .8;
}
.pvz-promo-halo::before {
  background: conic-gradient(transparent 0% 6%, rgba(56, 123, 255, .46) 9%, rgba(255, 255, 255, .95) 13%, rgba(255, 151, 72, .65) 17%, transparent 24% 52%, rgba(73, 96, 255, .38) 59%, rgba(255, 255, 255, .76) 67%, rgba(255, 140, 72, .5) 71%, transparent 78% 100%);
}
.pvz-promo-flare {
  padding: 3px;
}
.pvz-promo-flare::before {
  background: conic-gradient(transparent 0% 7%, rgba(98, 166, 255, .36) 10%, #fff 13%, #fff7da 14%, rgba(255, 159, 82, .8) 17%, transparent 21% 57%, rgba(93, 136, 255, .26) 62%, rgba(255, 255, 255, .86) 66%, rgba(255, 176, 107, .65) 69%, transparent 73% 100%);
}
.pvz-promo-icon {
  display: grid;
  flex: 0 0 44px;
  place-items: center;
  position: relative;
  z-index: 1;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: linear-gradient(140deg, #484650, #2c2a34 70%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .19), inset 0 -3px 6px rgba(0, 0, 0, .24), 0 2px 7px rgba(0, 0, 0, .5);
}
.pvz-promo-icon svg { width: 24px; height: 24px; }
.pvz-promo-button-label { position: relative; z-index: 1; font-size: 15px; font-weight: 650; letter-spacing: .01em; }
@keyframes pvz-orbit {
  /* Explicit midpoint keeps the animation interpolating in WebKit, too. */
  50% { transform: translate(-50%, -50%) rotate(180deg); }
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

@media (max-width: 768px) {
  .pvz-site-banner { padding-top: calc(8px + env(safe-area-inset-top, 0px)); }
  .pvz-site-banner .pvz-promo { margin-bottom: 8px; }
  .pvz-promo { flex-direction: column; align-items: stretch; gap: 14px; padding: 17px 18px; }
  .pvz-promo h2 { max-width: none; font-size: 18px; }
  .pvz-promo-button { align-self: flex-start; }
}
@media (max-width: 370px) {
  .pvz-promo { padding: 15px; gap: 12px; }
  .pvz-promo h2 { font-size: 16px; }
  .pvz-promo p { font-size: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .pvz-promo-rim::before, .pvz-promo-flare::before, .pvz-promo-halo::before { animation: none; }
}
