/* Сайт и кабинет. С 2026-10-12 — в духе top.co (просьба владельца): тёплый
   почти белый фон, чернильный текст, синий акцент, Inter, одно слово от руки
   (Caveat) с росчерком, кнопки-пилюли, большие скруглённые карточки без рамок
   и теней, тёмная полоса с выпуклым краем. Взяты только приёмы и цвета:
   ни знака, ни текстов, ни рисунков, ни их рукописного шрифта (он платный)
   у top.co не брали — рисунки на главной свои, в разметке.
   Намеренно:
   - шрифты свои, из /static/fonts: политика страницы — только свой адрес, а
     сайт, который обещает «no trackers», не зовёт Google Fonts;
   - скрипт один и свой (/static/site.js): тема, копирование ключа,
     закрытие списка языков и пометка «нажато мышью» для рамки фокуса;
     пример ключа и его хеш рисует сервер, меню на телефоне, список языков
     и вопросы — details. Рассказ на главной темнеет при прокрутке силами
     стиля (animation-timeline), скрипта для этого нет;
   - тема светлая по умолчанию, тёмная — кнопкой в шапке; за настройкой
     системы сайт не следует (админка следует, у неё свой admin.css);
   - поле внутри всех блоков — 24 px (владелец, 2026-10-10), и у больших
     карточек со скруглением 32 px тоже. */

@font-face { font-family: "Inter"; font-style: normal; font-weight: 400 700; font-display: swap; src: url("/static/fonts/inter.woff2") format("woff2"); }
@font-face { font-family: "Caveat"; font-style: normal; font-weight: 600; font-display: swap; src: url("/static/fonts/caveat.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400 500; font-display: swap; src: url("/static/fonts/jetbrains-mono.woff2") format("woff2"); }

/* Цвета top.co, замеренные на их странице: фон #FFFDF9, вторая подложка
   #F7F5EF, текст #14161F, акцент #3480F1. Акцент на светлом фоне даёт
   контраст 3,7 — мало для мелкого текста, поэтому у ссылок и подписей свой,
   темнее (#1F62D0, 5,5 на фоне и 5,1 на карточке). */
:root {
  --bg: #fffdf9;
  --bg-glass: rgb(255 253 249 / 0.72);
  --surface: #f7f5ef;
  /* Подложка внутри карточки: кнопка второго ряда и плитки на #F7F5EF
     сливались бы с ней. */
  --surface-2: #ecebe4;
  --surface-2-hover: #e3e1d9;
  --field: #fffdf9;
  --band: #f7f5ef;
  --text: #14161f;
  --text-2: #3b3e4a;
  --text-3: #2a2d38;
  --muted: #5e616d;
  --faint: #8c8f99;
  --line: rgb(20 22 31 / 0.12);
  --line-soft: rgb(20 22 31 / 0.07);
  --line-strong: rgb(20 22 31 / 0.22);
  --wash: rgb(20 22 31 / 0.05);
  --accent: #3480f1;
  --accent-text: #1f62d0;
  --accent-soft: #e4eefd;
  --accent-ring: rgb(52 128 241 / 0.24);
  /* Кнопки: главная — чернильная пилюля, вторая — на подложке. */
  --btn: #14161f;
  --btn-hover: #2e3240;
  --on-btn: #fffdf9;
  --btn-2: #f7f5ef;
  --btn-2-hover: #efece4;
  /* Тёмная карточка: старший тариф, команды проверки. */
  --ink: #14161f;
  --ink-text: #fffdf9;
  --ink-2: #c9cbd3;
  --ink-3: #dedfe5;
  --ink-muted: #a3a6b1;
  --ink-line: rgb(255 253 249 / 0.14);
  --ink-edge: rgb(255 253 249 / 0.24);
  --ink-wash: rgb(255 253 249 / 0.08);
  --ink-accent: #8db8ff;
  --ink-dot: #6fa6ff;
  /* Тёмная полоса с призывом внизу главной. */
  --cta-bg: #14161f;
  --cta-text: #fffdf9;
  --cta-muted: #b9bbc4;
  --cta-accent: #8db8ff;
  --ok: #157a3d;
  --ok-dot: #22a15a;
  --ok-bg: rgb(34 161 90 / 0.1);
  --warn: #8f5600;
  --warn-bg: rgb(245 166 35 / 0.16);
  --bad: #c0362c;
  --bad-line: rgb(192 54 44 / 0.3);
  --bad-bg: rgb(192 54 44 / 0.07);
  /* Вторая линия графика: фиолетовый, чтобы не путаться ни с акцентом
     первой линии, ни с жёлтым и красным порогов. */
  --chart-2: #8b5cf6;
  --r-card: 24px;
  --r-big: 32px;
  --r-field: 14px;
  --wrap: 1232px;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
  /* Иероглифов в Caveat нет: для них — тот же гротеск, что вокруг. */
  --hand: "Caveat", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
  color-scheme: light;
}
/* Тёмная — только по выбору: атрибут ставит site.js из localStorage. Фон —
   тот же чернильный #14161F, карточки чуть светлее, текст тёплый белый,
   акцент светлее, главная кнопка наоборот: светлая с тёмным текстом. */
:root[data-theme="dark"] {
  --bg: #14161f;
  --bg-glass: rgb(20 22 31 / 0.72);
  --surface: #1e212b;
  --surface-2: #2a2e3a;
  --surface-2-hover: #343846;
  --field: #14161f;
  --band: #1e212b;
  --text: #f4f2ec;
  --text-2: #c8cad2;
  --text-3: #dadbe1;
  --muted: #9a9da9;
  --faint: #6d717d;
  --line: rgb(255 253 249 / 0.11);
  --line-soft: rgb(255 253 249 / 0.06);
  --line-strong: rgb(255 253 249 / 0.22);
  --wash: rgb(255 253 249 / 0.06);
  --accent: #6fa6ff;
  --accent-text: #8db8ff;
  --accent-soft: rgb(111 166 255 / 0.2);
  --accent-ring: rgb(111 166 255 / 0.3);
  --btn: #f4f2ec;
  --btn-hover: #ffffff;
  --on-btn: #14161f;
  --btn-2: #1e212b;
  --btn-2-hover: #262a35;
  /* Тёмная карточка на тёмном фоне — глубже фона и с рамкой. */
  --ink: #0c0d13;
  --cta-bg: #232736;
  --cta-muted: #b4b7c2;
  --ok: #5fd08a;
  --ok-dot: #4ac07a;
  --warn: #f2b84b;
  --bad: #ff8a80;
  --bad-line: rgb(255 138 128 / 0.35);
  --bad-bg: rgb(255 138 128 / 0.08);
  --chart-2: #b197fc;
  color-scheme: dark;
}

* { box-sizing: border-box; }
/* Кнопки получают display: inline-flex, и без этого правила атрибут hidden их
   не прятал бы — кнопки темы и копирования были бы видны и без скрипта. */
[hidden] { display: none !important; }
/* Нажатие на кнопку или ссылку следа не оставляет (владелец, 2026-10-03:
   «отмечаются как будто, выглядит некрасиво»). Следов было три:
   - на телефоне браузер на миг заливает нажатое: Chrome в режиме телефона
     синим, rgba(51, 181, 229, 0.4). Отсюда tap-highlight ниже;
   - на телефоне :hover остаётся на последнем нажатом до следующего касания:
     кнопка темы стояла в сером круге, ссылка цвета акцента. Поэтому каждое
     правило наведения на сайте — внутри @media (hover: hover), где есть мышь;
   - Chrome рисует рамку :focus-visible и на кнопке, нажатой мышью, стоит
     после щелчка нажать любую клавишу, хоть Shift или Esc: глобус, закрытый
     по Esc, оставался в рамке. Поэтому site.js помечает щелчок и касание
     (data-input="pointer"), а Tab пометку снимает: рамка остаётся тому, кто
     ходит клавиатурой. Без скрипта рамку решает браузер, как раньше. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; -webkit-tap-highlight-color: transparent; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 16px/1.5 var(--sans); font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  display: flex; flex-direction: column; min-height: 100vh;
}
a { color: inherit; text-decoration: none; }
@media (hover: hover) { a:hover { color: var(--accent-text); } }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* none, а не просто без правила: иначе Chrome нарисовал бы свою рамку. */
:root[data-input="pointer"] :focus-visible { outline: none; }
h1, h2, h3 { font-weight: 500; line-height: 1.1; margin: 0; }
/* Длинные слова переводов — «Datenschutzerklärung», «конфиденциальности» —
   крупным кеглем шире телефона. Слово, которое не влезает в строку целиком,
   рвётся, а не вылезает за край; по слогам — только на телефоне (ниже), чтобы
   на широком экране заголовки не резались без нужды. */
h1, h2 { overflow-wrap: break-word; }
h1 { font-size: clamp(40px, 5.4vw, 64px); letter-spacing: -0.02em; margin: 0 0 16px; text-wrap: balance; }
h2 { font-size: clamp(30px, 3.4vw, 44px); letter-spacing: -0.02em; margin: 48px 0 16px; text-wrap: balance; }
h3 { font-size: 18px; line-height: 1.3; letter-spacing: -0.01em; margin: 0 0 6px; }
p { margin: 0 0 12px; text-wrap: pretty; }
small { font-size: 14px; }
small, .muted { color: var(--muted); }
code, .mono { font-family: var(--mono); font-size: 14px; }
strong { font-weight: 600; }
hr { border: 0; border-top: 1px solid var(--line); margin: 32px 0; }
/* Якоря под липкой шапкой. */
[id] { scroll-margin-top: 96px; }
/* Иероглифы, кана и хангыль — системным шрифтом: в Inter их нет. Сжатие
   букв под латиницу им вредит, а строки нужны чуть выше. */
:is(:lang(ja), :lang(ko), :lang(zh)) :is(h1, h2, h3) { letter-spacing: 0; line-height: 1.3; }
:lang(ko) :is(h1, h2) { word-break: keep-all; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
main { flex: 1; padding: clamp(24px, 3.5vw, 48px) 0 96px; }
main.narrow { display: flex; align-items: center; padding: clamp(32px, 6vw, 80px) 0; }
main.narrow .wrap { max-width: 520px; }
main.home, main.doc { padding: 0; }

/* Шапка: липкая, полупрозрачная, с размытием под собой. Черта снизу
   проявляется с прокруткой (вверху страницы её нет, как у top.co); где
   анимации по прокрутке нет, черта стоит всегда. */
header.top {
  position: sticky; top: 0; z-index: 10;
  background: var(--bg-glass); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--line-soft);
}
@supports (animation-timeline: scroll()) {
  header.top { animation: header-edge linear both; animation-timeline: scroll(root); animation-range: 0 64px; }
}
@keyframes header-edge { from { border-bottom-color: transparent; } to { border-bottom-color: var(--line-soft); } }
header.top .bar, nav.tabs, .menu-body { max-width: var(--wrap); margin: 0 auto; }
header.top .bar { position: relative; display: flex; align-items: center; gap: 8px; padding: 16px 24px 10px; }
.brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; font-size: 20px; letter-spacing: -0.02em; color: var(--text); }
header.top .bar > .brand { margin-right: auto; }
/* Знак — тот же, что у окна: звезда на тёмном круге. */
.brand img { width: 26px; height: 26px; border-radius: 50%; display: block; }
@media (hover: hover) { .brand:hover { color: var(--text); } }
nav.primary { display: flex; flex-wrap: wrap; gap: 4px 28px; font-size: 16px; font-weight: 500; color: var(--text); }
header.top .bar > nav.primary { margin-right: 20px; }
nav.primary a.on { color: var(--accent-text); }
nav.session { display: flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 500; }
header.top .bar > nav.session { margin-right: 4px; }
nav.session > a:not(.button), nav.session button.link { padding: 6px 10px; color: var(--text); font-weight: 500; }
nav.session > a.on:not(.button) { color: var(--accent-text); }
/* Вкладки админки — пилюли во второй строке шапки. */
nav.tabs { display: flex; flex-wrap: wrap; gap: 4px; padding: 0 24px 12px; }
nav.tabs a { font-size: 14px; padding: 6px 14px; border-radius: 999px; color: var(--muted); }
@media (hover: hover) { nav.tabs a:hover { color: var(--text); } }
nav.tabs a.on { background: var(--wash); color: var(--text); }
/* Кнопка темы и глобус: круги в 40 px. Луна в светлой, солнце в тёмной. */
button.theme { width: 40px; height: 40px; padding: 0; background: transparent; color: var(--text); flex: none; }
@media (hover: hover) { button.theme:hover { background: var(--surface); color: var(--text); } }
button.theme svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
button.theme .sun { display: none; }
:root[data-theme="dark"] button.theme .sun { display: block; }
:root[data-theme="dark"] button.theme .moon { display: none; }
/* Язык: список — `details`, без скрипта. Список прижат к правому краю
   строки шапки, а не к глобусу: на узком экране глобус стоит в середине
   строки, и список от него уезжал бы за левый край. */
details.lang > summary {
  list-style: none; cursor: pointer; width: 40px; height: 40px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center; color: var(--text);
}
details.lang > summary::-webkit-details-marker { display: none; }
details.lang[open] > summary { background: var(--surface); }
@media (hover: hover) { details.lang > summary:hover { background: var(--surface); color: var(--text); } }
details.lang svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
details.lang > ul {
  position: absolute; top: calc(100% - 2px); right: 24px; z-index: 11;
  display: grid; grid-template-columns: repeat(2, minmax(128px, 1fr)); gap: 2px;
  list-style: none; margin: 0; padding: 8px; max-height: calc(100vh - 96px); overflow-y: auto;
  background: var(--bg); border: 1px solid var(--line-strong); border-radius: 20px;
  box-shadow: 0 16px 40px rgb(20 22 31 / 0.12);
}
details.lang > ul a { display: block; padding: 7px 12px; border-radius: 12px; font-size: 15px; color: var(--text-2); white-space: nowrap; }
@media (hover: hover) { details.lang > ul a:hover { background: var(--surface); color: var(--text); } }
details.lang > ul a[aria-current] { background: var(--surface); color: var(--text); font-weight: 600; }
/* Узкий экран: имя, тёмная пилюля и круглая кнопка меню из двух черт.
   Меню — details, без скрипта. */
a.button.cta { display: none; }
details.menu { display: none; }
details.menu > summary {
  list-style: none; cursor: pointer; width: 40px; height: 40px; border-radius: 50%; background: var(--surface);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
details.menu > summary::-webkit-details-marker { display: none; }
details.menu > summary span { width: 16px; height: 1.75px; border-radius: 1px; background: currentColor; transition: transform 0.15s; }
details.menu[open] > summary span:first-child { transform: translateY(3.4px) rotate(45deg); }
details.menu[open] > summary span:last-child { transform: translateY(-3.4px) rotate(-45deg); }
.menu-body { display: none; flex-direction: column; gap: 20px; padding: 12px 24px 24px; }
.menu-body nav.primary { flex-direction: column; gap: 2px; font-size: 20px; margin: 0; }
.menu-body nav.primary a { padding: 6px 0; }
.menu-body nav.session { flex-wrap: wrap; margin-left: -10px; }
/* Глобус и тема в меню — только на телефоне, где их нет в строке. */
.menu-body .prefs { display: none; position: relative; align-items: center; gap: 4px; margin-left: -8px; }
.menu-body .prefs details.lang > ul { top: auto; bottom: calc(100% + 4px); left: 0; right: auto; max-height: calc(100vh - 160px); }
header.top:has(details.menu[open]) .menu-body { display: flex; }

/* Кнопки — пилюли top.co: главная чернильная, вторая на подложке, теней нет.
   Отступ сверху на 2 px меньше нижнего: так строка Inter встаёт по центру. */
button, a.button {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 18px 13px; border: 0; border-radius: 100px;
  background: var(--btn); color: var(--on-btn); font: 500 16px/24px var(--sans);
  cursor: pointer; white-space: nowrap; text-decoration: none;
}
@media (hover: hover) { button:hover, a.button:hover { background: var(--btn-hover); color: var(--on-btn); } }
button.secondary, a.button.secondary { background: var(--btn-2); color: var(--text); }
@media (hover: hover) { button.secondary:hover, a.button.secondary:hover { background: var(--btn-2-hover); color: var(--text); } }
button.danger, a.button.danger { background: var(--bad-bg); color: var(--bad); }
@media (hover: hover) { button.danger:hover { background: var(--bad); color: #fff; } }
button.link { padding: 0; border: 0; border-radius: 0; background: none; color: var(--accent-text); font-weight: 500; font-size: inherit; line-height: inherit; }
@media (hover: hover) { button.link:hover { background: none; color: var(--text); } }
button.link.danger { color: var(--bad); }
/* Кнопка в шапке — меньше, как у top.co. */
nav.session a.button, a.button.cta { padding: 6px 16px 7px; font-size: 15px; line-height: 24px; }
nav.session a.button.secondary.on { background: var(--btn); color: var(--on-btn); }
@media (hover: hover) { nav.session a.button.secondary.on:hover { background: var(--btn-hover); color: var(--on-btn); } }
.big { padding: 12px 22px 14px; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 24px 0 0; }
/* На подложке карточки вторая кнопка темнее подложки, иначе её не видно. */
:is(section.panel, details.panel, details.list, .plan, .system, .tile, figure.chart, .pay-cards .pay-net) { --btn-2: var(--surface-2); --btn-2-hover: var(--surface-2-hover); }

/* Формы */
form { margin: 0; }
form.inline { display: inline; }
form.stack { display: grid; gap: 20px; max-width: 760px; }
form.stack.wide { max-width: none; }
form.stack > button { justify-self: start; }
.field { display: grid; gap: 6px; align-content: start; }
.field > span, label.field > span { font-size: 14px; font-weight: 500; }
.field small { font-size: 13px; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 20px 24px; }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 20px 24px; }
label.check { display: flex; align-items: flex-start; gap: 12px; font-size: 15px; cursor: pointer; }
label.check input { margin: 3px 0 0; width: 16px; height: 16px; flex: none; accent-color: var(--accent); }
/* Радиокнопки не поле: выбор монеты прячет их сам (`.pay-pick > input`), а
   это правило точнее того и растягивало их на всю ширину блока. */
input:not([type=checkbox]):not([type=radio]):not([type=hidden]), select, textarea {
  width: 100%; font: 16px/1.4 var(--sans); padding: 12px 16px;
  border: 1px solid var(--line-strong); border-radius: var(--r-field);
  background: var(--field); color: var(--text);
}
input::placeholder, textarea::placeholder { color: var(--faint); }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
input.key { font: 500 20px/1.3 var(--mono); letter-spacing: 0.04em; text-transform: uppercase; padding: 16px 18px; border-radius: 16px; }
textarea.code { font: 13px/1.55 var(--mono); tab-size: 2; white-space: pre; overflow: auto; resize: vertical; }
form.row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
form.row select { width: auto; min-width: 260px; }

/* Сообщения */
.notice { border-radius: 16px; padding: 14px 24px; margin: 0 0 24px; background: var(--surface); color: var(--text); }
.notice p:last-child { margin: 0; }
.notice.ok { background: var(--ok-bg); color: var(--ok); }
.notice.error { background: var(--bad-bg); color: var(--bad); border: 1px solid var(--bad-line); }
.notice.warn { background: var(--warn-bg); }
.notice.ok, .notice.error { font-weight: 500; }

/* Состояние: точка и слово */
.badge { display: inline-flex; align-items: center; gap: 8px; font: 500 13px/1.3 var(--sans); color: var(--muted); white-space: nowrap; }
.badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--faint); flex: none; }
.badge.ok { color: var(--ok); }
.badge.ok::before { background: var(--ok-dot); }
.badge.bad { color: var(--bad); }
.badge.bad::before { background: var(--bad); }
.badge.warn { color: var(--warn); }
.badge.warn::before { background: var(--warn); }
.tag { display: inline-block; font: 500 12px/1.6 var(--sans); color: var(--text-2); background: var(--wash); border-radius: 100px; padding: 0 8px; vertical-align: 2px; }

/* Заголовок страницы */
.head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 40px; }
.head h1 { margin-bottom: 8px; }
.head p { margin: 0; font-size: 18px; line-height: 28px; color: var(--text-2); }
.crumb { font-size: 14px; margin-bottom: 16px; }
.crumb a { color: var(--muted); }
/* Подпись над заголовком — пилюлей с синей точкой. */
.eyebrow, .kicker {
  display: inline-flex; align-items: center; gap: 8px; margin: 0 0 24px; padding: 3px 14px 4px;
  border-radius: 100px; background: var(--surface); font: 500 14px/24px var(--sans); color: var(--text-2);
}
.eyebrow::before, .kicker::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }

/* Таблицы: на подложке, подписи мелким серым */
.table { width: 100%; overflow-x: auto; border-radius: var(--r-card); background: var(--surface); margin: 0 0 24px; }
table { width: 100%; border-collapse: collapse; font-size: 15px; }
th, td { text-align: left; padding: 16px 24px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
td + td, th + th { padding-left: 8px; }
th { padding-top: 14px; padding-bottom: 14px; font: 500 13px/1.4 var(--sans); color: var(--muted); white-space: nowrap; border-bottom-color: var(--line); }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; white-space: nowrap; }
td.num { font-family: var(--mono); font-size: 14px; }
.sub { display: block; color: var(--muted); font-size: 13px; }
td.act { text-align: right; white-space: nowrap; vertical-align: middle; }
td.act form + form { margin-left: 12px; }

/* Навигация по страницам длинного списка */
.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px; margin: -8px 0 32px; font-size: 14px; }
.pager .links { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.pager .links > * { display: inline-grid; place-items: center; min-width: 32px; height: 32px; padding: 0 10px; border-radius: 999px; }
.pager a { color: var(--text); text-decoration: none; }
@media (hover: hover) { .pager a:hover { background: var(--surface); } }
.pager .current { background: var(--btn); color: var(--on-btn); font-weight: 500; }

/* Переписка с поддержкой: свои справа на голубой подложке, чужие слева на
   своей, переводы строк как набраны. */
.chat-thread { display: flex; flex-direction: column; gap: 12px; margin: 0 0 20px; }
.chat-thread > p { margin: 0; }
.msg { align-self: flex-start; max-width: min(560px, 85%); }
.msg.mine { align-self: flex-end; }
.msg .meta { font: 12px/1.4 var(--sans); color: var(--muted); margin: 0 6px 4px; }
.msg.mine .meta { text-align: right; }
.msg .text { white-space: pre-wrap; overflow-wrap: anywhere; padding: 10px 16px; border-radius: 20px; background: var(--field); color: var(--text); font-size: 15px; line-height: 1.5; }
.msg.mine .text { background: var(--accent-soft); }
form.compose textarea { resize: vertical; min-height: 88px; }
form.compose .row-acts { margin-top: 10px; }
/* Поиск по номеру над списком, рядом с кнопкой */
.head .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
form.search { display: flex; align-items: center; gap: 8px; }
form.search input { width: 160px; }

/* Оплата: сумма крупно. Выбор — монета, потом сеть, потом карточка с QR
   (`web/pay.rs`): радиокнопки без скрипта, видна одна карточка. Кнопки
   спрятаны, но остаются в фокусе клавиатуры: рамка на плитке — от них. После
   щелчка по плитке рамки нет, как у всех кнопок (data-input, начало файла):
   выбранную и так видно по обводке. */
strong.amount { font: 500 18px/1.3 var(--mono); color: var(--text); }
.pay-pick { position: relative; margin: 20px 0 16px; }
.pay-pick > input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.pay-pick p.step { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font: 500 14px/1.4 var(--sans); color: var(--muted); }
.pay-pick p.step .num { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--surface-2); color: var(--text-2); font-size: 12px; }
.pay-coins, .pay-nets { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 20px; }
.pay-nets { display: none; }
.pay-coins label, .pay-nets label { display: inline-flex; align-items: center; gap: 12px; min-width: 156px; padding: 10px 18px 10px 10px; border: 1px solid var(--line-strong); border-radius: 18px; background: var(--field); cursor: pointer; transition: border-color .12s, background .12s, box-shadow .12s; }
@media (hover: hover) { .pay-coins label:hover, .pay-nets label:hover { background: var(--surface-2); } }
.pay-pick svg.ico { flex: none; display: block; width: 32px; height: 32px; }
.pay-pick .what { display: grid; line-height: 1.25; }
section.panel > .body .pay-pick .what strong, .pay-pick .what strong { font: 600 15px/1.25 var(--sans); color: var(--text); }
.pay-pick .what small { font-size: 12px; color: var(--muted); }
.pay-cards .pay-coin, .pay-cards .pay-net { display: none; }
.pay-cards .pay-net { align-items: flex-start; gap: 20px; padding: 24px; border-radius: var(--r-card); background: var(--field); border: 1px solid var(--line); }
/* Белое поле вокруг кода рисует сам QR (тихая зона в четыре модуля), своя
   подложка и отступ тут были вторым полем вокруг первого. */
.pay-net > svg { flex: none; display: block; width: 168px; height: 168px; border-radius: 12px; border: 1px solid var(--line); }
.pay-text { min-width: 0; }
.pay-net h4 { margin: 2px 0 10px; font-size: 16px; font-weight: 600; }
.pay-net code.addr { display: block; font: 14px/1.5 var(--mono); word-break: break-all; user-select: all; color: var(--text); background: var(--surface); border-radius: 12px; padding: 10px 12px; }
.pay-net button { margin-top: 10px; }
.pay-net p { margin: 10px 0 0; }
@media (max-width: 560px) {
  .pay-cards .pay-net { flex-direction: column; }
  /* По две в ряд и ровно в половину: последняя в нечётном ряду не
     растягивается на всю ширину и не выглядит главной. */
  .pay-coins label, .pay-nets label { flex: 0 1 calc(50% - 5px); min-width: 0; }
}
/* Выбранная монета открывает свои сети и карточки, выбранная сеть — свою
   карточку. Кнопок в конфиге может быть три монеты и тринадцать пар монета ·
   сеть (`crypto::TOKENS`, пара не повторяется); правил на одно больше каждого,
   четыре и четырнадцать, лишнее ничего не ломает. */
.pay-pick > #coin-0:checked ~ .pay-nets-0, .pay-pick > #coin-1:checked ~ .pay-nets-1, .pay-pick > #coin-2:checked ~ .pay-nets-2, .pay-pick > #coin-3:checked ~ .pay-nets-3 { display: flex; }
.pay-pick > #coin-0:checked ~ .pay-cards .pay-coin-0, .pay-pick > #coin-1:checked ~ .pay-cards .pay-coin-1, .pay-pick > #coin-2:checked ~ .pay-cards .pay-coin-2, .pay-pick > #coin-3:checked ~ .pay-cards .pay-coin-3 { display: block; }
.pay-pick > #pay-0:checked ~ .pay-cards .pay-card-0, .pay-pick > #pay-1:checked ~ .pay-cards .pay-card-1, .pay-pick > #pay-2:checked ~ .pay-cards .pay-card-2, .pay-pick > #pay-3:checked ~ .pay-cards .pay-card-3, .pay-pick > #pay-4:checked ~ .pay-cards .pay-card-4, .pay-pick > #pay-5:checked ~ .pay-cards .pay-card-5, .pay-pick > #pay-6:checked ~ .pay-cards .pay-card-6, .pay-pick > #pay-7:checked ~ .pay-cards .pay-card-7, .pay-pick > #pay-8:checked ~ .pay-cards .pay-card-8, .pay-pick > #pay-9:checked ~ .pay-cards .pay-card-9, .pay-pick > #pay-10:checked ~ .pay-cards .pay-card-10, .pay-pick > #pay-11:checked ~ .pay-cards .pay-card-11, .pay-pick > #pay-12:checked ~ .pay-cards .pay-card-12, .pay-pick > #pay-13:checked ~ .pay-cards .pay-card-13 { display: flex; }
.pay-pick > #coin-0:checked ~ .pay-coins label[for="coin-0"], .pay-pick > #coin-1:checked ~ .pay-coins label[for="coin-1"], .pay-pick > #coin-2:checked ~ .pay-coins label[for="coin-2"], .pay-pick > #coin-3:checked ~ .pay-coins label[for="coin-3"], .pay-pick > #pay-0:checked ~ .pay-nets label[for="pay-0"], .pay-pick > #pay-1:checked ~ .pay-nets label[for="pay-1"], .pay-pick > #pay-2:checked ~ .pay-nets label[for="pay-2"], .pay-pick > #pay-3:checked ~ .pay-nets label[for="pay-3"], .pay-pick > #pay-4:checked ~ .pay-nets label[for="pay-4"], .pay-pick > #pay-5:checked ~ .pay-nets label[for="pay-5"], .pay-pick > #pay-6:checked ~ .pay-nets label[for="pay-6"], .pay-pick > #pay-7:checked ~ .pay-nets label[for="pay-7"], .pay-pick > #pay-8:checked ~ .pay-nets label[for="pay-8"], .pay-pick > #pay-9:checked ~ .pay-nets label[for="pay-9"], .pay-pick > #pay-10:checked ~ .pay-nets label[for="pay-10"], .pay-pick > #pay-11:checked ~ .pay-nets label[for="pay-11"], .pay-pick > #pay-12:checked ~ .pay-nets label[for="pay-12"], .pay-pick > #pay-13:checked ~ .pay-nets label[for="pay-13"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
:root:not([data-input="pointer"]) .pay-pick > #coin-0:focus-visible ~ .pay-coins label[for="coin-0"], :root:not([data-input="pointer"]) .pay-pick > #coin-1:focus-visible ~ .pay-coins label[for="coin-1"], :root:not([data-input="pointer"]) .pay-pick > #coin-2:focus-visible ~ .pay-coins label[for="coin-2"], :root:not([data-input="pointer"]) .pay-pick > #coin-3:focus-visible ~ .pay-coins label[for="coin-3"], :root:not([data-input="pointer"]) .pay-pick > #pay-0:focus-visible ~ .pay-nets label[for="pay-0"], :root:not([data-input="pointer"]) .pay-pick > #pay-1:focus-visible ~ .pay-nets label[for="pay-1"], :root:not([data-input="pointer"]) .pay-pick > #pay-2:focus-visible ~ .pay-nets label[for="pay-2"], :root:not([data-input="pointer"]) .pay-pick > #pay-3:focus-visible ~ .pay-nets label[for="pay-3"], :root:not([data-input="pointer"]) .pay-pick > #pay-4:focus-visible ~ .pay-nets label[for="pay-4"], :root:not([data-input="pointer"]) .pay-pick > #pay-5:focus-visible ~ .pay-nets label[for="pay-5"], :root:not([data-input="pointer"]) .pay-pick > #pay-6:focus-visible ~ .pay-nets label[for="pay-6"], :root:not([data-input="pointer"]) .pay-pick > #pay-7:focus-visible ~ .pay-nets label[for="pay-7"], :root:not([data-input="pointer"]) .pay-pick > #pay-8:focus-visible ~ .pay-nets label[for="pay-8"], :root:not([data-input="pointer"]) .pay-pick > #pay-9:focus-visible ~ .pay-nets label[for="pay-9"], :root:not([data-input="pointer"]) .pay-pick > #pay-10:focus-visible ~ .pay-nets label[for="pay-10"], :root:not([data-input="pointer"]) .pay-pick > #pay-11:focus-visible ~ .pay-nets label[for="pay-11"], :root:not([data-input="pointer"]) .pay-pick > #pay-12:focus-visible ~ .pay-nets label[for="pay-12"], :root:not([data-input="pointer"]) .pay-pick > #pay-13:focus-visible ~ .pay-nets label[for="pay-13"] { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Сводка «ключ — значение» */
dl.facts { display: grid; grid-template-columns: minmax(140px, max-content) 1fr; margin: 0 0 16px; }
dl.facts dt, dl.facts dd { margin: 0; padding: 12px 0; border-bottom: 1px solid var(--line); }
dl.facts dt { color: var(--muted); font-size: 15px; padding-right: 24px; }
dl.facts > :nth-last-child(-n+2) { border-bottom: 0; }
/* Те же факты ячейками по три в ряд: подпись над значением. Линии между
   ячейками — тенью каждой, а не фоном сетки: в неполном ряду фон торчал
   серым прямоугольником. */
dl.facts.cells { grid-template-columns: repeat(3, minmax(0, 1fr)); border-radius: var(--r-card); background: var(--surface); overflow: hidden; margin: 0 0 32px; }
dl.facts.cells > div { padding: 14px 24px; box-shadow: 0 0 0 0.5px var(--line-soft); min-width: 0; }
dl.facts.cells dt, dl.facts.cells dd { padding: 0; border: 0; }
dl.facts.cells dt { font: 500 13px/1.4 var(--sans); color: var(--muted); margin-bottom: 4px; }
dl.facts.cells dd { font-size: 15px; overflow-wrap: anywhere; }
@media (max-width: 860px) { dl.facts.cells { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Плотный список: строка на человека, на тысяче людей страница короче вдвое. */
.table.dense th, .table.dense td { padding-top: 9px; padding-bottom: 9px; }
section.panel.list > header { padding-bottom: 0; }
section.panel.list > header p { font: 13px/1.4 var(--mono); }
section.panel.list > .table + .body { padding-top: 16px; padding-bottom: 16px; }
section.panel.list .pager { margin: 0; }
/* Свёрнутая карточка: заголовок — кнопка, содержимое — по нажатию. */
details.panel.fold { border-radius: var(--r-card); margin: 0 0 16px; overflow: hidden; background: var(--surface); }
details.panel.fold > summary { display: flex; align-items: center; gap: 16px; padding: 24px; cursor: pointer; list-style: none; }
details.panel.fold > summary::-webkit-details-marker { display: none; }
details.panel.fold > summary h2 { margin: 0; font-size: 20px; letter-spacing: -0.015em; }
details.panel.fold > summary > span { margin-left: auto; color: var(--muted); font-size: 14px; text-align: right; }
details.panel.fold > summary::after { content: ""; flex: none; width: 8px; height: 8px; border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted); transform: rotate(45deg); margin: -4px 4px 0 0; transition: transform 0.15s; }
details.panel.fold[open] > summary::after { transform: rotate(225deg); margin-top: 4px; }
details.panel.fold > .body { padding: 0 24px 24px; color: var(--text-2); }
details.panel.fold > .body > :last-child { margin-bottom: 0; }
@media (max-width: 560px) {
  details.panel.fold > summary { flex-wrap: wrap; }
  details.panel.fold > summary > span { margin-left: 0; text-align: left; flex-basis: 100%; order: 3; }
}

/* Карточка с заголовком: всё содержимое внутри одних полей. Поле у всех
   блоков сайта одно — 24px, и на телефоне тоже: 28 у одних и 24 у соседних
   было видно глазом (владелец, 2026-10-10). Рамки нет, как у карточек
   top.co: карточку отделяет от фона её подложка #F7F5EF. */
section.panel { border-radius: var(--r-card); margin: 0 0 16px; overflow: hidden; background: var(--surface); }
section.panel > header { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 24px 24px 0; }
section.panel > header h2 { margin: 0; font-size: 20px; line-height: 1.25; letter-spacing: -0.015em; }
section.panel > header p { margin: 0; color: var(--muted); font-size: 14px; }
section.panel > .body { padding: 16px 24px 24px; color: var(--text-2); }
section.panel > .body > :last-child { margin-bottom: 0; }
section.panel > .body strong { color: var(--text); font-weight: 500; }
section.panel > .body p a:not(.button) { color: var(--accent-text); text-decoration: underline; text-underline-offset: 2px; }
section.panel > .body h3 { margin: 16px 0 8px; font-size: 17px; color: var(--text); }
section.panel > .table { border-radius: 0; margin: 20px 0 0; border-top: 1px solid var(--line); background: transparent; }
section.panel > .table + .body { border-top: 1px solid var(--line); padding-top: 24px; }
/* Поля CDN разных входов — через черту: над полем имена записей, и без
   черты «not in connection files» следующего входа читалось как подпись
   к кнопке предыдущего. */
#cdn > .body > form + form { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--line); }
/* Своё имя записи — поле прямо под её именем в таблице входов. Поле и
   кнопка мельче обычных: их в ячейке бывает по одному на каждый адрес CDN. */
td > .entry + .entry { margin-top: 14px; }
form.rename { display: flex; align-items: center; gap: 8px; max-width: 440px; margin: 8px 0 10px; }
form.rename input.own:not([type=hidden]) { flex: 1; min-width: 0; padding: 7px 12px; font-size: 14px; }
form.rename button { padding: 7px 16px; font-size: 14px; }
section.panel.danger { box-shadow: inset 0 0 0 1px var(--bad-line); }
section.panel.danger > header h2 { color: var(--bad); font-size: 17px; }
/* Удалить нельзя, пока не отмечено согласие, — кнопка это и показывает.
   `#delete` — удаление аккаунта в кабинете: карточка там обычная, как
   соседние справа, а кнопка ведёт себя так же. */
:is(section.panel.danger, #delete) form:has(input[type=checkbox]):not(:has(input[type=checkbox]:checked)) button.danger { opacity: 0.5; }
:is(section.panel.danger, #delete) form:has(input[type=checkbox]:checked) button.danger { background: var(--bad); color: #fff; }
section.panel.danger form.stack > button { justify-self: stretch; }
.split { display: grid; grid-template-columns: minmax(0, 2fr) minmax(300px, 1fr); gap: 24px; align-items: start; }
.split > aside { position: sticky; top: 96px; }
.split > *, .two > *, .cols > * { min-width: 0; }
/* «Тарифы» в кабинете — заголовок колонки, а не раздела главной. */
.split h2#plans { font-size: 28px; margin: 40px 0 16px; }
.row-line { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 24px; padding: 20px 0; border-bottom: 1px solid var(--line); }
.row-line:first-child { padding-top: 4px; }
.row-line:last-child { border-bottom: 0; padding-bottom: 0; }
/* Строки, за которыми ещё что-то идёт («Добавить устройство», заметка): черта
   последней строки иначе упиралась прямо в кнопку. */
.row-line + form, .row-line + p { margin-top: 16px; }
.row-line p { margin: 6px 0 0; color: var(--muted); font-size: 14px; }
.row-line strong { font-size: 17px; }
/* Название кнопки внутри пояснения выделено весом, а не кеглем: правило выше
   написано для заголовка строки и делало слово в тексте крупнее соседних. */
.row-line p strong { font-size: inherit; color: var(--text); }
aside .row-line { flex-direction: column; align-items: flex-start; }
/* Кнопки строки рядом: «Файл» и «Убрать» у устройства. */
.row-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* Шкала расхода */
svg.meter { display: block; width: 100%; max-width: 420px; height: 6px; margin: 10px 0 2px; border-radius: 3px; overflow: hidden; }
svg.meter .track { fill: var(--line); }
svg.meter .fill { fill: var(--accent); }
svg.meter .fill.full { fill: var(--bad); }

/* Главная, первый экран: заголовок по центру, одно слово от руки. */
section.intro { text-align: center; padding: clamp(48px, 7vw, 96px) 0 0; overflow-x: clip; }
section.intro h1 { font-size: clamp(40px, 6.2vw, 72px); line-height: 1.1; max-width: 1000px; margin: 0 auto 24px; }
section.intro p.lead { max-width: 660px; margin: 0 auto 32px; }
section.intro .actions { justify-content: center; margin: 0; }
p.lead { font-size: 18px; line-height: 28px; color: var(--text-2); max-width: 560px; margin: 0 0 32px; }
/* Рукописное слово: Caveat крупнее соседних, цвет акцента, росчерк под ним.
   Росчерк растянут по ширине слова, толщина его от этого не меняется
   (non-scaling-stroke). Слово не рвётся посередине, пока помещается. */
.hand { position: relative; display: inline-block; padding: 0 0.06em 0.14em; font-family: var(--hand); font-weight: 600; font-size: 1.22em; line-height: 0.9; letter-spacing: 0; color: var(--accent); }
.hand svg.swash { position: absolute; left: 0; bottom: -0.04em; width: 100%; height: 0.26em; overflow: visible; fill: none; stroke: currentColor; stroke-width: 3px; stroke-linecap: round; vector-effect: non-scaling-stroke; }
:is(:lang(ja), :lang(ko), :lang(zh)) .hand { font-size: 1em; font-weight: 700; }
/* Сцена под заголовком: карточка-пример ключа, за ней тонкая кривая, вокруг
   звёзды и сердце. Кривая во всю ширину окна, лишнее срезает `overflow-x:
   clip` у первого экрана: иначе страница прокручивалась бы вбок. */
.stage { padding: clamp(56px, 7vw, 96px) 24px clamp(72px, 9vw, 128px); }
.stage .art { position: relative; max-width: 600px; margin: 0 auto; }
svg.squiggle { position: absolute; z-index: 0; left: 50%; top: 52%; width: 100vw; max-width: 1600px; height: clamp(120px, 16vw, 220px); transform: translate(-50%, -50%); fill: none; stroke: var(--text); stroke-width: 1.6px; stroke-linecap: round; vector-effect: non-scaling-stroke; }
svg.spark { position: absolute; z-index: 2; display: block; }
svg.spark.star { width: 72px; height: 72px; left: -96px; top: 14%; fill: var(--accent); transform: rotate(-8deg); }
svg.spark.heart { width: 30px; height: 30px; left: -30px; top: -40px; fill: var(--text); transform: rotate(-14deg); }
svg.spark.outline { width: 48px; height: 48px; right: -72px; top: -10px; fill: none; stroke: var(--accent); stroke-width: 1.8; stroke-linejoin: round; transform: rotate(10deg); }
/* Пример ключа нарисован «от руки»: толстый чернильный контур и нижний край
   нажатой клавиши, синие детали. Тень здесь — часть рисунка, а не тень. */
aside.key-card {
  position: relative; z-index: 1; text-align: left;
  background: var(--bg); color: var(--text); border: 2.5px solid var(--text); border-radius: 28px;
  box-shadow: 0 10px 0 0 var(--text); padding: 24px; display: flex; flex-direction: column; gap: 24px;
  container-type: inline-size;
}
:root[data-theme="dark"] aside.key-card { background: var(--surface); }
.key-card .cap { display: flex; justify-content: space-between; align-items: center; gap: 12px; font: 500 14px/1.4 var(--sans); color: var(--text-2); }
.key-card .cap span { display: inline-flex; align-items: center; gap: 10px; }
/* Слева — синяя клавиша с тем же нажатым краем, справа — пилюля «хранится
   только хеш». */
.key-card .cap span:first-child::before { content: ""; flex: none; width: 18px; height: 18px; border-radius: 6px; background: var(--accent); border: 2px solid var(--text); box-shadow: 0 3px 0 0 var(--text); }
.key-card .cap span:last-child { padding: 2px 12px 3px; border-radius: 100px; background: var(--accent-soft); color: var(--accent-text); gap: 8px; }
.key-card .cap span:last-child::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
/* Ключ — 24 знака моноширинным, около 15 em в длину; размер от ширины
   карточки, а не окна, иначе в узкой карточке он обрезался бы справа. */
.key-card .key { font: 500 min(32px, 6.6cqi)/1.2 var(--mono); letter-spacing: 0.02em; white-space: nowrap; overflow: hidden; }
.key-card .rule { display: flex; align-items: center; gap: 12px; font: 500 13px/1 var(--mono); color: var(--accent-text); }
.key-card .rule::before, .key-card .rule::after { content: ""; flex: 1; border-top: 2px dashed var(--line-strong); }
.key-card .kept small { display: block; font: 500 14px/1.4 var(--sans); color: var(--muted); margin-bottom: 10px; }
.key-card .kept code { display: block; font-size: 14px; line-height: 1.6; color: var(--accent-text); background: var(--accent-soft); border-radius: 16px; padding: 12px 16px; word-break: break-all; }

/* Принципы — три значка в ряд: рисованный значок, заголовок, абзац. Без
   чисел, кнопок и карточек (владелец, 2026-10-13: сначала были строки со
   снимками окна, потом сетка карточек с числами). Узко — столбиком сами
   (`auto-fit`). */
section.principles { padding: clamp(24px, 4vw, 48px) 0 clamp(56px, 7vw, 96px); }
section.principles .wrap { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 40px clamp(32px, 4vw, 64px); }
article.principle { display: flex; flex-direction: column; gap: 12px; }
article.principle h3 { margin: 8px 0 0; font-size: 22px; line-height: 1.25; font-weight: 500; letter-spacing: -0.01em; }
article.principle p { margin: 0; max-width: 360px; color: var(--text-2); }
/* Значок — тем же рисунком, что звёздочки у карточки ключа: чернильный
   контур 2,5, синие места, дырка ключа и глаза — цветом фона и текста. */
svg.mark { display: block; width: 64px; height: 64px; overflow: visible; }
svg.mark .ink { fill: none; stroke: var(--text); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
svg.mark .ink.thin { stroke-width: 1.8; }
svg.mark .fill { fill: var(--accent); }
svg.mark .soft { fill: var(--accent-soft); }
svg.mark .hole { fill: var(--bg); stroke: var(--text); stroke-width: 2; }
svg.mark .eye { fill: var(--text); }
svg.mark .spark { fill: var(--accent); }

/* Разделы главной: заголовок 44 px, под ним абзац 18/28. */
section.block { padding: clamp(48px, 7vw, 96px) 0; }
section.block > h2 { margin: 0 0 12px; }
section.block > p.intro { font-size: 18px; line-height: 28px; color: var(--text-2); max-width: 560px; margin: 0 0 40px; }
.cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 48px; }
.cols h3 { font-size: 22px; letter-spacing: -0.015em; margin: 0 0 12px; }
.cols p { color: var(--text-2); margin: 0; }
.cols .n { display: block; font: 500 14px/1 var(--sans); color: var(--accent-text); margin-bottom: 20px; }
/* «Как это работает» — три большие карточки на подложке. */
section.band { padding: clamp(48px, 7vw, 96px) 0; }
section.band h2 { margin: 0 0 12px; }
section.band p.intro { font-size: 18px; line-height: 28px; color: var(--text-2); max-width: 600px; margin: 0 0 40px; }
section.band .cols { gap: 16px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }
section.band .cols > div { background: var(--surface); border-radius: var(--r-big); padding: 24px; display: flex; flex-direction: column; }
section.band .cols .n { align-self: flex-start; padding: 3px 12px 4px; border-radius: 100px; background: var(--bg); line-height: 24px; margin-bottom: 56px; }
section.band .cols h3 { margin: 0 0 10px; }

/* Тарифы — по ширине своей колонки, а не окна. На странице аккаунта колонка
   узкая, и одним рядом при окне в 900px ячейке оставалось 121px. Поэтому:
   широкая колонка — все в ряд, средняя — по два, узкая — столбцом. */
:has(> .plans) { container-type: inline-size; }
/* В кабинете — по два в ряд: четыре в ряд в узкой колонке кабинета читались
   как столбики цифр. На главной (`showcase`) колонка широкая — там все в ряд. */
.plans { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.plans.showcase { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); grid-template-columns: none; gap: 16px; }
.plans:has(> .plan:only-child) { max-width: 360px; }
/* Нечётный последний — на всю строку, а не один с пустым местом рядом. */
.plans:not(.showcase) > .plan:last-child:nth-child(odd) { grid-column: 1 / -1; }
@container (max-width: 700px) {
  .plans.showcase { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .plans.showcase > .plan:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@container (max-width: 420px) {
  .plans, .plans.showcase { grid-template-columns: minmax(0, 1fr); }
}
.plan { container-type: inline-size; border-radius: var(--r-card); padding: 24px; display: flex; flex-direction: column; gap: 20px; background: var(--surface); }
.plans.showcase .plan { gap: 24px; border-radius: var(--r-big); }
.plan h3 { font: 500 15px/1.4 var(--sans); color: var(--muted); margin: 0 0 12px; }
/* Цена по ширине своей ячейки: у четырёх тарифов в колонке аккаунта по 180px. */
.plan .price { display: block; font-size: clamp(22px, 17cqi, 30px); font-weight: 500; letter-spacing: -0.02em; line-height: 1.15; white-space: nowrap; }
.plans.showcase .price { font-size: clamp(26px, 19cqi, 40px); }
.plan .per { display: block; color: var(--muted); font-size: 14px; }
/* Скидка: старая цена зачёркнутой и процент под новой, срок строкой ниже. */
.plan .was { display: flex; align-items: center; gap: 8px; margin: 4px 0 2px; font-size: 14px; color: var(--muted); }
.plan .was s { text-decoration-thickness: 1px; }
.sale { display: inline-block; font: 600 12px/1.6 var(--sans); color: #fff; background: var(--accent-text); border-radius: 999px; padding: 0 8px; }
.plan .until { display: block; margin-top: 2px; font-size: 13px; color: var(--accent-text); }
/* Код заказа: случайный, моноширинным — это не счётчик, а метка. */
code.order { font: 500 14px/1.3 var(--mono); letter-spacing: 0.02em; color: var(--text); white-space: nowrap; }
.plan ul { list-style: none; padding: 0; margin: 0; flex: 1; display: flex; flex-direction: column; gap: 6px; font-size: 15px; color: var(--text-3); }
.plans.showcase .plan ul { gap: 8px; }
/* Свой тариф — синей обводкой. */
.plan.current { box-shadow: inset 0 0 0 2px var(--accent); }
/* В кабинете название — прямо в карточке, а не в блоке с ценой. */
.plan > h3 { margin-bottom: -8px; }
.plans + p { margin-top: 12px; }
.plan form, .plan > .button { margin-top: auto; }
.plan form button, .plan > .button { width: 100%; }
.plan > p { margin: 0; font-size: 14px; color: var(--muted); }
/* Старший тариф на главной — чернильной карточкой. */
.plans.showcase > .plan:last-child:not(:only-child) { background: var(--ink); color: var(--ink-text); }
:root[data-theme="dark"] .plans.showcase > .plan:last-child:not(:only-child) { box-shadow: inset 0 0 0 1px var(--line); }
.plans.showcase > .plan:last-child:not(:only-child) h3 { color: var(--ink-muted); }
.plans.showcase > .plan:last-child:not(:only-child) .per, .plans.showcase > .plan:last-child:not(:only-child) .was { color: var(--ink-muted); }
.plans.showcase > .plan:last-child:not(:only-child) .until { color: var(--ink-accent); }
.plans.showcase > .plan:last-child:not(:only-child) .sale { background: var(--ink-accent); color: var(--ink); }
.plans.showcase > .plan:last-child:not(:only-child) ul { color: var(--ink-3); }
.plans.showcase > .plan:last-child:not(:only-child) .button { background: var(--ink-text); color: var(--ink); }
@media (hover: hover) { .plans.showcase > .plan:last-child:not(:only-child) .button:hover { background: var(--ink-accent); color: var(--ink); } }

/* Вопросы: заголовок слева, раскрывающиеся ответы справа. */
section.faq { display: flex; flex-wrap: wrap; gap: 32px 64px; padding: clamp(32px, 5vw, 64px) 0 clamp(96px, 12vw, 160px); }
section.faq > h2 { flex: 1 1 260px; margin: 0; }
section.faq > .qa { flex: 2 1 480px; min-width: 0; border-top: 1px solid var(--line); }
.qa details { border-bottom: 1px solid var(--line); }
.qa summary { list-style: none; cursor: pointer; padding: 22px 0; display: flex; justify-content: space-between; align-items: center; gap: 16px; font-size: 18px; line-height: 1.4; font-weight: 500; }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: "+"; flex: none; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: var(--surface); font-size: 20px; font-weight: 400; line-height: 1; transition: transform .2s; }
.qa details[open] summary::after { transform: rotate(45deg); }
.qa .answer { padding: 0 0 24px; color: var(--text-2); max-width: 640px; }
.qa .answer p:last-child { margin: 0; }
.qa .answer a { text-decoration: underline; text-underline-offset: 2px; }

/* Тёмная полоса с призывом: верх выпуклый, как у top.co, низ тоже чуть
   выгнут к подвалу. Выпуклости — псевдоэлементы цвета полосы, во всю
   ширину окна и не шире: вбок страница не прокручивается. */
section.cta { position: relative; margin-top: clamp(40px, 6vw, 88px); background: var(--cta-bg); color: var(--cta-text); text-align: center; padding: clamp(40px, 5vw, 64px) 0 clamp(72px, 8vw, 104px); }
section.cta::before, section.cta::after { content: ""; position: absolute; left: 0; right: 0; background: inherit; pointer-events: none; }
section.cta::before { bottom: calc(100% - 1px); height: clamp(36px, 6vw, 96px); border-radius: 50% 50% 0 0 / 100% 100% 0 0; }
section.cta::after { top: calc(100% - 1px); height: clamp(20px, 3vw, 48px); border-radius: 0 0 50% 50% / 0 0 100% 100%; }
section.cta h2 { font-size: clamp(34px, 4.6vw, 60px); max-width: 860px; margin: 0 auto 20px; color: var(--cta-text); }
section.cta p { font-size: 18px; line-height: 28px; color: var(--cta-muted); max-width: 560px; margin: 0 auto 32px; }
section.cta .actions { justify-content: center; margin: 0; }
section.cta .hand { color: var(--cta-accent); }
section.cta .button { background: var(--cta-text); color: var(--cta-bg); }
section.cta .button.secondary { background: rgb(255 253 249 / 0.1); color: var(--cta-text); }
@media (hover: hover) {
  section.cta .button:hover { background: var(--cta-accent); color: var(--cta-bg); }
  section.cta .button.secondary:hover { background: rgb(255 253 249 / 0.18); color: var(--cta-text); }
}

/* Ключ, показанный один раз: та же карточка «от руки», что пример на главной. */
.keyshow {
  background: var(--bg); color: var(--text); border: 2.5px solid var(--text); border-radius: 28px;
  box-shadow: 0 10px 0 0 var(--text); padding: 24px; display: flex; flex-direction: column; gap: 24px; margin: 0 0 40px;
}
:root[data-theme="dark"] .keyshow { background: var(--surface); }
.keyshow small { font: 500 14px/1.4 var(--sans); color: var(--muted); }
/* Размер — от ширины карточки, как у примера на главной: от ширины окна ключ
   в узкой колонке не влезал и отращивал полосу прокрутки. */
.keyshow { container-type: inline-size; }
.keyshow code { font: 500 min(28px, 6.4cqi)/1.2 var(--mono); letter-spacing: 0.02em; white-space: nowrap; overflow: hidden; user-select: all; }
.keyshow .actions { margin: 0; gap: 10px; }
.keyshow a.button { background: var(--btn-2); color: var(--text); }
@media (hover: hover) { .keyshow a.button:hover { background: var(--btn-2-hover); color: var(--text); } }
/* Без скрипта кнопки копирования нет — тогда главной становится «дальше». */
.keyshow button.copy[hidden] + a.button { background: var(--btn); color: var(--on-btn); }

/* Вход, регистрация, короткие сообщения: узкая колонка без рамки. */
.box h1 { font-size: clamp(36px, 5vw, 56px); margin: 0 0 16px; }
.box > p { font-size: 18px; line-height: 28px; color: var(--text-2); margin-bottom: 16px; }
.box > p.muted { color: var(--text-2); }
.box > p strong { color: var(--text); }
.box > p + form, .box > p + .keyshow, .box > p + .notice, .box > p + .actions { margin-top: 24px; }
.box > p a { text-decoration: underline; text-underline-offset: 2px; }
.box form.stack { gap: 12px; }
.box form.stack > button { justify-self: stretch; margin-top: 12px; }
.box label.field { gap: 12px; }
.box label.field > span { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-weight: 500; }
.box label.field > span small { font-size: 14px; font-weight: 400; color: var(--muted); }
.box .notice { font-size: 15px; }
p.after { margin: 32px 0 0; padding-top: 24px; border-top: 1px solid var(--line); color: var(--text-2); }
p.after a { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
p.fine { margin: 24px 0 0; font-size: 14px; color: var(--muted); }
p.fine a { text-decoration: underline; text-underline-offset: 2px; }

/* Промокод — карточка в правой колонке кабинета: поле и кнопка в ряд, код
   моноширинным и заглавными (сверяется без регистра). «Убрать код» — своей
   строкой под ними: в узкой колонке рядом с кнопкой ей места нет. */
form.promo { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
/* Через #promo: общее правило полей `input:not(…):not(…):not(…)` сильнее
   `form.promo input` и перебивало моноширинный шрифт. */
#promo form.promo input { flex: 1 1 140px; min-width: 0; font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.04em; }
form.promo a { flex-basis: 100%; font-size: 14px; color: var(--accent-text); }
form.promo + .notice { margin: 16px 0 0; }

/* Ключи доступа. Кнопки скрыты, пока скрипт не убедится, что браузер их
   умеет (`[hidden]` выше). На входе — «или» между ключом аккаунта и кнопкой
   ключа доступа; строка состояния видна, только когда в ней есть слова. */
.box .passkey { display: grid; gap: 12px; margin-top: 24px; }
.box .passkey.alt { margin-top: 20px; }
p.or { display: flex; align-items: center; gap: 14px; margin: 0; color: var(--muted); font: 500 14px/1.4 var(--sans); }
p.or::before, p.or::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
.passkey-status { margin: 10px 0 0; font-size: 14px; font-weight: 500; color: var(--bad); }
.box .passkey-status { margin: 0; font-size: 15px; }
.passkey-status:empty { display: none; }
.box .notice[data-passkey-none] { margin-top: 24px; }
section.panel .row-line + .passkey, section.panel p + .passkey { margin-top: 20px; }
section.panel .passkey ~ p { margin-top: 14px; }
/* Подтверждение старой сессии — первой карточкой кабинета, жёлтым. */
section.panel.attention { background: var(--warn-bg); }
/* Переименовать ключ: ссылка под названием, форма раскрывается под ней. */
details.rename { margin-top: 8px; }
details.rename > summary { display: inline-block; list-style: none; cursor: pointer; font-size: 14px; color: var(--accent-text); }
details.rename > summary::-webkit-details-marker { display: none; }
@media (hover: hover) { details.rename > summary:hover { color: var(--text); } }
details.rename[open] > summary { color: var(--text); }
details.rename form.row { margin-top: 10px; flex-wrap: nowrap; }
details.rename input { min-width: 0; max-width: 320px; padding: 8px 12px; font-size: 15px; }
details.rename button { padding: 8px 16px; font-size: 14px; }

/* Документы: заголовок во всю ширину, оглавление сбоку и липкое. */
.doc-head { padding: clamp(48px, 7vw, 96px) 0 48px; border-bottom: 1px solid var(--line); }
.doc-head .eyebrow { margin-bottom: 20px; }
.doc-head h1 { font-size: clamp(40px, 6vw, 72px); line-height: 1.1; margin: 0 0 20px; }
.doc-head .updated { font: 14px/1.4 var(--sans); color: var(--muted); margin: 0 0 24px; }
.doc-head p.lead { max-width: 660px; margin: 0; }
.doc-body { display: flex; flex-wrap: wrap; gap: 40px 64px; align-items: flex-start; padding: 56px 0 120px; }
nav.toc { flex: 1 1 220px; }
nav.toc small { display: block; font: 500 14px/1.4 var(--sans); color: var(--muted); margin-bottom: 16px; }
nav.toc ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 15px; color: var(--text-2); }
article.doc { flex: 3 1 520px; min-width: 0; max-width: 700px; color: var(--text-3); display: flex; flex-direction: column; gap: 56px; line-height: 1.65; }
article.doc h2 { font-size: 28px; letter-spacing: -0.02em; color: var(--text); margin: 0 0 20px; }
article.doc h2 span { font: 500 15px/1 var(--sans); color: var(--accent-text); margin-right: 12px; vertical-align: 4px; }
article.doc p { margin: 0 0 14px; }
article.doc section > :last-child { margin-bottom: 0; }
article.doc ul { margin: 0 0 14px; padding-left: 20px; display: flex; flex-direction: column; gap: 10px; }
article.doc a { text-decoration: underline; text-underline-offset: 2px; }
article.doc strong { color: var(--text); }
@media (min-width: 860px) { nav.toc { position: sticky; top: 96px; } }

/* Сводки */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: 12px; margin-bottom: 8px; }
.tile { border-radius: var(--r-card); padding: 24px; background: var(--surface); display: grid; gap: 2px; }
.tile .value { font-size: 40px; font-weight: 500; letter-spacing: -0.03em; line-height: 1.15; }
.tile .label { font-weight: 500; }
.tile small { font-size: 14px; }
figure.chart { margin: 0; border-radius: var(--r-card); padding: 24px; background: var(--surface); }
figure.chart svg { width: 100%; height: 160px; display: block; }
figure.chart rect.bar { fill: var(--accent); }
@media (hover: hover) { figure.chart rect.bar:hover { fill: var(--text); } }
figure.chart line.base { stroke: var(--line-strong); stroke-width: 1; }
figure.chart figcaption { display: flex; justify-content: space-between; font: 12px/1.4 var(--mono); color: var(--muted); margin-top: 10px; }
/* Нагрузка нод (`web/load.rs`): ячейка списка, карточка на странице ноды и
   графики за сутки. Линии — с `vector-effect: non-scaling-stroke`: график
   растянут по ширине, и без этого толщина линии менялась бы с шириной окна,
   а пунктир порогов растягивался бы в штрихи. Провал — серая полоса. */
td.load { min-width: 200px; }
.reason { color: var(--text-2); font-size: 14px; }
section.panel > dl.facts.cells { border-top: 1px solid var(--line); border-radius: 0; margin: 20px 0 0; background: transparent; }
form.port input { max-width: 220px; }
.two.charts { gap: 16px; margin-bottom: 40px; }
figure.chart.load { min-width: 0; }
figure.chart.load > header { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; margin: 0 0 12px; }
figure.chart.load h3 { margin: 0; font-size: 16px; letter-spacing: -0.01em; }
figure.chart.load .legend { display: flex; flex-wrap: wrap; gap: 4px 14px; font: 12px/1.4 var(--mono); color: var(--muted); }
figure.chart.load .key { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
figure.chart.load .key i { display: inline-block; width: 14px; height: 0; border-top: 2px solid var(--accent); }
figure.chart.load .key i.s2 { border-top-color: var(--chart-2); }
figure.chart.load .key i.dash { border-top: 1.5px dashed var(--text-2); }
figure.chart.load .key i.busy { border-top-color: var(--warn); }
figure.chart.load .key i.over { border-top-color: var(--bad); }
figure.chart.load svg { height: 120px; }
figure.chart.load line.base { vector-effect: non-scaling-stroke; }
figure.chart.load .series { fill: none; stroke-width: 1.75; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
figure.chart.load .series.s1 { stroke: var(--accent); }
figure.chart.load .series.s2 { stroke: var(--chart-2); }
figure.chart.load .mark { stroke: var(--text-2); stroke-width: 1; stroke-dasharray: 4 4; vector-effect: non-scaling-stroke; }
figure.chart.load .mark.busy { stroke: var(--warn); }
figure.chart.load .mark.over { stroke: var(--bad); }
figure.chart.load rect.gap { fill: var(--wash); }
figure.chart.load.none p { margin: 0; }
.two { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)); gap: 24px; }
.two h2 { font-size: 20px; letter-spacing: -0.015em; margin: 48px 0 16px; }
.empty { border: 1.5px dashed var(--line-strong); border-radius: var(--r-card); padding: 64px 24px; margin: 0 0 16px; text-align: center; color: var(--muted); }

/* Свёрнутый список */
details.list { border-radius: var(--r-card); margin: 0 0 24px; overflow: hidden; background: var(--surface); }
details.list > summary { cursor: pointer; padding: 16px 24px; font-weight: 500; }
details.list[open] > summary { border-bottom: 1px solid var(--line); }
details.list > .table { border-radius: 0; margin: 0; background: transparent; }
details.list > p { padding: 16px 24px; margin: 0; }

/* Подвал: имя и строка о сервисе слева, колонки ссылок, внизу © и право.
   После тёмной полосы главной черты сверху нет: полоса и так отделяет. */
footer.site { border-top: 1px solid var(--line-soft); font-size: 15px; }
body:has(section.cta) footer.site { border-top: 0; padding-top: clamp(24px, 4vw, 48px); }
footer.site .cols4 { display: flex; flex-wrap: wrap; gap: 40px; padding: 72px 24px 48px; }
footer.site .cols4 > div { flex: 1 1 130px; display: flex; flex-direction: column; gap: 10px; }
footer.site .cols4 > div:first-child { flex: 2 1 300px; max-width: 380px; gap: 14px; }
footer.site .cols4 p { margin: 0; color: var(--text-2); }
footer.site .cols4 a { color: var(--text); }
footer.site h4 { margin: 0 0 4px; font: 500 14px/24px var(--sans); color: var(--muted); }
footer.site ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
footer.site .legal { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 16px; padding: 24px; font-size: 14px; color: var(--muted); }
footer.site .cols4 + .legal { border-top: 1px solid var(--line-soft); }
footer.site .legal nav { display: flex; flex-wrap: wrap; gap: 20px; }
/* Видно только чтению с экрана: подпись без лишней надписи на странице. */
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Над переводом условий и политики — что действует английский текст. */
.doc-head .translated { max-width: 660px; margin: 0 0 20px; }
.doc-head .translated a { color: var(--accent-text); }

/* Страница загрузки. Первый экран — в две колонки: слева текст, справа та
   же карточка «от руки», что у примера ключа на главной, вместо ключа в ней
   версия. */
section.hero { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)); gap: clamp(40px, 6vw, 80px); align-items: center; padding: clamp(48px, 7vw, 96px) 0 56px; }
section.hero h1 { font-size: clamp(40px, 5.6vw, 72px); line-height: 1.1; margin: 0 0 24px; }
section.hero .actions { margin: 0; }
.release .key { font-size: min(72px, 22cqi); line-height: 1; letter-spacing: -0.02em; }
.release .file { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 16px; font: 14px/1.4 var(--mono); margin-top: -12px; }
.release .file span:last-child { color: var(--muted); }
.release p.none { margin: 0; color: var(--text-2); font-size: 18px; }
.release .kept a { color: var(--accent-text); }
@media (hover: hover) { .release .kept a:hover { color: var(--text); } }
.release .kept code { user-select: all; }
section.hero p.aside-note { margin: 24px 0 0; color: var(--muted); font-size: 15px; }
section.hero p.aside-note a { color: var(--accent-text); }
@media (hover: hover) { section.hero p.aside-note a:hover { color: var(--text); } }
/* Системы — по одной в строке во всю ширину (с 1.3.1): слева значок, имя,
   требования и как ставить, справа файлы. До этого были карточки два на два,
   и выходили они высокими: при 1280 px карточки Windows и macOS по 441 px,
   Linux с одной фразой 347, вся сетка 804 px, выше окна. Теперь 631, а на
   телефоне в 390 px 1156 вместо 1602 (владелец, 2026-10-03: «блоки сделай
   компактнее и по одной горизонтально»). Готовые идут первыми, заглушки за
   ними и ниже ростом. Уже 768 px строка складывается в столбик в порядке
   разметки: имя, текст, оговорка, файлы. При 768 правой колонке остаётся
   350 px, кнопка файла ставит размер под имя (правило ниже), и ни имя
   файла, ни подпись не рвутся ни на одном из 17 языков. Рамка прозрачная,
   но есть: у заглушки она пунктиром, и строки не сдвигаются друг от друга. */
.systems { display: grid; gap: 12px; }
.system { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; background: var(--surface); border: 1.5px solid transparent; border-radius: var(--r-card); padding: 24px; min-width: 0; }
.system > * { min-width: 0; }
.system header { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0 0 8px; }
.system svg.ico { width: 28px; height: 28px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.system h3 { font-size: 20px; letter-spacing: -0.015em; margin: 0; }
.system p { color: var(--text-2); margin: 0; }
.system p + p { margin-top: 4px; }
/* Оговорка о первом запуске на Mac длиннее остального текста строки: мельче,
   чтобы требования и установка читались первыми. */
.system p.note { font-size: 14px; line-height: 1.5; }
.system .files { display: grid; gap: 8px; align-content: start; container-type: inline-size; }
.system a.file { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 11px 16px; border-radius: 16px; background: var(--btn-2); color: var(--text); min-width: 0; }
.system a.file > span.what { display: grid; gap: 1px; min-width: 0; margin-right: auto; line-height: 1.35; }
.system a.file strong { font-weight: 500; }
.system a.file small { font: 12px/1.4 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.system a.file > span.size { font: 12px/1.4 var(--mono); color: var(--muted); white-space: nowrap; }
.system a.file svg.get { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.system a.file.main { background: var(--btn); color: var(--on-btn); }
.system a.file.main small, .system a.file.main > span.size { color: inherit; opacity: 0.72; }
@media (hover: hover) {
  .system a.file:hover { background: var(--btn-2-hover); color: var(--text); }
  .system a.file.main:hover { background: var(--btn-hover); color: var(--on-btn); }
}
/* Узкой кнопке размер под имя файла: строке «подпись или имя, размер, значок»
   нужно 344 px у zip Windows и до 398 у подписи архива по-нидерландски
   («Archief zonder installatieprogramma»), а в кнопке уже этого рвалось имя
   или подпись. Запас на номер версии подлиннее. */
@container (max-width: 429px) {
  .system a.file { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1px 16px; }
  .system a.file > span.what, .system a.file > span.size { grid-column: 1; }
  .system a.file svg.get { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
}
/* Linux (шаг L7): справа по формату пакета — кнопка x86_64, мелкой строкой
   arm64 и команда установки. Команда в рамке и без заливки, с приглашением
   «$»: тёмной, как команды проверки ниже, она стояла вплотную к тёмной
   кнопке файла и читалась третьей кнопкой. «$» не выделяется и не
   копируется, сама команда выделяется целиком одним щелчком; перенос — под
   начало команды, а не под «$», и путь к файлу переносится целиком (при
   768 px имя `.rpm` рвалось на дефисе). Оговорка о значке у часов — мелкая,
   в левой колонке. */
.system .pkg { display: grid; gap: 6px; }
.system .pkg + .pkg { margin-top: 10px; }
.system p.arch { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; padding: 0 16px; font: 12px/1.4 var(--mono); color: var(--muted); }
.system p.arch a { color: var(--text-2); overflow-wrap: anywhere; min-width: 0; }
@media (hover: hover) { .system p.arch a:hover { color: var(--accent-text); } }
.system pre.run { display: flex; gap: 10px; margin: 0; padding: 8px 15px; border: 1px solid var(--line-strong); border-radius: 14px; font: 13px/1.5 var(--mono); color: var(--text); }
.system pre.run::before { content: "$"; color: var(--muted); user-select: none; }
.system pre.run code { min-width: 0; font: inherit; white-space: pre-wrap; overflow-wrap: anywhere; user-select: all; }
.system pre.run code span { display: inline-block; max-width: 100%; }
.system .about p.note { margin-top: 10px; }
/* Заглушка: та же строка, но пунктиром, без заливки и ниже. Видно, что
   система в списке есть, а скачивать пока нечего. Сжат только промежуток
   между строками, когда имя и фраза идут столбиком. Короткое `gap: 4px` у
   двух классов перебивало и широкий промежуток колонок у `.system` (там
   один класс, а @media весу не прибавляет), и с 768 px фраза вставала на
   15 px левее файлов строк выше. */
.system.soon { background: transparent; border-style: dashed; border-color: var(--line-strong); padding: 14px 24px; row-gap: 4px; }
.system.soon header { margin: 0; }
.system.soon svg.ico { width: 22px; height: 22px; }
.system.soon h3 { font-size: 17px; }
.system.soon svg.ico, .system.soon h3, .system.soon p { color: var(--muted); }
.system.soon p { font-size: 15px; }
@media (min-width: 768px) {
  /* Справа файлы, а у заглушки её фраза, вровень с файлами строк выше.
     Правая колонка шире левой: поровну при 900 px ей доставалось 382 px, и
     нидерландская подпись архива рвалась рядом с размером. Оговорка Mac
     идёт под всей строкой: по-английски при 1280 px так в две строки. */
  .system { grid-template-columns: minmax(0, 4fr) minmax(0, 5fr); gap: 14px 32px; }
  .system > .about { grid-column: 1; grid-row: 1; }
  .system > .files { grid-column: 2; grid-row: 1; }
  .system > p.note { grid-column: 1 / -1; grid-row: 2; padding-top: 12px; border-top: 1px solid var(--line); }
  .system.soon { align-items: center; }
}
/* За первым экраном загрузки сразу раздел: без своего отступа он прижат к
   кнопкам. */
section.hero + section.block { padding-top: 48px; }
section.band > .wrap > .actions { margin-top: 40px; }
section.verify > p.intro, section#systems > p.intro { margin-bottom: 32px; }
/* Подпись над командой: для какой она системы и где её вводить. */
section.verify > p.cmd-for { margin: 0 0 8px; font: 500 14px/1.4 var(--sans); color: var(--muted); }
section.verify > pre.cmd + p.cmd-for { margin-top: 24px; }
pre.cmd { margin: 0 0 16px; padding: 18px 24px; border-radius: 20px; background: var(--ink); color: var(--ink-text); overflow-x: auto; }
:root[data-theme="dark"] pre.cmd { box-shadow: inset 0 0 0 1px var(--line); }
/* Команда переносится, а не уезжает за край: на телефоне её читают, а при
   копировании она остаётся одной строкой. */
pre.cmd code { font-size: 14px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; user-select: all; }
section.verify td code { font-size: 13px; }
@media (hover: hover) { section.verify td a:hover code { color: var(--accent-text); } }
section.verify td.sum { min-width: 22ch; }
section.verify td.sum code { word-break: break-all; color: var(--accent-text); user-select: all; }
section.verify .notes { max-width: 720px; margin: 8px 0 0; }
section.verify .notes p { color: var(--text-2); margin: 0 0 12px; }
section.verify .actions { margin-top: 28px; }

/* Страница состояния (`/status`, web/status.rs). Колонка уже обычной,
   920 px: строки частей с полосой за 30 суток читаются взглядом слева
   направо, а шире полоса только размазывается. Цвета — токены сайта:
   зелёный — работает, янтарный — с трудом, красный — лежит, синий акцент —
   работы, серый — нет данных; тёмная тема от них же. Подсказки суток —
   без скрипта: лежат в разметке и видны по наведению (там, где есть мышь)
   и по фокусу (клавиатура, касание сутки с фокусом). Прижаты к краю
   полосы у крайних суток (классы x…), иначе вылезали бы за экран. 30
   ячеек и на телефоне: в 375 px каждая около 7 px. */
main.status .wrap { max-width: 920px; }
:root { --day-ok: var(--ok-dot); --day-warn: #e8a317; --day-bad: #d4473c; --day-none: var(--surface-2); }
:root[data-theme="dark"] { --day-warn: #f2b84b; --day-bad: #ff7b70; }
.st-head { padding: clamp(8px, 2vw, 24px) 0 28px; }
.st-head h1 { font-size: clamp(36px, 4.4vw, 52px); margin: 0 0 12px; }
.st-head p.lead { margin: 0; max-width: 640px; }
.banner { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; padding: 20px 24px; margin: 0 0 48px; border-radius: var(--r-card); background: var(--ok-bg); color: var(--ok); }
.banner.warn { background: var(--warn-bg); color: var(--warn); }
.banner.bad { background: var(--bad-bg); color: var(--bad); box-shadow: inset 0 0 0 1px var(--bad-line); }
.banner.maint { background: var(--accent-soft); color: var(--accent-text); }
.banner .mark { flex: none; width: 12px; height: 12px; margin: 0 4px; border-radius: 50%; background: currentColor; box-shadow: 0 0 0 6px color-mix(in srgb, currentColor 18%, transparent); }
.banner strong { font-size: 20px; line-height: 1.3; font-weight: 600; letter-spacing: -0.01em; }
.banner .checked { margin-left: auto; font-size: 14px; color: var(--text-2); }
.st-block { margin: 0 0 56px; }
.st-block > h2 { font-size: 26px; letter-spacing: -0.015em; margin: 0 0 16px; }
#components > p.intro { margin: 0 0 12px; color: var(--text-2); font-size: 15px; }
ul.legend { display: flex; flex-wrap: wrap; gap: 6px 20px; list-style: none; margin: 0 0 32px; padding: 0; font-size: 13px; color: var(--muted); }
ul.legend li { display: inline-flex; align-items: center; gap: 8px; }
ul.legend li::before { content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--day); }
:is(ul.legend, ol.days) > .ok { --day: var(--day-ok); }
:is(ul.legend, ol.days) > .warn { --day: var(--day-warn); }
:is(ul.legend, ol.days) > .bad { --day: var(--day-bad); }
:is(ul.legend, ol.days) > .maint { --day: var(--accent); }
:is(ul.legend, ol.days) > .none { --day: var(--day-none); }
ul.legend > .none::before { box-shadow: inset 0 0 0 1px var(--line); }
section.group { margin: 0 0 28px; }
section.group > h2 { font-size: 18px; line-height: 1.3; letter-spacing: -0.01em; margin: 0 0 10px; }
ul.comps { list-style: none; margin: 0; padding: 0; border-radius: var(--r-card); background: var(--surface); }
li.comp { padding: 20px 24px 16px; border-top: 1px solid var(--line-soft); }
li.comp:first-child { border-top: 0; }
.comp .line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin: 0 0 12px; }
.comp .name { font-weight: 500; overflow-wrap: anywhere; }
.comp .load { padding: 1px 10px 2px; border-radius: 100px; background: var(--surface-2); color: var(--text-2); font-size: 13px; line-height: 1.5; white-space: nowrap; }
.comp .load.high { background: var(--warn-bg); color: var(--warn); }
/* Состояние — справа; не влезло в строку — уходит на следующую, тоже вправо. */
.comp .state { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; font-size: 14px; font-weight: 500; white-space: nowrap; }
.comp .state::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.comp .state.ok { color: var(--ok); }
.comp .state.warn { color: var(--warn); }
.comp .state.bad { color: var(--bad); }
.comp .state.maint { color: var(--accent-text); }
.comp .state.none { color: var(--muted); }
ol.days { display: grid; grid-template-columns: repeat(30, minmax(0, 1fr)); gap: 3px; height: 34px; margin: 0; padding: 0; list-style: none; }
ol.days > li.d { position: relative; border-radius: 3px; background: var(--day); }
@media (hover: hover) { ol.days > li.d:hover { filter: brightness(0.86); } }
ol.days .tip {
  display: none; position: absolute; bottom: calc(100% + 8px); z-index: 5; width: max-content; max-width: 240px;
  padding: 8px 12px 9px; border-radius: 12px; background: var(--ink); color: var(--ink-text);
  font-size: 13px; line-height: 1.45; box-shadow: 0 10px 28px rgb(20 22 31 / 0.18); pointer-events: none;
}
:root[data-theme="dark"] ol.days .tip { box-shadow: inset 0 0 0 1px var(--line-strong), 0 10px 28px rgb(0 0 0 / 0.4); }
ol.days .tip > * { display: block; }
ol.days .tip em { margin-top: 4px; font-style: normal; color: var(--ink-2); overflow-wrap: anywhere; }
ol.days > li.xl .tip { left: 0; }
ol.days > li.xc .tip { left: 50%; transform: translateX(-50%); }
ol.days > li.xr .tip { right: 0; }
@media (hover: hover) { ol.days > li.d:hover .tip { display: block; } }
ol.days > li.d:focus .tip { display: block; }
.comp .axis { display: flex; justify-content: space-between; gap: 12px; margin-top: 8px; font-size: 12px; line-height: 1.4; color: var(--muted); }
.comp .axis .pct { color: var(--text-2); font-weight: 500; }
article.incident { margin: 0 0 12px; padding: 20px 24px; border-radius: var(--r-card); background: var(--surface); box-shadow: inset 4px 0 0 var(--tone, var(--line-strong)); }
article.incident.warn { --tone: var(--day-warn); }
article.incident.bad { --tone: var(--day-bad); }
article.incident.maint { --tone: var(--accent); }
:is(article.incident, article.past) > header { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0 0 8px; }
:is(article.incident, article.past) h3 { margin: 0; font-size: 18px; overflow-wrap: anywhere; }
.sev { padding: 1px 10px 2px; border-radius: 100px; background: var(--wash); color: var(--text-2); font: 500 12px/1.6 var(--sans); white-space: nowrap; }
.sev.warn { background: var(--warn-bg); color: var(--warn); }
.sev.bad { background: var(--bad-bg); color: var(--bad); }
.sev.maint { background: var(--accent-soft); color: var(--accent-text); }
article.incident p.update { margin: 0 0 6px; color: var(--text-2); overflow-wrap: anywhere; }
article.incident p.update strong { color: var(--text); font-weight: 600; }
:is(article.incident, article.past) :is(p.meta, p.window, p.affects) { margin: 0 0 4px; font-size: 14px; color: var(--muted); }
article.incident p.window { color: var(--text-2); font-weight: 500; }
article.past { padding: 24px 0; border-top: 1px solid var(--line); }
#history > h2 + article.past { padding-top: 8px; border-top: 0; }
ol.timeline { list-style: none; margin: 16px 0 0 5px; padding: 0 0 0 20px; border-left: 2px solid var(--line); }
ol.timeline li { position: relative; margin: 0 0 16px; }
ol.timeline li:last-child { margin-bottom: 0; }
ol.timeline li::before { content: ""; position: absolute; left: -27px; top: 5px; width: 8px; height: 8px; border-radius: 50%; background: var(--bg); border: 2px solid var(--line-strong); }
ol.timeline li:first-child::before { border-color: var(--accent); }
ol.timeline strong { display: block; font-size: 15px; font-weight: 600; }
ol.timeline p { margin: 2px 0; color: var(--text-2); overflow-wrap: anywhere; }
ol.timeline time { font-size: 13px; color: var(--muted); }
p.st-foot { margin: 0; font-size: 14px; color: var(--muted); text-align: center; }
/* Телефон: строка «проверено» — под словом плашки. */
@media (max-width: 560px) {
  .banner { padding: 18px 20px; margin-bottom: 40px; }
  .banner .checked { margin-left: 0; flex-basis: 100%; padding-left: 36px; }
  ol.days { height: 32px; gap: 2px; }
}

/* Строка шапки целиком — от 1240 px (было 1000). Inter в 16 px шире
   прежнего гротеска в 15, и ссылки справа стоят просторнее. Замер по всем
   17 языкам, страница загрузки: гостю больше всех нужно по-французски,
   1095 px (по-украински 1070), вошедшему администратору — тоже
   по-французски, 1194 px (по-испански 1153). 1240 оставляет запас на полосу
   прокрутки в 15 px. Уже — имя, глобус, тема, пилюля и меню. */
@media (max-width: 1239px) {
  header.top .bar > nav.primary, header.top .bar > nav.session { display: none; }
  details.menu { display: block; }
  a.button.cta { display: inline-flex; }
}
@media (min-width: 1240px) { header.top .menu-body { display: none !important; } }
@media (max-width: 860px) {
  .split { grid-template-columns: minmax(0, 1fr); }
  .split > aside { position: static; }
  svg.spark.star { width: 52px; height: 52px; left: -12px; top: -56px; }
  svg.spark.heart { left: 30%; top: -48px; }
  svg.spark.outline { width: 40px; height: 40px; right: -4px; top: -58px; }
}
@media (max-width: 560px) {
  .wrap, header.top .bar, nav.tabs, .menu-body, footer.site .cols4, footer.site .legal, .stage { padding-left: 16px; padding-right: 16px; }
  header.top .bar { padding-top: 12px; padding-bottom: 8px; }
  details.lang > ul { right: 16px; }
  /* В строке телефона — имя, пилюля и меню; глобус и тема — в меню. */
  header.top .bar > details.lang, header.top .bar > button.theme { display: none; }
  .menu-body .prefs { display: flex; }
  /* Имя, пилюля и меню при 375 px: по-нидерландски («Account aanmaken»)
     строке в прежних размерах нужно ровно 375, по-украински 362. Мельче
     имя и пилюля — 350 и меньше на всех языках, с запасом до 360 px. */
  header.top .bar { gap: 6px; }
  header.top .bar .brand { font-size: 18px; gap: 8px; }
  header.top .bar .brand img { width: 24px; height: 24px; }
  a.button.cta { padding: 6px 12px 7px; font-size: 14px; }
  /* Две подписи над ключом в одну строку на телефоне не влезают и рвутся по
     слову — ставим их одну под другой. */
  .key-card .cap { flex-direction: column; align-items: flex-start; gap: 8px; }
  .head { margin-bottom: 32px; }
  dl.facts { grid-template-columns: minmax(0, 1fr); }
  dl.facts dt { padding-bottom: 0; border-bottom: 0; }
  /* Заголовок карточки с подписью — в столбик: «Add a node» рядом с длинной
     подписью иначе ломался на три строки по слову. */
  section.panel > header { flex-direction: column; align-items: flex-start; gap: 6px; }
  th, td { padding-left: 12px; padding-right: 12px; }
  /* Перенос по слогам берёт язык из <html lang>. */
  h1, h2 { hyphens: auto; }
  .doc-head h1 { font-size: 36px; }
  /* Тариф заказа на телефоне не показываем: код заказа в 12 знаков и
     длинные заголовки (Abonnement, Bestellung) уводили «Отменить» за край
     карточки. Какой тариф, человек только что выбрал сам. */
  .table .wide { display: none; }
  /* Имя файла и сумма в 64 знака в две колонки на телефоне не встают: имя
     рвалось по дефисам в три строки. Каждый файл идёт блоком, сумма под именем. */
  section.verify thead { display: none; }
  section.verify table, section.verify tbody, section.verify tr, section.verify td:not(.wide) { display: block; }
  section.verify tr { padding: 16px 24px; border-bottom: 1px solid var(--line-soft); }
  section.verify tr:last-child { border-bottom: 0; }
  section.verify td, section.verify td + td { padding: 0; border: 0; }
  section.verify td.sum { margin-top: 6px; }
}
