/* ============================================================================
   Matryoshka VPN World — личный кабинет.
   Бренд «Матрёшка» (из старого приложения matr/): NAVY #041562 + КРЕМ #F7EDC5 +
   ЖЁЛТЫЙ #FADB3F, красный = «подключено». Дисплей — Oswald SemiBold (капс),
   текст — Nunito. Шрифты и кукла — SELF-HOST (тот же origin, без CDN: VPN для РФ,
   приватность). Обе темы через prefers-color-scheme (без JS). Персонаж-матрёшка =
   символ бренда; «слои защиты» = кукла в куколке.
   ============================================================================ */

@font-face { font-family:'Oswald'; font-style:normal; font-weight:600; font-display:swap;
  src:url("./oswald.woff2") format("woff2"); }
@font-face { font-family:'Nunito'; font-style:normal; font-weight:800; font-display:swap;
  src:url("./nunito_bold.woff2") format("woff2"); }
@font-face { font-family:'Nunito'; font-style:normal; font-weight:500; font-display:swap;
  src:url("./nunito_med.woff2") format("woff2"); }

:root {
  /* фирменные */
  --navy:#041562; --navy-2:#0A1F95; --navy-3:#18399B;
  --cream:#F7EDC5; --yellow:#FADB3F; --amber:#FAC83D;
  --charcoal:#292823; --pink:#E19AC0; --red:#AC3737; --white:#fff;
  /* статусы */
  --ok:#1F9D57; --ok-ink:#137a42; --ok-tint:#1F9D5714;
  --danger:#AC3737; --danger-ink:#8f2c21; --danger-tint:#AC373714;
  --warn:#B8791E;
  /* поверхности (светлая) */
  --ground:#FBFAF3; --panel:#FFFFFF; --panel-2:#F3F1E6;
  --ink:#0B1030; --ink-soft:#4A5478; --ink-dim:#5C6488;
  --line:#E7E4D3; --line-strong:#D8D3BE;
  /* роли */
  --accent:var(--navy); --spot:var(--yellow);
  /* форма */
  --radius:14px; --radius-sm:9px;
  /* каркас. --shell-pad — боковой паддинг МОБИЛЬНОЙ раскладки (шапка, .app-main, попапы; до 940px).
     На десктопе те же роли берут --hd-pad (шапка и попапы) и собственный паддинг .app-main. */
  --shell-pad:clamp(16px, 4vw, 24px); --rail-w:clamp(198px, 19vw, 236px);
  --gutter:22px;   /* одна ВЕЛИЧИНА жёлоба на все двухколоночные секции (сами швы не совпадают —
                      колонки секций разной ширины), чтобы ритм не собирался по месту */
  /* --hd-h НЕ константа 59px: при увеличенном шрифте браузера строка бренда перерастает иконки,
     шапка становится выше, и sticky-меню с фиксированным отступом ушло бы ПОД неё.
     Формула = вертикальные паддинги 22px + рамка 1px + max(высота .hd-ico, строка .hd-word 0.98rem×1.5). */
  /* --hd-pad фиксирован = 14px паддинга .rail + 12px паддинга .rail-link: только так бренд в шапке
     стоит РОВНО над иконками бокового меню на ЛЮБОЙ ширине. С clamp(18px,2vw,26px) он совпадал
     лишь от ~1300px, а на 860–1200 уезжал влево на 2–8px (замерено). */
  --hd-h:calc(23px + max(36px, 1.47rem)); --hd-pad:26px;
  --shadow:0 1px 2px #04156212, 0 8px 24px -10px #04156226, 0 24px 48px -28px #04156220;
  --shadow-sm:0 1px 2px #04156214, 0 4px 14px -8px #04156222;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --sans: 'Nunito', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --display: 'Oswald', "Arial Narrow", system-ui, sans-serif;
  --doll: url("./doll_light.png");
}
@media (prefers-color-scheme: dark) {
  :root {
    --ground:#1B1B17; --panel:#242420; --panel-2:#2C2C26;
    --ink:#F4EFDD; --ink-soft:#C3BDA6; --ink-dim:#9A957E;
    --line:#37372F; --line-strong:#45443A;
    --accent:var(--yellow);
    --ok-ink:#5fce93; --ok-tint:#1F9D5722;
    --danger-ink:#e79086; --danger-tint:#AC373726;
    --shadow:0 1px 2px #00000030, 0 10px 30px -14px #00000066;
    --shadow-sm:0 1px 2px #00000030, 0 6px 18px -10px #00000055;
    --doll: url("./doll_dark.png");
  }
}

* { box-sizing: border-box; }
/* CSP веб-ЛК = `style-src 'self'` без 'unsafe-inline' → атрибут style= браузер отбросит; оформление
   noscript-блока обязано жить в файле. */
.noscript-block { padding: 32px 22px; }
/* UA-правило `[hidden]{display:none}` слабее ЛЮБОГО авторского `display` (напр. .tier{display:inline-flex}),
   поэтому el.hidden=true молча переставал скрывать. Ресет обязателен, иначе гейты видимости — no-op. */
[hidden] { display: none !important; }
html, body { margin: 0; }

body {
  background: radial-gradient(120% 80% at 50% -10%, var(--ground) 40%, var(--panel-2) 100%);
  color: var(--ink);
  font-family: var(--sans); font-weight: 500;
  font-size: 16px; line-height: 1.5;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  min-height: 100vh; display: flex; flex-direction: column;
}
/* тонкая «бумажная» зернистость — атмосфера, палитро-нейтральна (grayscale) */
body::before {
  content: ""; position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: .45;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E");
}
body > * { position: relative; z-index: 1; }

/* ── topbar ───────────────────────────────────────────────────────────── */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px clamp(16px, 4vw, 32px);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, color-mix(in srgb,var(--ground) 82%,transparent), transparent);
  -webkit-backdrop-filter: saturate(1.1) blur(6px); backdrop-filter: saturate(1.1) blur(6px);
}
.brand { display: flex; align-items: center; gap: 10px;
  font-family: var(--display); font-weight: 600; text-transform: uppercase;
  letter-spacing: .1em; font-size: 1rem; color: var(--ink); }
.brand .brand-doll { width: 17px; height: 30px; flex: none;   /* 17:30 ≈ пропорция куклы 460/825 → без бокового зазора при contain */
  background: var(--doll) center/contain no-repeat;
  filter: drop-shadow(0 1px 2px #04156230); }
.brand-dim { color: var(--ink-dim); font-weight: 600; }

/* ── layout ───────────────────────────────────────────────────────────── */
.wrap { width: 100%; max-width: 720px; margin: 0 auto; padding: clamp(28px, 6vw, 56px) clamp(16px, 4vw, 24px) 72px; flex: 1; }
/* `backwards`, а НЕ `both`. С `both` доигравшая анимация продолжает применять свой `transform`, и
   `getComputedStyle` отдаёт `matrix(1,0,0,1,0,0)` вместо `none` — а любой transform на предке делает
   элемент containing block'ом для `position:fixed`. Из-за этого нижний `.tabbar` якорился к низу
   ДОКУМЕНТА, а не экрана: на «Подписке» 390×844 он стоял на y=2396 при вьюпорте 844 и уезжал вместе
   со страницей. `rise` без задержки, поэтому вход анимации `backwards` не меняет, а после конца
   свойство возвращается к базовому — containing block не остаётся. Замерено, не выведено. */
.view { animation: rise .5s cubic-bezier(.2,.7,.2,1) backwards; }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.display {
  font-family: var(--display); font-weight: 600; text-transform: uppercase;
  font-size: clamp(2.1rem, 6.4vw, 3rem); line-height: 1.0; letter-spacing: .005em;
  margin: 0 0 10px; color: var(--ink);
}
.lede { color: var(--ink-soft); font-size: 1.04rem; margin: 0 0 30px; max-width: 48ch; }

/* ── LOGIN: матрёшка-герой + приподнятая карта ───────────────────────────── */
#view-login { text-align: center; }
.login-hero {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  margin: clamp(8px, 3vw, 28px) 0 6px; position: relative;
}
/* тёплый ореол за куклой (замена «колец» — на бренд артефакта) */
.login-hero::before {
  content: ""; position: absolute; top: -6%; left: 50%; transform: translateX(-50%);
  width: min(280px, 78%); aspect-ratio: 1; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 46%, color-mix(in srgb,var(--spot) 42%,transparent),
              color-mix(in srgb,var(--cream) 22%,transparent) 46%, transparent 66%);
  filter: blur(8px);
}
.login-hero .doll-hero {
  position: relative; width: clamp(120px, 34vw, 168px); aspect-ratio: 460/825; height: auto;
  background: var(--doll) center/contain no-repeat;
  filter: drop-shadow(0 22px 30px #04156230);
  animation: dollIn .8s cubic-bezier(.2,.8,.2,1) both, dollFloat 4.2s ease-in-out 1s infinite;
}
@keyframes dollIn { from { opacity: 0; transform: translateY(10px) scale(.92); } to { opacity: 1; transform: none; } }
@keyframes dollFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
#view-login .display { margin-top: 4px; }
#view-login .lede { margin-left: auto; margin-right: auto; }

.login-card {
  text-align: left; max-width: 440px; margin: 8px auto 0;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 26px 24px 22px; box-shadow: var(--shadow);
  position: relative; overflow: hidden;
  animation: rise .55s .12s cubic-bezier(.2,.7,.2,1) both;
}
/* фирменный хайрлайн сверху карты: navy → жёлтый → navy */
.login-card::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, var(--accent), var(--spot) 50%, var(--accent));
}
.login-card h2 { font-family: var(--display); text-transform: uppercase; letter-spacing: .02em;
  font-size: 1.35rem; margin: 2px 0 6px; font-weight: 600; }

/* ── card (общая) ─────────────────────────────────────────────────────── */
.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 22px; margin-bottom: 18px; box-shadow: var(--shadow-sm);
}
.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.card h2 { font-family: var(--display); text-transform: uppercase; letter-spacing: .02em;
  font-size: 1.2rem; margin: 0; font-weight: 600; }
.card h3 { font-size: 1rem; margin: 0 0 4px; font-weight: 800; }

/* ── buttons ──────────────────────────────────────────────────────────── */
.btn {
  font: inherit; font-family: var(--sans); font-weight: 800;
  border: 1px solid var(--line-strong); background: var(--panel-2); color: var(--ink);
  padding: 11px 18px; border-radius: var(--radius-sm); cursor: pointer;
  transition: transform .08s ease, background .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.btn:hover:not(:disabled) { box-shadow: var(--shadow-sm); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* primary = основной CTA: navy-блок с кремовым текстом (в тёмной — navy остаётся, читаемо) */
.btn-primary { background: var(--navy); border-color: var(--navy-2); color: var(--cream);
  box-shadow: 0 1px 0 #ffffff22 inset, 0 6px 16px -8px #04156266; }
.btn-primary:hover:not(:disabled) { background: var(--navy-2); }
/* в тёмной теме navy сливается с почти-чёрным фоном → поднимаем до navy-3 (виден, крем-текст читаем) */
@media (prefers-color-scheme: dark) { .btn-primary { background: var(--navy-3); border-color: #9AA3D6; } .btn-primary:hover:not(:disabled) { background: #2C4FC0; } }
/* premium = продление/премиум: жёлтый градиент, тёмный текст (пришло из .btn-garnet) */
.btn-premium { background: linear-gradient(135deg, var(--yellow), var(--amber));
  border-color: var(--amber); color: var(--charcoal); font-weight: 800;
  box-shadow: 0 1px 0 #ffffff44 inset, 0 6px 16px -8px #FADB3F55; }
.btn-premium:hover:not(:disabled) { background: linear-gradient(135deg, var(--amber), var(--yellow)); }
.btn-ghost { background: transparent; border-color: var(--line-strong); color: var(--ink); }
.btn-ghost:hover:not(:disabled) { background: color-mix(in srgb,var(--spot) 16%,transparent); border-color: var(--spot); }
.btn-small { padding: 10px 15px; font-size: .9rem; min-height: 48px; display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.btn-tg { background: var(--navy-3); border-color: var(--navy-2); color: #fff; text-decoration: none;
  display: inline-block; box-shadow: 0 1px 0 #ffffff2e inset, 0 6px 16px -8px #18399B55; }
.btn-tg:hover:not(:disabled) { background: var(--navy-2); }
.btn-block { display: block; width: 100%; text-align: center; }
.btn-lg { padding: 14px 20px; font-size: 1.05rem; border-radius: 11px; }
.login-card .btn-block { margin-top: 6px; }

.muted, .muted-small { font-size: .9rem; color: var(--ink-dim); }
.muted-small { font-size: .82rem; }
/* ── вход: заглушки Google/Apple «скоро» (вход ещё не подключён; GIS не монтируем) ── */
.login-alt { display: grid; gap: 10px; margin-top: 4px; }
.btn-soon { display: flex; align-items: center; gap: 11px; justify-content: flex-start; text-align: left;
  background: var(--panel-2); color: var(--ink-soft); border-color: var(--line-strong); font-weight: 700;
  cursor: not-allowed; opacity: 1; }
.btn-soon:disabled { opacity: 1; }                 /* glyph/label читаемы — «скоро» несёт состояние, не серость */
.btn-soon .alt-ic { width: 20px; height: 20px; flex: none; color: var(--ink-soft); }
.btn-soon > span:nth-of-type(1) { color: var(--ink-soft); }
.btn-soon .soon { margin-left: auto; font-size: .68rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .06em; color: var(--accent); background: color-mix(in srgb,var(--accent) 14%,transparent);
  padding: 3px 9px; border-radius: 999px; }
.or-divider { display: flex; align-items: center; gap: 10px; color: var(--ink-dim); font-size: .8rem; margin: 14px 0; font-weight: 700; }
.or-divider::before, .or-divider::after { content: ""; flex: 1; border-top: 1px solid var(--line); }

/* ── forms ────────────────────────────────────────────────────────────── */
.stack { display: flex; flex-direction: column; gap: 14px; margin-top: 14px; }
.stack label, .row label { display: flex; flex-direction: column; gap: 6px; font-size: .85rem; color: var(--ink-dim); font-weight: 800; }
input, select {
  font: inherit; font-family: var(--sans); color: var(--ink);
  padding: 11px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--panel-2); width: 100%;
}
input:focus, select:focus { outline: 3px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.row { display: flex; gap: 10px; align-items: stretch; margin-top: 8px; }
.row .btn { white-space: nowrap; }
.code-input { font-family: var(--mono); letter-spacing: 0.08em; text-transform: uppercase; flex: 1; }

.hint { font-size: .85rem; color: var(--ink-dim); margin: 6px 0 0; }
.hint code, .lede code { font-family: var(--mono); background: color-mix(in srgb,var(--spot) 18%,transparent);
  padding: 1px 5px; border-radius: 4px; color: var(--ink-soft); }
.hint b { color: var(--ink-soft); font-weight: 800; }

.dev-login { margin-top: 18px; border-top: 1px dashed var(--line-strong); padding-top: 12px; }
.dev-login summary { cursor: pointer; color: var(--ink-dim); font-size: .82rem; font-weight: 800; }

/* ── account head ─────────────────────────────────────────────────────── */
.acct-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 22px; flex-wrap: wrap; }
.account-id, .inline-id { font-family: var(--mono); font-size: .8rem; color: var(--ink-dim);
  background: color-mix(in srgb,var(--spot) 16%,transparent); padding: 3px 8px; border-radius: 6px; }

/* ── status ───────────────────────────────────────────────────────────── */
.status-card { position: relative; }
.badge {
  display: inline-block; font-family: var(--display); font-weight: 600; font-size: .78rem;
  text-transform: uppercase; letter-spacing: .08em; padding: 5px 13px; border-radius: 999px; margin-bottom: 18px;
  background: var(--line-strong); color: var(--ink-soft);
}
.badge.is-active { background: var(--ok-tint); color: var(--ok-ink); box-shadow: 0 0 0 1px #1F9D5740 inset; }
.badge.is-inactive { background: var(--danger-tint); color: var(--danger-ink); box-shadow: 0 0 0 1px #AC373740 inset; }

.kv { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 0 0 20px; }
.kv div { min-width: 0; }
.kv dt { font-size: .8rem; color: var(--ink-dim); font-weight: 800; text-transform: uppercase; letter-spacing: .04em; }
.kv dd { margin: 5px 0 0; font-size: 1.15rem; font-weight: 600; letter-spacing: .01em; font-family: var(--display); text-transform: uppercase; }

/* ── config / подключение ─────────────────────────────────────────────── */
.config-block { border-top: 1px solid var(--line); padding-top: 16px; }
.config-label { font-size: .78rem; color: var(--ink-dim); font-weight: 800; }
.config-row { display: flex; gap: 10px; align-items: center; margin-top: 6px; }
.config-url {
  font-family: var(--mono); font-size: .82rem; background: var(--panel-2);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: 9px 11px;
  /* было `nowrap` + `overflow-x:auto` → ссылка-подписка обрезалась на середине без многоточия и
     без возможности прочитать её целиком. Переносим, как в mini-app. */
  flex: 1; min-width: 0; overflow-wrap: anywhere; white-space: normal; color: var(--ink-soft);
}
.steps { margin-top: 16px; display: grid; gap: 4px; }
.steps .hint { margin: 0; padding: 8px 0 8px 2px; border-bottom: 1px dashed var(--line); }
.steps .hint:last-child { border-bottom: none; }
.link-result { margin-top: 14px; }

/* ── toast ────────────────────────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; top: 18px; transform: translateX(-50%);
  background: var(--navy); color: var(--cream); padding: 11px 18px; border-radius: var(--radius-sm);
  font-size: .9rem; font-weight: 800; z-index: 50; max-width: 90vw; box-shadow: var(--shadow);
  animation: rise .25s ease both;
}
.toast.is-error { background: var(--danger); color: #fff; }
.toast.is-ok { background: #137a42; color: #fff; }   /* тёмно-зелёный: #fff даёт ~5.3:1 (AA), var(--ok) давал 3.49:1 */

.footer { text-align: center; color: var(--ink-dim); font-size: .8rem; padding: 26px; border-top: 1px solid var(--line); }
.footer::before { content: "🪆 "; }

/* ── табы ─────────────────────────────────────────────────────────────── */
.tabs { display: flex; gap: 2px; margin: 0 0 22px; border-bottom: 1px solid var(--line); overflow-x: auto; }
.tab {
  font: inherit; font-family: var(--display); text-transform: uppercase; letter-spacing: .03em;
  font-weight: 600; font-size: .92rem; color: var(--ink-dim);
  background: none; border: none; border-bottom: 2.5px solid transparent;
  padding: 10px 15px; cursor: pointer; white-space: nowrap; margin-bottom: -1px; transition: color .15s;
}
.tab:hover { color: var(--ink); }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.tab:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.tabpanel { animation: fade .22s ease; }

/* ── трафик-бар (семантика: navy=норма → янтарь → красный) ─────────────── */
.traffic-bar { height: 9px; background: var(--line-strong); border-radius: 999px; overflow: hidden; margin: 0 0 20px; box-shadow: 0 1px 2px #04156218 inset; }
.traffic-fill { height: 100%; min-width: 8px; background: linear-gradient(90deg, var(--navy-3), var(--navy)); border-radius: 999px; transition: width .4s ease; }
.traffic-fill.is-low { background: linear-gradient(90deg, var(--amber), var(--warn)); }
.traffic-fill.is-crit { background: linear-gradient(90deg, var(--red), #d2584a); }
@media (prefers-color-scheme: dark) { .traffic-fill { background: linear-gradient(90deg, var(--yellow), var(--amber)); } }

/* ── тарифы ───────────────────────────────────────────────────────────── */
/* Тарифов и пакетов ВСЕГДА три. `auto-fill` давал промежуточную двухколоночную стадию (480–939px),
   а в ней три карточки ложатся 2+1 с сиротой. Поэтому стадии всего две: одна колонка или сразу три.
   Попытка «дотянуть сироту на всю ширину» через `:last-child:nth-child(odd)` не годится: селектор
   не знает, сколько колонок вышло, и срабатывал даже на полном ряду (проверено рендером). */
.plans-grid { display: grid; grid-template-columns: 1fr; gap: 12px; margin: 14px 0 8px; }
@media (min-width: 760px) { .plans-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* карточки тарифов/пакетов на web — ИНФОРМАЦИОННЫЕ (покупка Stars только в Telegram): без сигналов
   интерактивности (cursor/hover-lift/focus/selected), чтобы не обещать неработающий на web выбор */
.plan-card {
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 16px; background: var(--panel-2);
  display: flex; flex-direction: column; gap: 4px;
}
.plan-card .plan-title { font-weight: 600; font-size: 1.05rem; font-family: var(--display); text-transform: uppercase; letter-spacing: .01em; }
.plan-card .plan-meta { color: var(--ink-dim); font-size: .85rem; font-weight: 600; }
.plan-card { justify-content: flex-start; }
.plan-card .price { margin-top: auto; }
.plan-card .plan-price { margin-top: 6px; font-weight: 600; font-size: 1.3rem; letter-spacing: .01em; color: var(--accent); font-family: var(--display); }
.plan-card .plan-price .stars { color: var(--ink-dim); font-weight: 700; font-size: .9rem; font-family: var(--sans); }

.pay-block { border-top: 1px solid var(--line); margin-top: 18px; padding-top: 16px; }
.pay-block h3 { margin: 0 0 10px; font-family: var(--display); text-transform: uppercase; letter-spacing: .02em; font-weight: 600; }
.pay-block .btn-block { margin-bottom: 8px; }

/* ── аккордеоны ───────────────────────────────────────────────────────── */
.accordions { margin-top: 14px; }
/* `.panel details` — «Нет Happ в App Store?» и «Частые вопросы»: они не попадали ни под один
   селектор и рисовались системным треугольником без рамки, рядом с оформленными аккордеонами. */
.accordions details, .accordion-item, .tabpanel details, .panel details {
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: 0 14px; margin-bottom: 8px; background: var(--panel-2);
}
.accordions summary, .accordion-item summary, .tabpanel details summary, .panel details summary {
  cursor: pointer; font-weight: 800; padding: 12px 0; list-style: none;
}
summary::-webkit-details-marker { display: none; }
.accordions summary::after, .accordion-item summary::after, .tabpanel details summary::after,
.panel details summary::after { content: "＋"; float: right; color: var(--accent); font-weight: 400; }
.accordions details[open] summary::after, .accordion-item[open] summary::after,
.tabpanel details[open] summary::after, .panel details[open] summary::after { content: "－"; }
.accordions details > *:not(summary), .accordion-item > *:not(summary), .tabpanel details > *:not(summary),
.panel details > *:not(summary) { margin-bottom: 14px; }

@media (max-width: 480px) {
  .kv { grid-template-columns: 1fr 1fr; gap: 14px; }
  .login-card { padding: 22px 18px 20px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ============================================================================
   КАРКАС КОНКУРЕНТА (хедер · нижний таб-бар · drawer · дашборд) — на бренд-токенах.
   Раскладка как у конкурента, палитра/шрифты/кукла — Matryoshka (accent-flip уже в --accent).
   ============================================================================ */
.app-header {
  position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 9px;
  padding: 11px var(--shell-pad); background: var(--panel); border-bottom: 1px solid var(--line);
}
.hd-brand { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0; }
.hd-doll { width: 17px; height: 30px; flex: none; background: var(--doll) center/contain no-repeat;
  filter: drop-shadow(0 1px 2px #04156230); }
.hd-word { font-family: var(--display); font-weight: 600; text-transform: uppercase; letter-spacing: .08em;
  font-size: .98rem; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hd-word .dim { color: var(--ink-dim); }
.hd-ico { width: 36px; height: 36px; flex: none; display: grid; place-items: center; border-radius: 10px;
  background: var(--panel-2); border: 1px solid var(--line-strong); color: var(--ink-soft); font-size: 15px;
  cursor: pointer; position: relative; }
.hd-ico:hover { color: var(--ink); }
.hd-ico:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* flex вместо унаследованного от .hd-ico grid: в grid флаг и стрелка ▾ становились ДВУМЯ строками
   сетки — ▾ уезжала под флаг и вылезала за нижний край кнопки (видно на всех размерах). */
.hd-lang { width: auto; padding: 0 10px; gap: 5px; font-size: .78rem; font-weight: 800; font-family: var(--sans);
  display: flex; align-items: center; justify-content: center; white-space: nowrap; }

.app-main { width: 100%; max-width: 720px; margin: 0 auto;
  padding: var(--shell-pad) var(--shell-pad) 96px; }
/* обёртки колонок дашборда: на мобиле их как будто нет (порядок и вид — прежние),
   раскладку они получают только в десктопном блоке в конце файла */
.col-main, .col-side, .bal-duo { display: contents; }
.rail, .app-foot { display: none; }
.panel { display: none; }
.panel.is-active { display: block; animation: fade .2s ease; }

.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; display: flex;
  background: var(--panel); border-top: 1px solid var(--line);
  padding: 7px 4px calc(8px + env(safe-area-inset-bottom, 0px));
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.tabbar .tab { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 3px 0; font-family: var(--sans); font-size: .64rem; font-weight: 800; letter-spacing: 0;
  text-transform: none; color: var(--ink-dim); background: none; border: 0; border-bottom: 0; margin: 0; cursor: pointer; }
.tabbar .tab .ti { width: 42px; height: 26px; display: grid; place-items: center; border-radius: 10px; font-size: 16px; }
.tabbar .tab.is-active { color: var(--accent); }
.tabbar .tab.is-active .ti { background: color-mix(in srgb, var(--accent) 14%, transparent); }

/* drawer */
.scrim { position: fixed; inset: 0; z-index: 40; background: rgba(4,10,30,.5); opacity: 0; visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease; }
.scrim.is-open { opacity: 1; visibility: visible; }
.drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 50; width: min(330px, 86vw);
  background: var(--panel); border-left: 1px solid var(--line); box-shadow: var(--shadow);
  transform: translateX(100%); visibility: hidden; transition: transform .22s ease, visibility 0s linear .22s;
  display: flex; flex-direction: column;
  padding: 16px 16px calc(18px + env(safe-area-inset-bottom, 0px)); overflow-y: auto; }
/* visibility 0s с задержкой (НЕ интерполируем): открытие — сразу видим; закрытие — прячем ПОСЛЕ слайда (#1) */
.drawer.is-open { transform: none; visibility: visible; transition: transform .22s ease, visibility 0s linear 0s; }
.drawer-head { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.avatar { width: 46px; height: 46px; flex: none; border-radius: 14px; display: grid; place-items: center;
  font-family: var(--display); font-weight: 600; font-size: 18px; color: var(--charcoal);
  background: linear-gradient(135deg, var(--yellow), var(--amber)); }
.drawer-name { font-family: var(--display); font-weight: 600; font-size: 1.05rem; text-transform: uppercase; }
.drawer-sub { font-size: .8rem; color: var(--ink-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drawer-close { margin-left: auto; }
.drawer-nav { display: flex; flex-direction: column; gap: 2px; margin-top: 14px; }
.drawer-link { display: flex; align-items: center; gap: 11px; padding: 11px 10px; border-radius: 11px;
  color: var(--ink); background: none; border: 0; font: inherit; font-family: var(--sans); font-weight: 700;
  text-align: left; cursor: pointer; width: 100%; }
.drawer-link:hover { background: var(--panel-2); }
.drawer-link .di { width: 22px; text-align: center; font-size: 16px; }
.drawer-link .soon-tag { margin-left: auto; }
.drawer-sep { height: 1px; background: var(--line); margin: 10px 2px; border: 0; }
.drawer .link-result { margin-top: 8px; }

/* дашборд-компоненты */
.welcome { font-family: var(--display); font-weight: 600; text-transform: uppercase; font-size: 1.6rem;
  line-height: 1.06; margin: 2px 0; letter-spacing: .01em; }
.screen-h1 { font-family: var(--display); font-weight: 600; text-transform: uppercase; font-size: 1.7rem;
  line-height: 1.05; margin: 2px 0 8px; }
#home-tier { display: none; }   /* статус живёт пилюлей в карточке — дубль убран на всех ширинах */
.tier { display: inline-flex; align-items: center; gap: 5px; margin: 6px 0 2px; font-size: .72rem; font-weight: 800;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent); padding: 4px 10px; border-radius: 999px; }
.sec-row { display: flex; justify-content: space-between; align-items: baseline; margin: 20px 0 10px; }
.sec-row .t, .section-title { font-family: var(--display); text-transform: uppercase; letter-spacing: .05em;
  font-size: .78rem; color: var(--ink-dim); font-weight: 600; }
.section-title { margin: 34px 0 10px; }
.sec-row .a { font-size: .8rem; color: var(--accent); font-weight: 800; background: none; border: 0; cursor: pointer;
  font-family: var(--sans); }
.card-title { font-family: var(--display); text-transform: uppercase; letter-spacing: .04em; font-size: .78rem;
  color: var(--ink-dim); font-weight: 600; margin-bottom: 9px; }

.sub-top { display: flex; align-items: center; gap: 8px; }
.sub-name { font-family: var(--display); font-weight: 600; font-size: 1.05rem; flex: 1; text-transform: uppercase; letter-spacing: .01em; }
.pill { font-size: .74rem; font-weight: 800; letter-spacing: .04em; padding: 3px 9px; border-radius: 999px; text-transform: uppercase; }
.pill.on { color: #fff; background: #137a42; }   /* фикс-контраст ~5.3:1 (var(--ok) давал ~3.4:1, fail AA) */
.pill.off { color: var(--ink-dim); background: var(--panel-2); border: 1px solid var(--line-strong); }
/* аварийное состояние обязано быть ГРОМЧЕ здорового: тихая .off читалась мягче зелёной .on */
.pill.crit { color: #fff; background: var(--danger); }
.bar-row { display: flex; justify-content: space-between; font-size: .82rem; color: var(--ink-dim); margin: 12px 0 6px; font-weight: 800; }
.bar-row b { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.meta { display: flex; gap: 13px; flex-wrap: wrap; margin-top: 12px; font-size: .82rem; color: var(--ink-dim); font-weight: 800; }
.meta .warn-x { color: var(--danger-ink); }
.meta .soon-inline, .plan-feat .soon-inline { color: var(--ink-dim); }

.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 12px; }
.duo.solo { grid-template-columns: 1fr; }   /* реферал-карта скрыта (флаг OFF) → баланс на всю ширину */
.mini { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px;
  text-align: left; cursor: pointer; font-family: var(--sans); color: var(--ink); box-shadow: var(--shadow-sm); }
.mini:hover { border-color: var(--spot); }
.mini .k { display: flex; justify-content: space-between; font-size: .8rem; color: var(--ink-dim); font-weight: 800; }
.mini .v { font-family: var(--display); font-weight: 600; font-size: 1.3rem; margin-top: 8px; color: var(--ink); }
.mini .v.acc { color: var(--accent); }
.mini .s { font-size: .8rem; color: var(--ink-dim); margin-top: 1px; }

.promo { background: linear-gradient(120deg, color-mix(in srgb, var(--spot) 12%, transparent), transparent);
  border: 1px solid color-mix(in srgb, var(--spot) 32%, transparent); border-radius: var(--radius); padding: 14px;
  display: flex; gap: 11px; align-items: center; margin: 12px 0; }
.promo .em { font-size: 24px; flex: none; }
.promo .tt { font-family: var(--display); font-weight: 600; font-size: .95rem; text-transform: uppercase; }
.promo .dd { font-size: .8rem; color: var(--ink-soft); margin-top: 2px; }

.prov { display: flex; flex-direction: column; gap: 9px; }
.prov .p { background: var(--panel); border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: 12px 14px; display: flex; align-items: center; gap: 12px; text-align: left; width: 100%;
  font-family: var(--sans); color: var(--ink); cursor: pointer; }
.prov .p:disabled { cursor: default; opacity: .8; }
.prov .p:not(:disabled):hover { border-color: var(--spot); }
.prov .p .pv-em { font-size: 20px; flex: none; }
.prov .p .pv-main { flex: 1; min-width: 0; }
.prov .p b { font-family: var(--display); font-size: .92rem; font-weight: 600; display: block; text-transform: uppercase; letter-spacing: .01em; }
.prov .p small { color: var(--ink-dim); font-size: .82rem; }
.prov .p .lim { color: var(--ink-soft); font-size: .82rem; margin-top: 2px; }

.empty { display: flex; flex-direction: column; align-items: center; gap: 10px; color: var(--ink-dim);
  padding: 26px 0; font-size: .85rem; text-align: center; }
.empty .eb { width: 56px; height: 56px; border-radius: 16px; background: var(--panel-2); border: 1px solid var(--line-strong);
  display: grid; place-items: center; font-size: 24px; }
.soon-tag { font-family: var(--display); font-size: .68rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); border-radius: 999px; padding: 3px 9px; }
.soon-inline { font-weight: 800; }
.kv-line { margin: 4px 0; font-size: .9rem; }
.kv-line b { font-weight: 800; }

/* всплывающие панели (колокол / язык) */
/* top привязан к той же мере, что и высота шапки: с крупным шрифтом попап не наезжает на неё */
.pop { position: fixed; top: calc(var(--hd-h) - 1px); right: var(--shell-pad); z-index: 45; width: min(300px, 82vw);
  background: var(--panel); border: 1px solid var(--line-strong); border-radius: 14px; box-shadow: var(--shadow);
  padding: 12px; display: none; }
.pop.is-open { display: block; animation: fade .16s ease; }
.pop-title { font-family: var(--display); text-transform: uppercase; letter-spacing: .04em; font-size: .72rem;
  color: var(--ink-dim); font-weight: 600; margin-bottom: 8px; }
.lang-opt { display: flex; align-items: center; gap: 9px; padding: 9px 8px; border-radius: 10px; cursor: pointer;
  font-size: .9rem; color: var(--ink); background: none; border: 0; width: 100%; font-family: var(--sans); text-align: left; font-weight: 700; }
.lang-opt:hover { background: var(--panel-2); }
.lang-opt.is-active { color: var(--accent); }
.lang-opt .soon-tag { margin-left: auto; }
.lang-opt:disabled { cursor: default; }

/* dashboard-версии тарифных фич */
.plan-feat { display: flex; gap: 14px; flex-wrap: wrap; font-size: .8rem; color: var(--ink-soft); margin-top: 8px; font-weight: 700; }
.plan-card .price, .price { font-family: var(--display); font-weight: 600; font-size: 1.2rem; color: var(--accent); margin-top: 10px; }
.price .from { font-size: .7rem; color: var(--ink-dim); font-weight: 700; text-transform: uppercase; letter-spacing: .03em; }
.price .stars { font-size: .82rem; color: var(--ink-soft); font-family: var(--sans); }

/* утилит-классы вместо inline style= (CSP web-ЛК: style-src 'self' gsi/style, нет 'unsafe-inline' → inline-стили дропаются) */
.mt0 { margin-top: 0; }
.mt8 { margin-top: 8px; }
.mt14 { margin-top: 14px; }
.mt16 { margin-top: 16px; }
.center { text-align: center; }
#panel-balance .card.center { text-align: left; }   /* соседняя карточка выровнена влево — ряд не читался */
.minw0 { min-width: 0; }
.config-block.flush { border-top: 0; padding-top: 0; }
#balance-value { font-size: 2.1rem; margin-top: 2px; }
.dw-label { margin: 2px 2px 8px; }
.dw-hint { margin: 0 2px 8px; }
.empty.tight { padding: 14px 0; }

/* QR ссылки-подписки + store-ссылки Happ (вкладка «Подключение») */
.qr-host { display: flex; justify-content: flex-start; }
/* «Показать QR» и ряд магазинов — во всю ширину на ЛЮБОМ экране: на телефоне кнопка была
   обрубком 135px над рядом на 312px, единственным рваным краем в карточке. */
#show-qr { width: 100%; }
/* три магазина = три РАВНЫХ трека, а не flex:1 1 30% — тот давал 2+1 с растянутой сиротой */
.store-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px; margin: 12px 0 4px; }
.store-link { text-align: center; text-decoration: none; font-weight: 800; min-width: 0;
  white-space: nowrap; }   /* без nowrap подпись переносилась и кнопка становилась выше соседей */
.qr-img {
  width: 220px; max-width: 70%; height: auto; margin: 12px auto 0;
  background: #fff; padding: 10px;                     /* белое поле — контраст для сканера (в любой теме) */
  border-radius: var(--radius-sm); border: 1px solid var(--line-strong);
  box-shadow: 0 6px 18px -10px #04156255;
}

/* ============================================================================
   ДЕСКТОП. Тот же кабинет, но не растянутая мобила: нижний таб-бар — это паттерн
   БОЛЬШОГО ПАЛЬЦА, на мыши он уезжает на другой край экрана и оставляет посреди
   страницы одинокую колонку 720px. От 940px навигация переезжает в боковое меню,
   от 1200px главная, баланс и карточка «Подключение» становятся двухколоночными.
   Порог 940, а не 860: при 860–939 колонка контента выходила ÝЖЕ мобильных 672px
   (648 на 900), то есть расширение окна СУЖАЛО бы текст. Замерено.
   Разметка и JS общие: rail и таб-бар несут один и тот же data-tab.
   ============================================================================ */

/* ── ≥940px: боковое меню вместо нижнего таб-бара ─────────────────────────── */
@media (min-width: 940px) {
  /* шапка: бренд встаёт над боковым меню, иконки — у правого края окна */
  .app-header { padding-inline: var(--hd-pad); }

  /* Подложку меню рисует САМА сетка, а не .rail: sticky-элемент высотой в экран закрашивает только
     свой бокс, и на длинной странице колонка под ним осталась бы фоном страницы. Градиент с жёсткими
     стопами = панель + разделительная линия на всю высоту колонки при любой длине контента. */
  .app-shell { display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr); align-items: start;
    min-height: calc(100vh - var(--hd-h));   /* короткая страница: колонка меню всё равно до низа экрана */
    background: linear-gradient(90deg,
      var(--panel) 0 calc(var(--rail-w) - 1px),
      var(--line)  calc(var(--rail-w) - 1px) var(--rail-w),
      transparent  var(--rail-w)); }
  /* Контент центрирован в «холсте» справа от меню и не растекается на всю ширину монитора.
     flex-колонка + min-height нужны подвалу: без них он вставал сразу за последней карточкой и
     страница обрывалась посреди пустого холста (на «нет подписки» контент кончался на трети экрана). */
  .app-main { max-width: 1040px; margin: 0 auto; padding: 30px clamp(22px, 3vw, 44px) 40px;
    display: flex; flex-direction: column; min-height: calc(100vh - var(--hd-h)); }
  /* свободную высоту забирает АКТИВНАЯ панель, а не подвал: так у подвала остаётся его
     margin-top:40px как МИНИМАЛЬНЫЙ отступ на длинных страницах (у `margin-top:auto` минимума нет) */
  .panel.is-active { margin-bottom: auto; }
  .tabbar { display: none; }

  /* Меню — панель во всю высоту экрана, а не колонка, висящая в воздухе: она даёт странице
     вертикальную опору, когда контента мало (у нового юзера главная — полторы карточки). */
  .rail { display: flex; flex-direction: column; gap: 3px;
    position: sticky; top: var(--hd-h); max-height: calc(100vh - var(--hd-h)); overflow-y: auto;
    padding: 22px 14px 24px; }
  .rail-link {
    position: relative; display: flex; align-items: center; gap: 11px;
    padding: 11px 12px; border-radius: 11px; width: 100%;
    font: inherit; font-family: var(--sans); font-weight: 800; font-size: .93em;
    color: var(--ink-soft); background: none; border: 0; text-align: left; cursor: pointer;
    transition: background .14s ease, color .14s ease;
  }
  .rail-link .ri { width: 26px; flex: none; text-align: center; font-size: 16px; }
  .rail-link:hover { background: var(--panel-2); color: var(--ink); }
  .rail-link:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
  .rail-link.is-active { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
  /* фирменная засечка активного раздела — то же «подчёркивание акцентом», что у .tab, но сбоку */
  .rail-link.is-active::before {
    content: ""; position: absolute; left: -1px; top: 9px; bottom: 9px; width: 3px;
    border-radius: 999px; background: var(--accent);
  }

  /* попапы прижаты к тому же правому краю, что и вся группа иконок шапки (--hd-pad), а не
     к своей кнопке: так они не пляшут при смене набора иконок */
  .pop { right: var(--hd-pad); }
  /* разделы уже стоят в боковом меню — в drawer'е они были бы вторым таким же списком.
     На десктопе drawer = только профиль: привязка входов и аккаунт. */
  .drawer-nav, .drawer-nav + .drawer-sep { display: none; }
  .drawer-head { margin-bottom: 14px; }

  /* заголовки экранов на десктопе крупнее — иначе теряются в широкой колонке */
  .welcome { font-size: 2rem; margin: 4px 0 2px; }
  .screen-h1 { font-size: 2rem; margin: 4px 0 10px; }
  /* Всё ниже — ТОЛЬКО внутри .app-main. Без скоупа десктопные меры перебивали намеренные
     настройки экрана входа: `#view-login .lede` объявлен на 48ch, а общее правило тянуло его к 68ch. */
  .app-main .card { padding: 24px 26px; }
  /* проза читается до ~68 символов; на 900px строка была бы вдвое длиннее нормы */
  .app-main .hint, .app-main .lede, .app-main .kv-line { max-width: 68ch; }
  /* пустые состояния — узкий блок ПО ЦЕНТРУ карточки (без margin:auto ограничение по ширине
     утащило бы иконку и текст к левому краю широкой карточки) */
  .app-main .empty { max-width: 46ch; margin-inline: auto; }
  /* `max-width:340px` снят: он делал КАЖДУЮ блочную кнопку 340-пиксельной посреди колонки 954px,
     и её правый край не совпадал ни с одной карточкой над ней. Главные действия берут ширину своего
     блока, вторичное «Картой — скоро» — по содержимому. */
  .app-main #pay-card { width: auto; display: inline-flex; align-items: center; }

  /* ── Экран входа: матрёшка слева, форма справа ──────────────────────────
     Разметку не трогаем — четверо детей #view-login разводятся по колонкам явными
     grid-column/grid-row. На мобиле секция остаётся обычным блоком (стопкой), как была. */
  /* Островок по центру экрана, а не два блока по его краям. Ширину задают КОЛОНКИ, а не окно:
     при `1fr` левая колонка растягивалась на всё свободное место, между куклой и карточкой зияла
     дыра, и «лечить» её размером матрёшки (пробовал 300px) — сделать страницу нелепой. */
  #view-login {
    /* размер матрёшки подобран так, чтобы высота левой колонки СОШЛАСЬ с карточкой:
       иначе разница вылезает распорками внутри карточки, а это те же пустые места */
    --doll-w: clamp(140px, 11.5vw, 166px);
    max-width: 960px;
    /* Средняя колонка в 1px — сама разделительная линия. Так её высота РАВНА высоте строк сетки
       (то есть контента) без единого магического числа: абсолютное позиционирование пришлось бы
       привязывать к padding-box секции, которая из-за `align-content:center` выше контента. */
    /* Колонки РАВНЫЕ, а не «1fr + 400px»: при 1fr левая колонка была шире своего текста, и линия,
       стоящая точно посередине сетки, читалась прижатой к карточке (замер: 72px до текста против
       38px до карточки). Равные колонки совмещают математический центр с видимым. */
    display: grid; grid-template-columns: minmax(0, 400px) 1px minmax(0, 400px);
    column-gap: clamp(22px, 2.6vw, 40px); align-content: center; justify-content: center;
    padding-bottom: clamp(28px, 6vw, 56px);
  }
  /* линия затухает к краям — не палка встык, а тонкий шов между половинами */
  #view-login::before {
    /* `span 3`, а НЕ `1 / -1`: строки здесь неявные, и `-1` указывает на конец ЯВНОГО грида,
       которого нет — линия схлопывалась в одну первую строку (замерено). */
    content: ""; grid-column: 2; grid-row: 1 / span 3; width: 1px; justify-self: center;
    background: linear-gradient(180deg, transparent 0,
      var(--line-strong) 12%, var(--line-strong) 88%, transparent 100%);
  }
  #view-login > .login-hero  { grid-column: 1; grid-row: 1; align-items: center; margin: 0 0 14px; }
  #view-login > .display     { grid-column: 1; grid-row: 2; }
  #view-login > .lede        { grid-column: 1; grid-row: 3; margin-bottom: 0; max-width: none; }
  /* карточка тянется вдоль всех трёх строк героя и центрируется по его высоте */
  /* Левая колонка — симметричный блок: матрёшка ПО ЦЕНТРУ над заголовком (прижатая влево она
     читалась как стоящая сбоку от него), заголовок и подпись центрированы тем же `text-align`,
     что и на мобиле. Карточка — высотой ПО СОДЕРЖИМОМУ: `stretch` раздувал её до высоты левой
     колонки и оставлял внутри белого прямоугольника пустые поля сверху и снизу. */
  /* Карточка держит высоту ЛЕВОЙ колонки (stretch), а её содержимое распределяется по этой высоте
     (space-between). Так белая область остаётся крупной, но пустых полей сверху и снизу внутри неё
     нет: разница уходит в промежутки между блоками, а не в поля по краям. */
  /* Высоту карточка набирает САМИМИ элементами, а не распорками между ними. Прошлая попытка
     растянула её и увела разницу в две пружины по 65px — это те же пустые места, просто
     переставленные. Здесь крупнее становятся кнопки, разделитель и поля карточки, поэтому
     содержимое заполняет высоту, а `auto`-margin'ам остаются единицы пикселей. */
  #view-login > .login-card  { grid-column: 3; grid-row: 1 / span 3; margin: 0; align-self: stretch;
    max-width: none; padding: 30px 28px; display: flex; flex-direction: column; }
  /* Минимум задаём margin'ом ПРЕДЫДУЩЕГО элемента: в flex-контейнере соседние margin'ы не
     схлопываются, а складываются, поэтому `margin-bottom: 18px` + `margin-top: auto` даёт
     «не меньше 18px, а излишек — в распорку». Без этого на узком десктопе, где свободного места
     нет вовсе, `auto` обнулялся и кнопка прилипала к тексту вплотную (замерено на 1024). */
  /* шапка карточки по центру — просил владелец; кнопки и строки способов остаются слева */
  #view-login > .login-card > h2            { text-align: center; }
  #view-login > .login-card > .hint         { margin: 8px 0 18px; text-align: center; }
  #view-login > .login-card > #login-tg-btn { margin: auto 0 18px; padding: 18px 20px; font-size: 1.08rem; }
  #view-login > .login-card > .or-divider   { margin: auto 0 16px; }
  #view-login > .login-card > .login-alt    { margin-top: 0; gap: 14px; }
  #view-login .btn-soon                     { padding: 17px 18px; }
  #view-login > .login-card > .dev-login    { margin-top: 18px; }
  /* Ореол на десктопе СНЯТ. На мобиле кукла по центру экрана и мягкое пятно за ней читается как
     подсветка; в колонке рядом с прямоугольной карточкой то же пятно — размытая клякса без края,
     которая ломает и без того хрупкое выравнивание. Ровные линии важнее декора. */
  #view-login > .login-hero::before { content: none; }
  /* dollFloat качал матрёшку ±5px БЕСКОНЕЧНО. Рядом с прямоугольной карточкой любая выверенная
     линия из-за этого «дышит», и композиция читается как скачущая. Вход остаётся, качание снято. */
  #view-login .doll-hero { animation: dollIn .8s cubic-bezier(.2,.8,.2,1) both; }
  #view-login .doll-hero { width: var(--doll-w); }

  /* ── ПЛОТНОСТЬ ДЕСКТОПА ────────────────────────────────────────────────────
     Мобильные кегли на мониторе читаются как мелкий шрифт: замер до правки —
     .meta/.bar-row/.kv dt 11.84px, .sec-row .t 12.48px, .plan-feat 12.8px.
     Здесь они подняты до 13–15px; мобильные значения не трогаются. */
  .app-main .meta, .app-main .bar-row, .app-main .kv dt,
  .app-main .mini .k, .app-main .prov .p small { font-size: .84rem; }
  .app-main .plan-feat, .app-main .kv-line, .app-main .mini .s { font-size: .88rem; }
  .app-main .hint { font-size: .92rem; }
  .app-main .sec-row .t, .app-main .section-title, .app-main .card-title { font-size: .86rem; letter-spacing: .06em; }
  .app-main .kv dd { font-size: 1.3rem; }
  .app-main .mini .v { font-size: 1.7rem; }
  .app-main .pill { padding: 5px 12px; }
  .app-main .soon-tag { font-size: .66rem; padding: 4px 10px; }
  .app-main .sub-name { font-size: 1.2rem; }

  /* Кнопки одной высоты: было 40px у store/копировать против 48px у остальных. */
  .app-main .btn-small { min-height: 48px; font-size: .92rem; padding: 10px 16px; }
  .app-main .store-row { gap: 10px; }

  /* Пустые состояния занимали 952×188 при иконке 56px — почти пустая карточка. */
  .app-main .empty { padding: 14px 0; gap: 8px; font-size: .9rem; }
  .app-main .empty .eb { width: 44px; height: 44px; font-size: 20px; border-radius: 13px; }

  /* Трафик-бар и строки под ним — крупнее, чтобы читались с расстояния монитора */
  .app-main .traffic-bar { height: 11px; }
  .app-main .bar-row b { font-size: .92rem; }

  /* Провайдеры оплаты: строка названия была мельче своей же подписи-хвоста */
  .app-main .prov .p b { font-size: 1rem; }
  .app-main .prov .p { padding: 15px 16px; }

  /* Карточки тарифов: заголовок и цена крупнее, признаки — читаемые */
  .app-main .plan-card { padding: 18px 20px; }
  .app-main .plan-card .plan-title { font-size: 1.12rem; }
  .app-main .plan-card .price, .app-main .price { font-size: 1.35rem; }

  /* Ссылка-подписка занимает три строки — кнопка «Копировать» рядом с ней висела по центру
     этой высоты. Прижимаем её к верхней строке, чтобы ряд читался как «поле + действие». */
  .app-main .config-row { align-items: flex-start; }
  .app-main .config-url { font-size: .86rem; line-height: 1.5; padding: 11px 13px; }

  /* Шаги: пунктирные разделители после каждой строки дробили и без того короткий список */
  .app-main .steps .hint { padding: 7px 0; border-bottom: 0; }
  .app-main .steps { gap: 2px; }

  /* Промокод: поле и кнопка одной высоты и одного веса */
  .app-main .code-input { min-height: 48px; font-size: .95rem; }

  /* Заголовок карточки подписки и её бейдж — на одной оптической линии */
  .app-main .sub-top { gap: 12px; }

  /* Статус подписки дублировался ТРИЖДЫ на одном экране: бейдж над секцией, слово в заголовке
     карточки и пилюля в ней же. На десктопе оставляем пилюлю внутри карточки — она рядом с
     данными, к которым относится. На мобиле карточка уходит под сгиб, поэтому бейдж там нужен. */
  
  /* «Показать QR» стоял узкой кнопкой над рядом из трёх — ряд не читался как ряд */
  /* пустая карточка истории занимала 950×155 ради одного значка */
  .app-main .card > .empty { padding: 6px 0; }

  .app-foot { display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
    margin-top: 40px; padding-top: 16px; border-top: 1px solid var(--line);
    font-size: .78rem; color: var(--ink-dim); }
  .af-brand { font-weight: 800; }
  .af-link { font: inherit; font-family: var(--sans); font-weight: 800; color: var(--ink-dim);
    background: none; border: 0; padding: 2px 0; cursor: pointer; }
  .af-link:hover { color: var(--accent); }
  .af-link:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
}

/* ── ≥1360px: главная и баланс — двухколоночный дашборд ──────────────────────
   Порог 1360, а не 1200: при 1200 контент 900px делился 1.5fr/1fr, и карточка подписки падала
   с 899 до 527px — расширение окна на 1px УХУДШАЛО вид. На 1360 левой колонке остаётся ~600. */
@media (min-width: 1360px) {
  #panel-home.is-active {
    display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    column-gap: var(--gutter); align-items: start;
  }
  #panel-home.is-active > .welcome { grid-column: 1 / -1; }
  #panel-home.is-active > .tier { grid-column: 1 / -1; justify-self: start; }
  .col-main, .col-side { display: block; min-width: 0; }
  /* в боковой колонке мини-карточки идут стопкой, а не парой (там ширины на пару нет) */
  .col-side .duo { grid-template-columns: 1fr; margin-top: 0; }
  .col-side .mini { padding: 16px 18px; }
  .col-side .mini .v { font-size: 1.5rem; }
  /* Ровняем по КАРТОЧКАМ, а не по метке: с padding-top:20px правая карточка вставала на 32px
     выше левой, и ряд не читался как ряд (замер: top 149 против 181). */
  .col-side { padding-top: 52px; }

  /* без align-items:start карточки ряда тянутся до общей высоты — иначе низ пары «Баланс/Промокод» рваный */
  .bal-duo { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--gutter); }
  /* auto-fit, а не «1fr 1fr»: способов оплаты ТРИ, и жёсткие две колонки оставляли «Криптовалюту»
     половинкой с пустой ячейкой рядом. auto-fit даёт столько колонок, сколько влезает по 270px —
     сейчас ровно 3 на всех ширинах ≥1200. NB: при четвёртом способе неполный ряд вернётся. */
  #panel-balance .prov { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
    gap: var(--gutter); }

  /* «Подключение»: слева ссылка/QR/сторы, справа — шаги. Явные grid-column вместо areas:
     .steps пришит ко 2-й колонке на все три ряда, остальное само укладывается в 1-ю.
     Порог именно 1200: при 940–1199 внутри карточки ~690px, и ссылка-подписка ужималась в столбик
     155–265px — ýже, чем на самом узком телефоне. Замерено. */
  #connect-block > .card {
    display: grid; grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
    column-gap: var(--gutter); align-items: start;
  }
  #connect-block > .card > .config-block { grid-column: 1; }
  #connect-block > .card > .store-row    { grid-column: 1; }
  #connect-block > .card > details       { grid-column: 1; margin-top: 14px; }
  #connect-block > .card > .steps        { grid-column: 2; grid-row: 1 / span 3; margin-top: 0; }
}
