/* ══════════════════════════════════════════════════════════════════════
   Skara Fit — лендінг.

   Та сама мова, що й у продукті: Manrope, кістяне тло, білі аркуші,
   вольтовий акцент #a8cf1b виключно ФОНОМ (як текст — його темний крок
   #5a7409), тепле лише для «прострочено». Іконки — Material Symbols
   Rounded, той самий набір, що в кабінеті.

   Дві смуги виламуються з цього навмисно — герой і фінальний заклик.
   Це фотографія з написом на ній, і кожен колір там записаний літералом:
   рівно той виняток, який у CRM має `.ff-auth` (сторінка входу). Причина
   та сама: фотографія не має теми, і сірий текст на ній — це не «та сама
   сторінка при іншому світлі», а інший дизайн.
   ══════════════════════════════════════════════════════════════════════ */

/* Шрифти вантажить <head>, а не `@import` звідси: імпорт усередині стилю
   браузер бачить лише після того, як стиль приїхав, і шрифт чекає цілий обіг
   мережі дарма. Тут лишаються тільки їхні імена. */

/* ══ ТРИ ГОЛОСИ ═══════════════════════════════════════════════════

   Manrope лишається текстовим шрифтом сторінки, і це не обережність:
   всередині неї стоять справжні знімки продукту, набрані Manrope. Інший
   текстовий шрифт поруч із ними читався б не як характер, а як помилка
   верстки — підпис під скриншотом іншим шрифтом, ніж сам скриншот.

   Oswald — голос ДВОХ ФОТОПОЛОС. Та сама пара винятків, про яку каже шапка
   файла: сторінка відкривається фотографією й закривається нею, і рівно там
   вона говорить вузьким капітелем — мова стартових номерів, табло й дошки
   результатів. Заголовки секцій між ними лишаються Manrope, інакше сторінка
   перестає бути сторінкою й стає афішею.

   Дрібний капітель — теж Oswald: перемикач мов, заголовки колонок підвалу,
   кнопки. Це один регістр одного шрифта, а не третій шрифт.

   Моноширинний — системний і рівно в одному місці: адресний рядок у рамці
   браузера. Це машинний рядок, а не «щось технічне»; тягнути заради нього
   окреме накреслення з мережі — платити шрифтом за 11 пікселів. */
:root {
  --font: "Manrope", system-ui, -apple-system, sans-serif;
  --display: "Oswald", "Manrope", system-ui, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Сторінка ТЕМНА цілком, і темна вона тією самою палітрою, якою вже
     говорили дві фотополоси, — не другою, вигаданою поруч. Тому `--ground`
     дорівнює `--photo-ground`: герой і фінальний заклик перестають бути
     острівцями, і сторінка читається як одна кімната, а не як світлий
     документ із двома темними вставками.

     Це навмисний відхід від продукту: кабінет — кістяне тло й білі аркуші.
     Лендінг не кабінет, він рекламна поверхня, і в CRM темна тема теж є, тож
     темне для бренду не чуже. Що лишається спільним — Manrope, вольт як фон,
     Material Symbols і саме зерно.

     Аркуші тут майже не відрізняються від тла за заливкою (1,1:1) і це
     нормально: на темному глибину дають волосяна лінія й світлий відблиск
     згори, а не світліша пляма. Тінь окремо, але вона тут не «підіймає», а
     садить предмет у тло. */
  --ink: #1f262a;               /* смуга з телефонами: на темній сторінці блок СВІТЛІШИЙ за тло */
  --on-ink: #ffffff;
  --on-ink-2: #c9d1d6;
  --on-ink-dim: #98a2a8;

  --ground: #0e1113;
  --paper: #161b1e;
  --sunken: #131719;
  --hairline: rgba(255, 255, 255, .085);
  /* Відблиск згори — те, чим на темному робиться край аркуша. */
  --edge-lit: inset 0 1px 0 rgba(255, 255, 255, .06);

  --lime: #a8cf1b;
  --lime-press: #b8dd2c;        /* на темному наведення СВІТЛІШАЄ, а не темнішає */
  --lime-ink: #bfe855;          /* вольт як ТЕКСТ: на темному це його світлий крок */
  --lime-soft: #212a0e;         /* вольтова підкладка, тепер темна */
  --lime-on-ink: #c6e45f;
  /* Чорнило НА вольті. Окремий токен, бо `--ink` на темній сторінці означає
     смугу з телефонами, а не «майже чорне»: вольт лишається фоном, і те, що
     на ньому пишуть, не має ходити за кольором чужої поверхні. */
  --on-volt: #14181b;

  /* Рампа перевернута: 1 — заголовок, 4 — те, чого ніхто не читає. */
  --t1: #f4f6f3; --t2: #d8ded9; --t3: #a6b0a7; --t4: #848e85;

  /* Тінь має зсув і мʼяке розмиття. Ореол без зсуву — це не глибина.
     На темному вона майже не читається, тому працює в парі з `--edge-lit`. */
  --card-shadow: 0 1px 2px rgba(0, 0, 0, .5);
  --lift: 0 18px 38px -22px rgba(0, 0, 0, .8), 0 3px 8px rgba(0, 0, 0, .4);
  --deep: 0 44px 70px -38px rgba(0, 0, 0, .9), 0 6px 14px rgba(0, 0, 0, .5);

  /* Фотографія — своя палітра літералами (див. шапку файла). */
  --photo-ground: #0e1113;
  --photo-fg: #ffffff;
  --photo-fg-2: #ccd3cd;        /* тінтований від тла, а не сірий */
  --photo-fg-3: #a8b0a6;      /* третинний тон на фото: 5,1:1 навіть над смугою світла */
  --photo-line: rgba(255, 255, 255, .16);
  --photo-volt: #bfe855;        /* вольт світлішає, бо стоїть на темному */

  /* Зерно. Темна полоса — це великий майже-чорний градієнт поверх стиснутого
     кадру, а це рівно те місце, де браузер малює смуги на плавному переході
     і де JPEG/WebP лишає квадрати навколо контурів. Зерно розбиває і те, й
     інше: воно дає оку випадковість, на тлі якої артефакт стиснення перестає
     читатись як артефакт. Промт для фотографії просить плівкове зерно з тієї
     самої причини — тут воно просто не залежить від того, чи послухався
     генератор. Один інлайновий SVG, жодного файла. */
  --grain: 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='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");

  --gutter: clamp(20px, 5vw, 56px);
  --shell: 1200px;
}

* { box-sizing: border-box; }

/* `hidden` мусить перемагати будь-який `display`, який ми самі поставили.
   Правило браузера `[hidden] { display: none }` слабше за найпростіший клас,
   тож рядок довідки з `display: grid` лишався на екрані попри `el.hidden` —
   пошук «фільтрував», нічого не приховуючи. */
[hidden] { display: none !important; }

/* Плавна прокрутка — це теж рух, і для вестибулярного апарату вона з того
   самого списку, що й паралакс героя. Під прапорцем її просто немає: якір
   спрацьовує миттєво, як і задумано браузером. */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
section[id] { scroll-margin-top: 88px; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--t1);
  font: 400 16px/1.55 var(--font);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }

/* Зерно тепер лежить на ВСІЙ сторінці, а не тільки на фотополосах: воно й було
   тим, що робило верх верхом. Один шар поверх усього, `fixed` — щоб не їхало
   разом із прокруткою й не перетворилось на текстуру, приклеєну до секцій.
   `soft-light` тримає його як світло, а не як сірий пил, і не чіпає кольори.
   `pointer-events: none` обовʼязкові: інакше шар з'їдає всі кліки. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 90; pointer-events: none;
  background-image: var(--grain); background-size: 160px 160px;
  opacity: .3; mix-blend-mode: soft-light;
}
@media (prefers-reduced-motion: reduce) { body::after { opacity: .22; } }
a { color: inherit; }

h1, h2, h3 { font-weight: 800; letter-spacing: -.035em; line-height: 1.05; margin: 0; text-wrap: balance; }
/* `pretty` бореться з висячим словом в останньому рядку абзацу. Для заголовків
   є `balance` вище — він вирівнює рядки між собою, і це інша задача. */
p { margin: 0; text-wrap: pretty; }


/* ── поверхні, які малює браузер, а не ми ─────────────────────────── */
::selection { background: #3b4a12; color: #eaf7bd; }
:root { accent-color: var(--lime); caret-color: var(--lime-ink); color-scheme: dark; }
:focus-visible { outline: 2px solid var(--lime-ink); outline-offset: 3px; border-radius: 6px; }
* { scrollbar-width: thin; scrollbar-color: #39423b transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: #39423b; border: 3px solid transparent; background-clip: content-box; border-radius: 99px; }
*::-webkit-scrollbar-track { background: transparent; }

/* Іконки — шрифт-лігатура, як у кабінеті. Клас обрізає свій квадрат, щоб
   гліф, який переріс оптичний розмір, не штовхав рядок.

   `opsz` МУСИТЬ іти за кеглем: без нього змінний шрифт малює 22px гліф так,
   ніби це зменшена 48-піксельна іконка — тонко й дрібно. `wght` 500, бо поруч
   стоїть 800-й текст, і 400-ва лінія біля нього губиться. */
.ms {
  font-family: 'Material Symbols Rounded';
  font-style: normal; line-height: 1; letter-spacing: normal;
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; overflow: hidden; user-select: none;
  white-space: nowrap; direction: ltr; -webkit-font-feature-settings: 'liga';
  font-size: 22px; width: 22px; height: 22px;
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}

.shell { width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }

/* ── кнопки ───────────────────────────────────────────────────────── */
/* Кнопка — це дія, і на цій сторінці вона говорить капітелем. Розрядка тут
   не смак: вузькі великі літери без неї злипаються, і чим коротше слово, тим
   помітніше. Мінус — кнопка стає ширшою, тож поля трохи менші, ніж були. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  border: none; border-radius: 14px; cursor: pointer;
  padding: 16px 25px;
  font: 600 15px/1 var(--display); letter-spacing: .05em; text-transform: uppercase;
  text-decoration: none; white-space: nowrap;
  transition: background .16s ease, transform .16s cubic-bezier(.2, .9, .3, 1), box-shadow .16s ease;
}
/* Стрілка підказує, що кнопка веде далі по сторінці, і зрушується назустріч
   курсору. Гліф оптично важчий за капітель поруч — тому на крок легший. */
.btn .ms {
  font-size: 19px; width: 19px; height: 19px; margin-right: -3px;
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 20;
  transition: transform .2s cubic-bezier(.2, .9, .3, 1);
}
.btn:hover .ms { transform: translateX(4px); }
/* Тінь під вольтовою кнопкою тонована її ж зеленню: сіра тінь під зеленим
   робить кнопку брудною, а не піднятою. Зсув і розмиття — як і скрізь. */
/* Тінь нейтральна, не зелена. На світлій сторінці зелений відкид під зеленою
   кнопкою ще читався як тінь; на темній це вже кольоровий ореол — рівно той
   несмак, за яким упізнають згенерований інтерфейс. Колір ink тут літералом:
   `--ink` тепер означає смугу з телефонами, а не «майже чорне». */
.btn--volt { background: var(--lime); color: #14181b; box-shadow: 0 1px 2px rgba(0, 0, 0, .45); }
.btn--volt:hover { background: var(--lime-press); transform: translateY(-1px); box-shadow: 0 12px 22px -12px rgba(0, 0, 0, .75), 0 2px 5px rgba(0, 0, 0, .4); }
.btn--ink { background: rgba(255, 255, 255, .07); color: var(--t1); box-shadow: var(--edge-lit); }
.btn--ink:hover { background: rgba(255, 255, 255, .12); transform: translateY(-1px); }
.btn--wire { background: transparent; color: var(--photo-fg); box-shadow: inset 0 0 0 1.5px var(--photo-line); }
.btn--wire:hover { box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .34); background: rgba(255, 255, 255, .07); transform: translateY(-1px); }
/* Натискання мусить перебивати наведення — тому стоїть після нього. */
.btn:active { transform: translateY(1px); box-shadow: 0 1px 2px rgba(0, 0, 0, .45); }
.btn--sm { padding: 11px 15px; font-size: 13px; border-radius: 12px; }

/* ── перше посилання сторінки ─────────────────────────────────────
   Видно його лише з клавіатури, і це не декоративний «прихований елемент»:
   шапка — це знак, два меню, чотири мови й кнопка, тобто півтора десятка
   зупинок, однакових на кожній із шістнадцяти сторінок. Без цього рядка їх
   доводиться проходити наново щоразу.

   Ховається ЗСУВОМ, а не `display: none` і не нульовим розміром: те й інше
   виймає посилання з порядку табуляції — тобто вимикає рівно те, заради чого
   воно тут. Показується і на `:focus`, і на `:focus-visible`: єдиний спосіб
   сюди потрапити — клавіатура, і промахнутись тут дорожче, ніж показати
   зайвий раз.

   Обведення лишається глобальним вольтовим, і саме через відступ у три
   пікселі: воно лягає не на саму плитку, а на темне тло поруч із нею. Темне
   обведення «під колір чорнила» довелося спробувати, щоб побачити, що воно
   зникає — темне по темному. */
.skip {
  position: fixed; top: 10px; left: 10px; z-index: 100;
  transform: translateY(-180%);
  padding: 13px 19px; border-radius: 12px;
  background: var(--lime); color: var(--on-volt);
  font: 600 13px/1 var(--display); letter-spacing: .05em; text-transform: uppercase;
  text-decoration: none; box-shadow: var(--lift);
  transition: transform .18s cubic-bezier(.16, 1, .3, 1);
}
.skip:focus, .skip:focus-visible { transform: none; }

/* ── шапка ────────────────────────────────────────────────────────── */
.nav {
  position: sticky; top: 0; z-index: 60;
  background: rgba(14, 17, 19, .5); backdrop-filter: blur(16px) saturate(120%);
  border-bottom: 1px solid transparent;
  transition: background .25s ease, border-color .25s ease;
}
/* Сторінка темна вся, тож шапка нікуди не «переїжджає» — вона лише
   ущільнюється, коли фотографія лишилась позаду: над кадром вона мусить
   пропускати його крізь себе, над рештою сторінки — тримати власний край. */
.nav[data-past-photo="1"] {
  background: rgba(14, 17, 19, .88);
  border-bottom-color: var(--hairline);
}
.nav__in { display: flex; align-items: center; gap: 10px; height: 68px; }

.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; font-weight: 800; font-size: 17px; letter-spacing: -.025em; color: var(--photo-fg); transition: color .25s ease; }
.brand img { width: 30px; height: 30px; border-radius: 9px; }

.nav__links { display: flex; gap: 2px; margin-left: auto; }
.nav__links a {
  padding: 9px 12px; border-radius: 10px; text-decoration: none;
  font: 700 14px/1 var(--font); color: var(--photo-fg-2);
  transition: background .15s ease, color .15s ease;
}
.nav__links a:hover { background: rgba(255, 255, 255, .1); color: var(--photo-fg); }

/* ── перемикач мов ────────────────────────────────────────────────── */
.langs { display: flex; gap: 1px; padding: 2px; border-radius: 11px; background: rgba(255, 255, 255, .11); }
.langs button {
  border: none; cursor: pointer; background: transparent;
  padding: 7px 9px; border-radius: 9px;
  font: 600 12.5px/1 var(--display); letter-spacing: .07em;
  color: var(--photo-fg-2); transition: background .15s ease, color .15s ease;
}
.langs button:hover { color: var(--photo-fg); }
.langs button[aria-pressed="true"] { background: var(--photo-volt); color: #16210a; }

/* Розділи ховаються лише тоді, коли їм справді бракує місця: на 900–1040
   вони містилися й ховалися дарма. Далі, на 560, здається слово в знаку —
   логотип упізнається й сам.

   Кнопка на цій ширині теж іде, і правило, яке її прибирає, стоїть нижче,
   біля бургера (там же, де решта телефонної шапки). Тут вона лише
   підтискається — на 561–900, де місце ще є. На 390 у шапці залишається знак,
   чотири мови й бургер: усе разом це вже близько двохсот пʼятдесяти пікселів
   із трьохсот девʼяноста, і «СПРОБУВАТИ» просто нема куди поставити. Дія при
   цьому нікуди не дівається — вона на першому ж екрані під заголовком і в
   шухляді, тобто вдвічі ближче, ніж була б у шапці. */
@media (max-width: 900px) { .nav__links { display: none; } .langs { margin-left: auto; } }
@media (max-width: 560px) {
  .nav .brand span { display: none; }
  .nav__in { gap: 8px; }
  .langs button { padding: 7px 7px; }
  .nav__cta { padding: 10px 14px; }
}

/* ══ ГЕРОЙ — фотографія з написом на ній ══════════════════════════ */
.hero {
  position: relative; isolation: isolate;
  /* Паралакс масштабує шар фотографії в 1.02, і на 1440 він вилазить по 14px з
     кожного боку. Трансформ справді не чіпає розкладку, але в область прокрутки
     входить, і сторінка починала їздити вбік. `clip`, а не `hidden`: він не
     робить із секції контейнер прокрутки й не ламає `position: sticky` всередині. */
  overflow: clip;
  background: var(--photo-ground); color: var(--photo-fg);
  /* Повітря під написом раніше давала сцена зі знімком кабінету. Знімка
     більше немає, тож смуга тримає його сама — і тим самим числом, яким
     копія віднімає його від висоти вікна. Одне джерело, два вжитки. */
  --hero-foot: clamp(56px, 7vw, 96px);
  /* Верхній відступ рахується від ВИСОТИ вікна, а не від ширини. Поки під
     заголовком стояв знімок кабінету, це було байдуже: за згин ішов він, і
     нікому не шкода. Тепер за згин іде кнопка — а відступ у 12vw на широкому
     ноутбуці давав 148px незалежно від того, 800 там пікселів заввишки чи
     1300, тобто зʼїдав чверть короткого екрана. */
  --hero-top: clamp(56px, 10vh, 148px);
  margin-top: -68px; padding: calc(68px + var(--hero-top)) 0 var(--hero-foot);
}
/* Смуга героя вища за кадр: копія тримає екран заввишки, а кадр — стільки,
   скільки просить його власна пропорція. Тому шар фотографії не розтягується
   на всю висоту смуги, а тримає ВЛАСНЕ співвідношення: тоді `cover` не ріже
   нічого й на жодній ширині. Співвідношення підставляє
   той самий скрипт, що вантажить фото, — інша фотографія просто дасть інше число.
   Раніше тут стояв clamp по висоті, і він мав рацію рівно на 1440: ширше впирався
   у максимум і зрізав кадр згори, вужче — у мінімум і зрізав з боків. */
.hero__photo {
  position: absolute; inset: 0 0 auto; width: 100%;
  aspect-ratio: var(--hero-photo-ratio, 16 / 9);
  z-index: 0; pointer-events: none;
  /* Фото не обовʼязкове: без нього лишається градієнт, і сторінка ціла. */
  background-image: var(--hero-photo, none);
  background-size: cover; background-position: 50% 50%; background-repeat: no-repeat;
  /* Гасне на власному нижньому краї, а не там, де це вгадав градієнт скрима —
     інакше на кожній іншій висоті вилазив би шов. */
  /* Рампа довга й з кривою, а не з двома стопами. Око чутливе саме до
     останнього шматка фактури, що зникає: лінійне згасання з різкою зміною
     нахилу читається як обрив, навіть коли жодного стрибка кольору немає.
     Сім стопів наближають ease-out — кадр тане повільно й доходить до нуля
     аж на власному нижньому краї, а не за сотню пікселів до нього. */
  --hero-fade: linear-gradient(180deg,
      #000 30%,
      rgba(0, 0, 0, .94) 44%,
      rgba(0, 0, 0, .82) 56%,
      rgba(0, 0, 0, .62) 67%,
      rgba(0, 0, 0, .4) 77%,
      rgba(0, 0, 0, .22) 86%,
      rgba(0, 0, 0, .08) 94%,
      transparent 100%);
  -webkit-mask-image: var(--hero-fade);
          mask-image: var(--hero-fade);
}
/* На телефоні кадр 16:9 — це смужка у двісті пікселів, під якою заголовок стоїть
   на порожньому чорному. Тут навпаки: беремо висоту й свідомо ріжемо з боків,
   тримаючи в кадрі людину. */
.hero__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    /* Окрема підкладка рівно під написом: рівний скрим довелося б робити таким
       щільним, що фотографії не лишилось би. Вага стоїть там, де текст, а права
       частина кадру живе далі.

       Числа тут ходять за фотографією, а не навпаки. Під попереднім кадром вони
       були на два кроки щільніші — там ліва третина була просто темною стіною,
       і давити її нічого не коштувало. У цього кадру в лівій третині вікно й
       смуга світла по підлозі, тобто рівно те, заради чого він і знятий; при
       старих числах від нього лишався темний прямокутник із людиною в кутку.
       Запас по контрасту (найвужче місце 5,6 при нормі 4,5) витрачено сюди.
       Замінюючи фотографію, переміряйте — спосіб описаний у README. */
    radial-gradient(112% 76% at -6% 40%, rgba(14, 17, 19, .87) 0%, rgba(14, 17, 19, .68) 36%, rgba(14, 17, 19, 0) 74%),
    /* Кадр і так знятий у темряві — цей шар лише прибирає різкість переходу. */
    linear-gradient(96deg, rgba(14, 17, 19, .6) 0%, rgba(14, 17, 19, .32) 32%, rgba(14, 17, 19, .06) 70%, rgba(14, 17, 19, 0) 90%),
    radial-gradient(70% 52% at 8% 0%, rgba(168, 207, 27, .15), rgba(168, 207, 27, 0) 64%),
    /* Розсіяне світло кімнати триває нижче за сам кадр. Без цього під
       фотографією лягала смуга рівного чорного заввишки в пів екрана, і
       перехід читався як обрив, хоча кольорового стрибка там немає: тло
       героя й тло сторінки — та сама фарба. Дуже слабко й дуже широко —
       це не пляма, це відсутність мертвої зони. */
    radial-gradient(78% 34% at 62% 30%, rgba(196, 206, 190, .07) 0%, rgba(196, 206, 190, .028) 46%, rgba(196, 206, 190, 0) 78%),
    linear-gradient(180deg, rgba(14, 17, 19, 0) 70%, var(--photo-ground) 96%);
}

@media (max-width: 760px) {
  .hero__photo { aspect-ratio: auto; height: 62vh; background-position: 70% 38%; }
  /* На телефоні текст лягає просто на модель, а не поруч із нею: підкладка мусить
     бути щільнішою. Без запасу інша фотографія — світліша за цю — провалить AA. */
  .hero__scrim {
    background:
      linear-gradient(180deg, rgba(14, 17, 19, .58) 0%, rgba(14, 17, 19, .74) 44%, var(--photo-ground) 86%),
      radial-gradient(80% 40% at 6% 4%, rgba(168, 207, 27, .13), rgba(168, 207, 27, 0) 66%);
  }
}

/* ── зерно на обох фотополосах ────────────────────────────────────
   Стоїть на СКРИМІ, а не на фотографії: кадр під ним їде паралаксом, а зерно
   мусить лишатись на місці — плівкове зерно належить плівці, а не сцені, і
   зерно, що повзе разом із картинкою, читається як брудне скло.

   `soft-light` замість прозорості внапряму: п'ятдесятивідсотковий сірий у
   цьому режимі не міняє нічого, а відхилення шуму штовхають пікселі в обидва
   боки пропорційно до того, що вже під ними. Тобто глибокі тіні лишаються
   глибокими — а це половина того, за що ця смуга взагалі темна, — тоді як
   плавний перехід у градієнті, де браузер малює смуги, дістає рівно ту
   випадковість, яка ці смуги розбиває.

   Зерно тепер одне на всю сторінку (`body::after`) і покриває ці смуги теж.
   Свій шар у них лишався ще від світлої сторінки, і всередині героя зерно
   виходило подвійним: `soft-light` із шумом на майже-чорному в середньому
   ПІДІЙМАЄ тон, тож смуга стояла на три рівні світліша за сторінку, а на її
   нижньому краї це читалося як рівний горизонтальний стик. */
/* Кадр підтягується під палітру сторінки: трохи більше контрасту (щоб темні
   місця не пливли після стиснення) і трохи менше насиченості — інакше будь-яка
   зелень у кадрі починає сперечатися з вольтом, який тут єдиний чистий колір. */
.hero__photo,
.final__photo { filter: contrast(1.06) saturate(.9); }

/* Петля лежить УСЕРЕДИНІ шару фотографії: маска нижнього краю, колірний
   фільтр і паралакс оголошені на `.hero__photo`, і дитина дістає всі три
   задарма. Під нею лишається сам кадр — його видно, поки відео вантажиться,
   і видно назавжди тим, хто відео не отримає. */
.ff-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 50%;
  opacity: 0; transition: opacity .7s ease;
}
.ff-video.is-on { opacity: 1; }

/* Скрим вивірений під ФОТОГРАФІЮ, а петля місцями світліша за неї: на кадрах
   близько 40-ї та 48-ї секунди заголовок падав до 1,8:1 при нормі 3. Одного
   заміру це не видно — рухомий фон треба міряти по всій петлі, і саме тому
   підкладка тут окрема, а не вшита в базовий скрим. Стоїть лише тоді, коли
   відео справді змонтоване: під самою фотографією вона зайва й забрала б
   у неї вікно та смугу світла. */
.hero.is-video .hero__scrim {
  background:
    radial-gradient(124% 88% at -6% 40%, rgba(14, 17, 19, .95) 0%, rgba(14, 17, 19, .85) 40%, rgba(14, 17, 19, .16) 82%),
    linear-gradient(96deg, rgba(14, 17, 19, .74) 0%, rgba(14, 17, 19, .52) 32%, rgba(14, 17, 19, .16) 70%, rgba(14, 17, 19, .04) 92%),
    radial-gradient(70% 52% at 8% 0%, rgba(168, 207, 27, .13), rgba(168, 207, 27, 0) 64%),
    /* Розсіяне світло кімнати триває нижче за сам кадр. Без цього під
       фотографією лягала смуга рівного чорного заввишки в пів екрана, і
       перехід читався як обрив, хоча кольорового стрибка там немає: тло
       героя й тло сторінки — та сама фарба. Дуже слабко й дуже широко —
       це не пляма, це відсутність мертвої зони. */
    radial-gradient(78% 34% at 62% 30%, rgba(196, 206, 190, .07) 0%, rgba(196, 206, 190, .028) 46%, rgba(196, 206, 190, 0) 78%),
    linear-gradient(180deg, rgba(14, 17, 19, 0) 70%, var(--photo-ground) 96%);
}

/* Вміст — над фотографією і скримом; жодних відʼємних z-index. */
/* Копія тримає рівно екран заввишки, і наступний блок починається за згином.
   Без цього висота верху задавалася б вмістом, а не вікном, і перший екран
   гуляв би на кожній висоті.

   Відніманням записано те саме, що складається вище по файлу: шапка, власний
   верхній відступ смуги і її дно. `svh`, а не `vh`: на телефоні панелі
   браузера зʼїдають висоту, і `vh` заганяв би нижній рядок під них. */
.hero > .shell {
  position: relative; z-index: 2;
  min-block-size: calc(100svh - 68px - var(--hero-top) - var(--hero-foot));
}
.hero__copy { max-width: 720px; }
/* Вузький капітель Oswald. Кегль виріс із 76 до 104 не з жадібності: та сама
   фраза в конденсованих великих літерах займає приблизно на чверть менше по
   горизонталі, тож при старому кеглі заголовок просто став би дрібнішим за
   свій рядок. Колонка тому теж ширша — 720 замість 640, щоб фраза лягала у
   два рядки, а не в три.

   Розрядка додатна, і це протилежно до решти заголовків сторінки. Мінусовий
   трекінг збирає докупи РЯДКОВІ літери з їхніми виносними; великі літери
   однакової висоти від нього злипаються — особливо кирилиця, де поруч
   стоять кілька прямокутних знаків підряд (ВЕДІТЬ, ШІСТЬ).

   Міжрядковий трохи більший за одиницю, і це не смак, а чеська зі словацькою:
   над великими літерами там стоять гачек, чарка й кружок, і при щільнішому
   рядку кружок над Ů в'їжджає в кому рядка вище (VEĎTE KLIENTY, / NE ŠEST
   PANELŮ — рівно цей випадок). Українська й англійська стерпіли б .93, але
   заголовок один на чотири мови, а не чотири різні. */
.hero h1 {
  font-family: var(--display); font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(44px, 8.4vw, 104px);
  line-height: 1.06; letter-spacing: .006em;
}
/* Обіцянка підкреслена вольтом, і підкреслення зʼявляється після того, як
   заголовок сів (див. блок РУХ).

   Це `text-decoration`, і жоден інший спосіб тут не працює. Фраза з двох слів
   переноситься на наступний рядок, і на розірваному рядковому боксі
   псевдоелемент малює ОДНУ коробку навколо обох шматків — навскіс через
   порожнечу між ними. Фон із `box-decoration-break: clone` малює кожен шматок
   окремо, але тягне його на всю ширину фрагмента разом із пробілом перед
   переносом, тож лінія вилітає за слово аж до краю колонки. І перше, і друге
   довелося побачити. Підкреслення ж браузер малює під самими літерами, пробіл
   на переносі пропускає, і — головне — тримається ВСЕРЕДИНІ рядкового боксу:
   лінія фоном стояла на 7 пікселів нижче й перекреслювала перший рядок
   підзаголовка, бо при заголовку в сто пікселів це нижче за його рядок. */
.hero h1 em {
  font-style: normal; color: var(--photo-volt);
  text-decoration: underline;
  text-decoration-thickness: .055em;
  text-underline-offset: .1em;
  text-decoration-skip-ink: none;
}
.hero__sub { margin-top: clamp(22px, 2.4vw, 30px); max-width: 34em; font-size: clamp(16px, 1.75vw, 19px); line-height: 1.62; color: var(--photo-fg-2); }
.hero__cta { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 34px; }
.hero__note { margin-top: 18px; font-size: 13.5px; font-weight: 600; color: var(--photo-fg-3); }

/* Невидима копія боксу фотографії — рівно її пропорція й нічого більше.
   Потрібен один її піксель: нижній край, по якому шапка розуміє, що кадр
   лишився позаду. Окремим елементом, а не самим `.hero__photo`, бо на тому
   лежить паралакс — трансформ возив би цей край разом із собою, і шапка
   перемикалася б не там, де це видно оку. */
.hero__edge {
  position: absolute; inset: 0 0 auto; width: 100%;
  aspect-ratio: var(--hero-photo-ratio, 16 / 9);
  z-index: 0; pointer-events: none;
}

/* ══ РУХ ══════════════════════════════════════════════════════════

   Правило те саме, що й було, і воно тут головне: однакова поява на кожній
   секції — це не анімація, а тик. Жодна секція цієї сторінки не виїжджає
   знизу тільки тому, що до неї долистали.

   Натомість рухається те, що й без руху вже є композицією або змістом. Кожен
   рух нижче можна назвати одним реченням, і в кожному реченні є «бо». Жоден
   нічого не ховає: без JS і при `prefers-reduced-motion` сторінка показує
   кінцевий стан усіх до одного.

   1. Поява верху при завантаженні — те, що було тут завжди.
   2. Вольтова лінія під обіцянкою в заголовку дорисовується після того, як
      сам заголовок сів. Одна авторська мить на весь перший екран.
   3. Кадр героя повільно наїжджає, поки сторінка йде вниз. Скрим стоїть на
      місці — тому напис лишається прибитим, а глибина зʼявляється між ним і
      фотографією. Це і є паралакс: не «фон їде», а два плани роз'їжджаються.
   4. Великий знімок продукту сідає на своє місце — він виламується з колонки
      до краю вікна, і глибина каже, що це навмисне, а не збій сітки.
   5. Нитка прогресу під шапкою. Сторінка довга, а нитка на ній — уже мотив:
      нею з'єднані кроки «першого вечора» і кроки «двох дверей». Прогрес
      читання — це та сама нитка, тільки про всю сторінку.
   6. Нитки «двох дверей» малюють себе. Рух тут — стежка, якою клієнт іде.
   7. Колія «першого вечора» заповнюється. Там рух — це і є зміст.

   Решта — не поява, а відповідь на дію: кнопка, рядок, питання, стрілка,
   телефон під курсором. */
@media (prefers-reduced-motion: no-preference) {
  .rise { animation: rise .9s cubic-bezier(.16, 1, .3, 1) backwards; }
  .rise-1 { animation-delay: .04s; }
  .rise-2 { animation-delay: .12s; }
  .rise-3 { animation-delay: .2s; }
  @keyframes rise {
    from { opacity: 0; transform: translateY(24px); filter: blur(7px); }
    to   { opacity: 1; transform: none; filter: none; }
  }

  /* Лінія приходить тоді, коли заголовок уже став на місце: вона — висновок
     фрази, а не її частина, і рухатись разом із нею їй нема чого. Анімується
     колір підкреслення, бо його ширину анімувати не можна; чому саме
     `text-decoration`, а не лінія, якій можна розгорнути ширину, — сказано
     там, де вона оголошена. */
  .hero h1 em { animation: heroRule .5s ease .62s backwards; }
  @keyframes heroRule {
    from { text-decoration-color: transparent; }
    to   { text-decoration-color: var(--photo-volt); }
  }
}

/* Великий знімок продукту сідає на місце, перетинаючи екран: він виламується
   з колонки до краю вікна, і глибина каже, що це навмисне, а не збій сітки.
   Прокрутка тут не привід для появи — вона і є той рух, який композиція вже
   описує. Де `view()` не працює, знімок просто стоїть у кінцевому стані.

   Діапазон починається рано: знімок іде до краю вікна, і поки його нижній
   край іще за екраном, рух під ним нікому не видно. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .shot {
      animation: settle linear both;
      animation-timeline: view();
      animation-range: entry 14% cover 40%;
    }
    @keyframes settle {
      from {
        transform: translateY(16px) scale(.988);
        box-shadow: 0 6px 14px -14px rgba(20, 24, 27, .3), 0 1px 3px rgba(20, 24, 27, .04);
      }
      to { transform: none; box-shadow: var(--lift); }
    }
  }
}

/* Паралакс кадру героя. Часова вісь — прокрутка сторінки, а не поява самого
   шару: шар лежить на екрані з першої фарби, і `view()` дав би йому прогрес
   уже посеред діапазону — кадр стояв би зміщеним ще до того, як хтось
   торкнувся коліщатка. `scroll(root)` із явним діапазоном у 90vh рахує від
   нуля, тому початковий стан — і є те, що видно при завантаженні.

   Масштаб трохи більший за одиницю з самого початку і росте разом зі зсувом:
   кадр іде вгору на 7% власної висоти, і без запасу знизу відкрилася б смуга
   тла. Зсув і масштаб в одному `transform` — одна композитна властивість,
   тобто рух не торкається розкладки взагалі. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero__photo {
      animation: heroDrift linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 90vh;
    }
    /* Масштаб навмисно скромний. Кадр тут 1280×720 на смузі в півтори тисячі
       пікселів завширшки, тобто його вже розтягують; кожен зайвий відсоток
       наїзду віднімає різкість там, де її й так обмаль. Раніше тут стояло
       1.03→1.10, і ці сім відсотків було видно. */
    @keyframes heroDrift {
      from { transform: translate3d(0, 0, 0) scale(1.02); }
      to   { transform: translate3d(0, -4%, 0) scale(1.06); }
    }

    /* Нитка прогресу. Стоїть на власному нижньому краї шапки — тобто рівно
       там, де в «пройденому» стані вже є волосяна лінія, і замінює її собою,
       а не додає другу смугу під нею. */
    .nav::after {
      content: ""; position: absolute; left: 0; bottom: -1px;
      width: 100%; height: 2px; background: var(--lime);
      transform: scaleX(0); transform-origin: 0 50%;
      animation: navProgress linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes navProgress {
      from { transform: scaleX(0); }
      to   { transform: scaleX(1); }
    }
  }
}

/* ── секції ───────────────────────────────────────────────────────── */
.section { padding: clamp(64px, 9vw, 116px) 0; }
/* Чорнильна смуга вже несе власні поля — секція навколо неї їх не додає. */
.section--flush { padding-block: 0 clamp(64px, 9vw, 116px); }
.section--top-flush { padding-top: 0; }
/* Остання секція сторінки не малює свого дна. Закриття в кожної з шістнадцяти
   сторінок — самодостатній блок із власними полями всередині (`.after` на
   внутрішніх, фотополоса `.final` на головній), а під ним стоїть власний
   відступ підвала. Секція додавала між ними третій проміжок, і разом виходило
   224 пікселі порожнього ґрунту — чверть екрана, на якій не діється нічого,
   рівно там, де сторінка мала б закінчитися кадром і кнопкою. Лишається
   відступ підвала, який для цього й існує. */
main > .section:last-child { padding-bottom: 0; }
.lede { max-width: 20ch; font-size: clamp(30px, 4.2vw, 46px); }
.lede--wide { max-width: 26ch; }
.lede + p { margin-top: 20px; max-width: 62ch; font-size: clamp(15.5px, 1.7vw, 18px); color: var(--t3); line-height: 1.62; }

/* ══ ЗАЧИНИ ═══════════════════════════════════════════════════════

   На сторінці одинадцять секцій, і десять із них починалися однаково:
   заголовок `.lede`, під ним дрібний сірий абзац. Кожен блок окремо був
   правильний; разом вони давали ритм одного документа з десятьма
   однаковими підзаголовками — того, який гортають, а не читають.

   Зачинів тепер чотири, і кожен обрано за ЗМІСТОМ абзаца під заголовком,
   а не заради різноманітності:

     `.opener`   — абзац не пояснює заголовок, а є тезою сторінки;
     `.ledger`   — заголовок стоїть збоку й тримається, поки повз нього
                   йдуть докази;
     `.showcase` — заголовок живе в колонці поруч із кадром;
     `.lede`     — звичайний зачин; лишився там, де за ним іде самодостатній
                   блок, який говорить сам: двері, тарифи, колія, питання. */
.opener { max-width: 24ch; font-size: clamp(32px, 5.2vw, 56px); }
/* Теза набрана великою й світлою, а не дрібною сірою, і `--t2` замість
   `--t3` — з тієї самої причини: це не підпис під заголовком, це те, заради
   чого сторінку відкрили. */
.opener__lead {
  margin-top: clamp(20px, 2.6vw, 30px);
  max-width: 52ch;
  font-size: clamp(17px, 2vw, 22px);
  line-height: 1.52; color: var(--t2);
  text-wrap: pretty;
}

/* Твердження ліворуч, шість доказів праворуч. Липкість тут не ефект: доки
   список доводить, твердження лишається на екрані — інакше читач доходить
   до шостого рядка, вже не памʼятаючи, що саме ці рядки доводять.

   `align-self: start` обовʼязковий. Без нього колонка розтягується на всю
   висоту рядка сітки, і `sticky` всередині неї не тримає нічого: липкому
   елементу нема куди їхати всередині власної повної висоти.

   Зсув рахується від шапки, а не вгадується: вона `sticky` заввишки 68px,
   і заголовок мусить ставати під нею, а не за нею.

   Нижче 1000px колонка одна й липкості немає взагалі — тримати заголовок
   на телефоні означає забрати в списку третину екрана. */
.ledger { display: grid; grid-template-columns: 1fr; gap: clamp(28px, 3.6vw, 44px); }
@media (min-width: 1000px) {
  .ledger {
    grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
    column-gap: clamp(44px, 5vw, 80px);
  }
  .ledger__head { position: sticky; top: calc(68px + clamp(20px, 3vw, 36px)); align-self: start; }
}

/* ══ ЗМІСТ КАБІНЕТУ — список, а не сітка карток ═══════════════════

   Список лишається списком. Змінилися дві речі, і обидві — про читання.

   Десять однакових рядків на всю ширину — це текстура, а не зміст: око бачить
   сіру стіну й гортає далі. Два стовпці по пʼять дають той самий список одним
   поглядом і рівно ту висоту, яку зміст і має мати.

   Назва більше не стоїть у вузькій колонці. «Налаштування» і «Листування»
   переносилися там на два рядки, поки праворуч лишалося пів екрана порожнечі:
   колонка була розрахована на англійське слово. Тепер назва починає рядок, а
   опис іде під нею — і жодна мова не ламає сітку. */
.index {
  margin-top: clamp(40px, 5vw, 60px);
  display: grid; grid-template-columns: 1fr;
  border-top: 1px solid var(--hairline);
}
@media (min-width: 1000px) {
  /* Колонка вниз, потім друга: порядок у розмітці = порядок читання. */
  .index {
    grid-template-columns: 1fr 1fr; grid-template-rows: repeat(5, auto);
    grid-auto-flow: column; column-gap: clamp(32px, 4vw, 60px);
  }
}
.index__row {
  position: relative;
  display: grid; grid-template-columns: 34px 1fr; gap: 3px 16px;
  padding: 17px 2px; border-bottom: 1px solid var(--hairline);
}
/* Аркуш під рядком — окремим шаром: волосяна лінія лишається на сітці, а
   підсвітка виходить за неї на відступ, як у списках кабінету. */
.index__row::before {
  content: ""; position: absolute; inset: 3px -14px; z-index: 0;
  border-radius: 14px; background: var(--paper); box-shadow: var(--card-shadow), 0 0 0 1px var(--hairline), var(--edge-lit);
  opacity: 0; transition: opacity .18s ease;
}
.index__row:hover::before { opacity: 1; }
.index__row > * { position: relative; z-index: 1; }
/* Вольт плиткою — це вольт ФОНОМ, той самий закон, що й у кнопки. Десять
   маленьких плиток дають стіні ритм, якого не дає десять сірих гліфів. */
.index__row .ms {
  grid-row: 1 / span 2; align-self: start; transform: none;
  width: 34px; height: 34px; border-radius: 10px; font-size: 19px;
  background: var(--lime-soft); color: var(--lime-ink);
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 20;
  transition: background .18s ease, color .18s ease, font-variation-settings .22s ease;
}
/* Вісь FILL — ідіома самого кабінету, де залитий гліф каже «ви тут». Тут він
   каже «курсор тут»: та сама вісь того самого змінного шрифта, тому заливка,
   а не збільшення й не поворот. */
.index__row:hover .ms {
  background: var(--lime); color: var(--on-volt);
  font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 20;
}
.index__row b { font-size: 16.5px; font-weight: 800; letter-spacing: -.025em; }
.index__row p { font-size: 14.5px; color: var(--t3); line-height: 1.55; max-width: 52ch; }

/* ══ ДВОЄ ДВЕРЕЙ — дві стежки, що сходяться в одну ════════════════

   Найгостріша правда продукту жила рядком у FAQ. Тут вона стає композицією:
   дві колонки кроків, зʼєднані вольтовою ниткою, і одна смуга під ними, на
   якій обидві сходяться. Це не «дві однакові картки» — це дві стежки, і без
   тексту скелет каже те саме, що й із ним.

   Смуга — єдина вольтова поверхня на сторінці. Вольт тут фон, текст — темний
   крок (#5a7409 на #edf4d6 = 4,7:1), рівно як у кабінеті. */
.doors { margin-top: clamp(38px, 4.6vw, 56px); display: grid; gap: clamp(18px, 2.2vw, 26px); grid-template-columns: 1fr 1fr; }
@media (max-width: 820px) { .doors { grid-template-columns: 1fr; } }

.door { background: var(--paper); border-radius: 20px; padding: clamp(24px, 3vw, 34px); box-shadow: var(--card-shadow), 0 0 0 1px var(--hairline), var(--edge-lit); }
.door__head { display: flex; align-items: center; gap: 13px; }
.door__head .ms {
  width: 38px; height: 38px; border-radius: 11px; font-size: 21px;
  background: var(--ink); color: var(--lime-on-ink);
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}
.door__head b { font-size: 17.5px; font-weight: 800; letter-spacing: -.03em; }

.door__steps { list-style: none; margin: 22px 0 0; padding: 0; }
.door__steps li {
  position: relative; padding: 0 0 22px 32px;
  font-size: 15px; color: var(--t2); line-height: 1.55;
}
/* Вузол на нитці. Ореол — це не тінь, а другий крок вольта: він відділяє
   вузол від лінії, яка крізь нього проходить. */
.door__steps li::before {
  content: ""; position: absolute; left: 4px; top: 7px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--lime); box-shadow: 0 0 0 3.5px var(--lime-soft);
}
.door__steps li::after {
  content: ""; position: absolute; left: 7.5px; top: 20px; bottom: 1px;
  width: 2px; border-radius: 2px; background: var(--hairline);
}
.door__steps li:last-child { padding-bottom: 0; }
.door__steps li:last-child::after { display: none; }

.doors__one {
  margin-top: clamp(16px, 2vw, 22px);
  display: flex; align-items: flex-start; gap: 16px;
  background: var(--lime-soft); color: var(--lime-ink);
  border-radius: 18px; padding: clamp(20px, 2.4vw, 26px) clamp(22px, 2.6vw, 30px);
  font: 700 clamp(15px, 1.6vw, 17px)/1.5 var(--font); letter-spacing: -.015em;
}
.doors__one .ms {
  width: 26px; height: 26px; font-size: 26px; flex: none;
  /* Оптичне вирівнювання по першому рядку: гліф вищий за свою висоту рядка. */
  margin-top: -1px;
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}

/* Обидві стежки малюють себе — вузол спалахує, за ним тягнеться нитка до
   наступного. Це той самий механізм, що в колії «першого вечора» (той самий
   спостерігач у скрипті, той самий клас `is-on`), і це навмисно: у CSS вище
   вже сказано, що двоє дверей і чотири кроки — одна будова.

   Двері малюються ОДНОЧАСНО, а не одні за одними. Зміст блока в тому, що
   дверей двоє й вони рівноправні; послідовність сказала б, що спершу бот, а
   вже потім код, чого немає.

   Початковий стан оголошений лише під `.js` — клас ставить інлайновий скрипт
   у <head>. Без JS перша ж фарба показує повні стежки, а не порожні, які
   хтось потім домалює. */
@media (prefers-reduced-motion: no-preference) {
  .js .door__steps li::before { transform: scale(.4); opacity: 0; }
  .js .door__steps li::after { scale: 1 0; transform-origin: center top; }

  .js .doors.is-on .door__steps li::before {
    transform: none; opacity: 1;
    transition: transform .38s cubic-bezier(.16, 1, .3, 1), opacity .22s ease;
  }
  .js .doors.is-on .door__steps li::after {
    scale: 1 1; transition: scale .34s cubic-bezier(.16, 1, .3, 1);
  }

  .js .doors.is-on .door__steps li:nth-child(1)::before { transition-delay: .06s; }
  .js .doors.is-on .door__steps li:nth-child(1)::after  { transition-delay: .16s; }
  .js .doors.is-on .door__steps li:nth-child(2)::before { transition-delay: .34s; }
  .js .doors.is-on .door__steps li:nth-child(2)::after  { transition-delay: .44s; }
  .js .doors.is-on .door__steps li:nth-child(3)::before { transition-delay: .62s; }
}

/* ── великий знімок продукту ──────────────────────────────────────── */
.showcase { display: grid; gap: clamp(30px, 4vw, 52px); align-items: center; grid-template-columns: minmax(0, .72fr) minmax(0, 1.28fr); }
.showcase--flip .showcase__copy { order: 2; }
/* `order` переставляє елементи по клітинках, а не клітинки — тож ширшу колонку
   треба перенести теж, інакше в перевернутому блоці знімок отримує вузьку. */
.showcase--flip { grid-template-columns: minmax(0, 1.28fr) minmax(0, .72fr); }
@media (max-width: 940px) { .showcase { grid-template-columns: 1fr; } .showcase--flip .showcase__copy { order: 0; } }

/* Знімок виходить за колонку до краю вікна: інакше кабінет ужимається
   до шестисот пікселів і перестає читатись як робочий екран. */
.showcase__shot { margin-right: calc(-1 * (50vw - var(--shell) / 2)); }
.showcase--flip .showcase__shot { margin-right: 0; margin-left: calc(-1 * (50vw - var(--shell) / 2)); }
@media (max-width: 1260px) { .showcase__shot, .showcase--flip .showcase__shot { margin-inline: 0; } }

/* Смуга з ФОТОГРАФІЄЮ, а не зі знімком продукту, живе за іншим правилом.
   Виламування за край вікна й вузька колонка тексту існували заради одного:
   кабінет, ужатий до шестисот пікселів, перестає читатись як робочий екран.
   Фотографія на шестистах читається чудово — а от заголовок у чотири рядки
   в колонці на 360 не читається зовсім. Тож тут колонки рівні, і кадр
   лишається всередині смуги.

   Запит по ширині тут ОБОВʼЯЗКОВИЙ, і саме його бракувало. Правило стоїть
   нижче за `@media (max-width: 940px)`, яке звалює `.showcase` в одну колонку,
   тож без власної межі воно перемагало те звалювання на кожній ширині: смуга
   «Грошей» лишалася двоколонковою і на 390, де заголовок ліг у чотири рядки
   по три слова, а кадр ужався до трьохсот пікселів збоку від нього. Межа та
   сама (941), бо це те саме звалювання, а не друге. */
@media (min-width: 941px) {
  .showcase--photo,
  .showcase--photo.showcase--flip { grid-template-columns: minmax(0, 1fr) minmax(0, .92fr); }
}
.showcase--photo .showcase__shot,
.showcase--photo.showcase--flip .showcase__shot { margin-inline: 0; }

.shot { border-radius: 14px; overflow: hidden; box-shadow: var(--lift), 0 0 0 1px var(--hairline); background: var(--paper); }

.claims { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 16px; }
.claims li { position: relative; padding-left: 30px; font-size: 15px; color: var(--t2); line-height: 1.58; max-width: 46ch; }
.claims .ms { position: absolute; left: 0; top: 1px; font-size: 20px; width: 20px; height: 20px; color: var(--lime-ink); font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 20; }

/* ══ ЗАСТОСУНОК — чорнильна смуга ════════════════════════════════ */
.ink {
  background: var(--ink); color: var(--on-ink);
  border-radius: clamp(22px, 2.6vw, 34px);
  padding: clamp(48px, 7vw, 82px) 0 clamp(30px, 4vw, 46px);
  position: relative; overflow: hidden;
}
.ink::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(48% 42% at 6% 2%, rgba(168, 207, 27, .17), rgba(168, 207, 27, 0) 66%),
    radial-gradient(44% 40% at 96% 98%, rgba(168, 207, 27, .08), rgba(168, 207, 27, 0) 68%);
}
.ink > * { position: relative; }
.ink .lede + p { color: var(--on-ink-2); }

/* Смуга гасне на обох краях: обрізаний телефон інакше читається як помилка
   верстки, а не як «тут є ще». Маска йде рівно по відступу смуги, тож перший
   і останній кадри стоять на місці, а не в тумані. */
.phones {
  margin-top: clamp(36px, 5vw, 52px); display: flex; gap: 20px;
  overflow-x: auto; scroll-snap-type: x proximity;
  /* `overflow-x: auto` робить `overflow-y` теж прокруткою, тобто ріже і зверху.
     Шести пікселів не вистачало навіть у спокої: рамка телефона намальована
     тінню назовні на 8,5px, а при наведенні картка ще й підіймається на 7 —
     отже зверху треба щонайменше 16, і саме верх зрізало. Знизу тінь наведення
     доходить до тридцяти. */
  padding: 18px var(--gutter) 34px; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 calc(var(--gutter) * .8), #000 calc(100% - var(--gutter) * .8), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 calc(var(--gutter) * .8), #000 calc(100% - var(--gutter) * .8), transparent 100%);
}
.phones::-webkit-scrollbar { display: none; }
.phone { scroll-snap-align: center; flex: none; width: 228px; margin: 0; }
.phone__screen {
  border-radius: 27px; overflow: hidden;
  /* Рамка мусить читатись НА чорнилі, тому вона світліша за нього. */
  box-shadow: 0 0 0 7px #2f363b, 0 0 0 8.5px #545d63, 0 22px 44px -20px rgba(0, 0, 0, .78);
}
.phone b { display: block; margin-top: 19px; font-size: 14px; font-weight: 800; letter-spacing: -.02em; transition: color .18s ease; }
.phone p { margin-top: 5px; font-size: 13px; color: var(--on-ink-dim); line-height: 1.48; }
/* Смуга гортається, і під курсором кадр мусить показати, що він — окремий
   предмет, а не шматок картинки. Піднімається екран, а не вся картка:
   підпис лишається на своєму рядку, і сусідні підписи з ним не розʼїжджаються. */
.phone__screen { transition: transform .22s cubic-bezier(.2, .9, .3, 1), box-shadow .22s ease; }
.phone:hover .phone__screen {
  transform: translateY(-7px);
  box-shadow: 0 0 0 7px #363e44, 0 0 0 8.5px #6b757b, 0 30px 52px -20px rgba(0, 0, 0, .85);
}
.phone:hover b { color: var(--lime-on-ink); }
.phones__hint {
  display: flex; align-items: center; gap: 7px;
  padding-inline: var(--gutter);
  font: 700 12.5px/1 var(--font); color: var(--on-ink-dim);
}
.phones__hint .ms { font-size: 16px; width: 16px; height: 16px; font-variation-settings: 'FILL' 0, 'wght' 600, 'GRAD' 0, 'opsz' 20; }

/* «Гортайте вбік» — це порада пальцю. Миші вона нічого не каже: у смуги
   навмисно немає смужки прокрутки, тож на десктопі не видно навіть того,
   що вона рухається. Тому там стоять справжні кнопки, а підказка йде. */
.phones__nav { display: none; }
@media (hover: hover) and (pointer: fine) {
  .phones__hint { display: none; }
  .phones__nav { display: flex; gap: 8px; padding-inline: var(--gutter); }
}
.phones__nav button {
  width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .14); color: var(--on-ink);
  transition: background .16s ease, color .16s ease, opacity .16s ease;
}
.phones__nav button:hover:not(:disabled) { background: var(--lime); color: var(--on-volt); }
.phones__nav button:disabled { cursor: default; opacity: .3; }
.phones__nav .ms { font-size: 20px; width: 20px; height: 20px; }

/* ══ ПРОБЛЕМА, А ПОТІМ ВИГОДА ════════════════════════════════════

   Блок стоїть рівно там, де в кожного конкурента смуга довіри: «400k
   тренерів», логотипи мереж, 4.9 на Capterra. Вигаданій цифрі тут не
   місце, а слот справжній — і заповнює його коштом того, хто читає:
   спершу ціна проблеми, потім дві вигоди. Проза, бо це міркування, а
   не перелік; список тут сказав би, що продукт — це набір фіч. */
.what {
  margin-top: 22px; display: grid; gap: clamp(16px, 2vw, 26px);
  grid-template-columns: 1fr 1fr;
}
@media (max-width: 880px) { .what { grid-template-columns: 1fr; } }
.what p { font-size: clamp(15px, 1.6vw, 16.5px); line-height: 1.66; color: var(--t2); }
/* Одна вигода в колонці. Вольтова крапля на початку каже, що це двоє,
   а не один текст у дві колонки. */
.what p::before {
  content: ""; display: block; width: 26px; height: 3px; border-radius: 2px;
  margin-bottom: 16px; background: var(--lime);
}
/* Риска каже, що колонок двоє; вона не каже, ПРО ЩО кожна. Тому вигода
   винесена в окремий рядок і світліша за текст — її видно ще до того,
   як око почне читати абзац, який її пояснює. */
.what p b {
  display: block; margin-bottom: 7px;
  font-weight: 800; letter-spacing: -.02em; color: var(--t1);
}

/* ── три обіцянки: рядки, а не картки ─────────────────────────────

   Кожну з трьох можна перевірити, не реєструючись, і саме цим вони й
   відрізняються від «#1 platform» у сусідів. (Четвертими тут були «Чотири
   мови»; чому їх звідси прибрано — у README.)

   Малювались вони сіткою з трьох комірок з іконкою — тобто тим самим, чим
   нижче намальовані «своє» й «двоє дверей». Обіцянку читають, а не
   проглядають: тому рядок на всю ширину, кегль замість іконки й волосяна
   лінія замість коробки. Ліворуч те, що ми обіцяємо, праворуч — чому це
   правда, і на вузькому екрані друге просто стає під першим. */
.facts {
  list-style: none; margin: clamp(38px, 4.8vw, 58px) 0 0; padding: 0;
  border-top: 1px solid var(--hairline);
}
.facts li {
  display: grid; grid-template-columns: 1fr; gap: 7px 40px;
  padding: clamp(19px, 2.3vw, 26px) 0;
  border-bottom: 1px solid var(--hairline);
}
/* Колонка обіцянки міряється в `ch`, а не у відсотках: тут чотири мови, і
   «Гроші йдуть на ваш рахунок» проти «The money lands in your account» —
   це різна довжина, а не різна частка ширини. */
@media (min-width: 820px) {
  .facts li { grid-template-columns: minmax(0, 24ch) minmax(0, 1fr); align-items: baseline; }
}
.facts b {
  font-size: clamp(16.5px, 1.9vw, 19px); font-weight: 800;
  letter-spacing: -.03em; color: var(--t1); text-wrap: balance;
}
/* Опис займає решту рядка, а не 62ch посеред нього: волосяна лінія йде на всю
   ширину, і текст, що уривався за три чверті до неї, лишав праворуч порожнечу,
   яка читалась як недоверстаний блок, а не як повітря. */
.facts span { font-size: 15px; line-height: 1.6; color: var(--t3); max-width: 78ch; }

.who {
  display: flex; align-items: flex-start; gap: 11px;
  margin-top: clamp(22px, 2.6vw, 30px);
  font-size: 14.5px; line-height: 1.6; color: var(--t3); max-width: 74ch;
}
.who .ms { flex: none; margin-top: 1px; font-size: 19px; width: 19px; height: 19px; color: var(--t4); }

/* ══ СЛОТ ПІД ФОТОГРАФІЮ ═════════════════════════════════════════

   Контракт той самий, що в героя: файл необовʼязковий, і сторінка мусить
   виглядати закінченою без нього. Немає файла — лишається намальована
   заглушка, яка читається як рішення, а не як діра; є — скрипт кладе
   `--slot`, і фотографія просто перекриває її собою.

   Пропорція задана ТУТ, а не береться з файла: слот стоїть у колонці
   поруч із текстом, і кадр, що приїхав за секунду після першої фарби,
   інакше зсував би все, що під ним.

   3:2, а не 4:3, — і це не смак, а те, що віддає генератор. ChatGPT у
   горизонтальному режимі дає 1536×1024, тобто рівно 3:2; при 4:3 `cover`
   зрізав би по одинадцять відсотків з кожного боку, а на цих кадрах саме
   там стоять предмети, які тримають композицію. Дешевше підігнати слот
   один раз, ніж різати кожну фотографію. Промти — `assets/photo/PROMPTS.md`. */
.photoslot {
  position: relative; margin: 0; aspect-ratio: 3 / 2;
  border-radius: 18px; overflow: hidden;
  background: var(--sunken) var(--slot, none) center / cover no-repeat;
  box-shadow: var(--lift), 0 0 0 1px var(--hairline), var(--edge-lit);
  display: grid; place-content: center; justify-items: center; gap: 12px;
}
/* Пунктир — те, чим EmptyState у застосунках каже «сюди ще нічого не
   поклали». Він лежить усередині, а не рамкою: рамка змагалася б із
   волосяною лінією аркуша. */
.photoslot::before {
  content: ""; position: absolute; inset: 14px; border-radius: 12px;
  border: 1.5px dashed rgba(255, 255, 255, .12);
}
.photoslot .ms {
  font-size: 30px; width: 30px; height: 30px; color: var(--lime-ink);
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 40;
}
.photoslot figcaption {
  font: 600 11.5px/1.2 var(--display); letter-spacing: .13em;
  text-transform: uppercase; color: var(--t4);
}
/* Слот у смузі застосунку ширший і пласкіший за два інші: у ньому не
   портрет, а композиція «людина + екран, у який вона дивиться», і 3:2
   поставило б телефон на всю висоту кадру. 2:1 — те, що віддає монтаж, і
   те, з чим не треба нічого різати. Він стоїть на всю ширину смуги, а не
   в колонці поруч із текстом, тож пропорція тут — єдине, що тримає
   верстку до приїзду файла. */
.photoslot--app {
  aspect-ratio: 2 / 1; max-width: 1120px; margin: clamp(28px, 3.6vw, 44px) auto 0;
}
/* Пропорція та сама на будь-якій ширині, і на телефоні теж. Спокуса
   зробити кадр квадратнішим, щоб екран не мерхнув, коштує рівно того,
   заради чого кадр тут: `cover` ріже симетрично від центру, а телефон
   стоїть при правому краї — на 4:3 у нього зникала права третина разом
   із «2 of 3 this week». Змонтований кадр ріжеться лише там, де його
   монтували; тут — ніде. */

/* Приїхала фотографія — заглушка йде цілком. Не `opacity`: пунктир поверх
   кадру читався б як рамка, якої ніхто не просив. */
.photoslot.has-photo::before,
.photoslot.has-photo .ms,
.photoslot.has-photo figcaption { display: none; }

/* ══ ТАРИФИ ══════════════════════════════════════════════════════

   Три комірки в одній рамці, розділені волосяною лінією, — той самий
   прийом, що й у «Бот ваш» (`.own`). README відмовляється від сіток
   однакових карток як від структури сторінки, і має рацію; але три плани
   саме ПОРІВНЮЮТЬ, і спільна рамка тут і є змістом, а не шаблоном.

   Ціна набрана Oswald: це мова стартових номерів і табло, тобто рівно та
   сама, якою на цій сторінці говорять фотополоси. Числа звірені з
   `backend/modules/platform-billing` — див. коментар в `index.html`. */
.plans {
  margin-top: clamp(38px, 4.6vw, 56px);
  display: grid; gap: 1px; background: var(--hairline);
  border-radius: 20px; overflow: hidden; box-shadow: 0 0 0 1px var(--hairline);
}
@media (min-width: 760px) { .plans { grid-template-columns: repeat(3, 1fr); } }
/* Колонка з `margin-top: auto` перед ціною, а не `min-height` на описі:
   опис має чотири переклади, і чеський вирівнює висоту рівно доти, доки
   хтось не додасть слово. Ціна й ліміт прибиті до низу картки, тож усі три
   стоять в один рядок будь-якою мовою. */
.plan {
  position: relative; background: var(--paper);
  padding: clamp(26px, 3vw, 36px);
  display: flex; flex-direction: column; gap: 8px;
}
/* Відмічений план — вольтова смужка ЗГОРИ, а не світліша заливка комірки:
   на темному світліша пляма читається як наведення, а не як вибір.

   Але й ТЕМНІША заливка не годиться, а саме вона тут і стояла: `--sunken`
   темніший за `--paper`, тож відмічена комірка западала між двома звичайними
   й читалася не як вибрана, а як вимкнена — рівно навпаки до наміру. Заливка
   тепер та сама, що в сусідів, і весь знак несе світло з верхнього краю:
   смужка та сама, під нею — короткий вольтовий розсип, який гасне на чверті
   висоти. Це не пляма й не наведення: це край, що світиться.

   Розсип — шар ВЛАСНОГО фону комірки, а не псевдоелемент. Псевдоелемент
   позиціонується, тобто малюється поверх звичайних дітей, і вольтова вуаль,
   хай навіть у десять відсотків, лягала б на слово «PRO» й на ціну під ним.
   Фоновим шаром вона там, де їй місце: під текстом. */
.plan--mark {
  background: linear-gradient(180deg, rgba(168, 207, 27, .10), rgba(168, 207, 27, 0) 26%), var(--paper);
}
.plan--mark::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 3px; background: var(--lime);
}
.plan__name { font: 600 15px/1 var(--display); letter-spacing: .1em; text-transform: uppercase; color: var(--t1); }
.plan--mark .plan__name { color: var(--lime-ink); }
.plan__for { font-size: 14px; line-height: 1.5; color: var(--t3); }
.plan__sum {
  margin-top: auto; padding-top: 18px;
  font: 600 clamp(40px, 4.6vw, 54px)/1 var(--display);
  letter-spacing: -.01em; color: var(--t1);
}
.plan__cur { font-size: .56em; margin-right: .1em; color: var(--t3); }
.plan__per { font: 700 14px/1 var(--font); letter-spacing: 0; color: var(--t3); margin-left: 6px; }
.plan__cap {
  display: flex; align-items: center; gap: 8px; margin-top: 14px;
  font-size: 14.5px; font-weight: 700; color: var(--t2);
}
.plan__cap .ms { font-size: 18px; width: 18px; height: 18px; color: var(--lime-ink); }

/* Те, що однакове в усіх трьох. Стоїть ПІД рамкою, а не рядком у кожній
   комірці: повторене тричі, воно читалось би як три різні обіцянки. */
.price__all { list-style: none; margin: clamp(24px, 3vw, 32px) 0 0; padding: 0; display: grid; gap: 13px; }
.price__all li { display: flex; align-items: flex-start; gap: 11px; font-size: 15px; line-height: 1.58; color: var(--t2); max-width: 74ch; }
.price__all .ms {
  flex: none; margin-top: 1px; font-size: 19px; width: 19px; height: 19px; color: var(--lime-ink);
  font-variation-settings: 'FILL' 0, 'wght' 600, 'GRAD' 0, 'opsz' 20;
}

/* Заклик під тарифами. Підпис однаковий із героєвим — один намір, один
   підпис, — а нота під ним та сама, що й там: «без картки» коштує рівно
   стільки ж уваги біля ціни, скільки біля першої кнопки. */
.price__act {
  margin-top: clamp(30px, 3.6vw, 42px);
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px;
}
.price__act p { font-size: 13.5px; font-weight: 600; color: var(--t4); }

/* ══ ПИТАННЯ ═════════════════════════════════════════════════════ */
.faq { margin-top: clamp(32px, 4vw, 44px); max-width: 800px; border-top: 1px solid var(--hairline); }
.faq details { border-bottom: 1px solid var(--hairline); }
.faq summary {
  cursor: pointer; list-style: none; padding: 21px 2px;
  font: 800 17px/1.4 var(--font); letter-spacing: -.025em;
  display: flex; align-items: center; gap: 16px;
}
.faq summary::-webkit-details-marker { display: none; }
/* Рядок, який відкривається натисканням, мусить це показувати до натискання. */
.faq summary:hover { color: var(--lime-ink); }
.faq summary:hover .ms { color: var(--lime-ink); }
.faq summary .ms { margin-left: auto; color: var(--t4); transition: transform .22s cubic-bezier(.2, .9, .3, 1), color .16s ease; }
.faq details[open] summary .ms { transform: rotate(180deg); }
.faq p { padding: 0 46px 24px 2px; font-size: 15.5px; color: var(--t3); line-height: 1.62; max-width: 70ch; }
/* Відповідь виїжджає, а не зʼявляється миттю: розкриття — це зміна стану, і
   вона єдина каже, що клацнули саме сюди. Там, де браузер не вміє тягнути
   `auto`, лишається сьогоднішній стрибок — сторінка від цього не ламається. */
@supports (interpolate-size: allow-keywords) {
  @media (prefers-reduced-motion: no-preference) {
    :root { interpolate-size: allow-keywords; }
    .faq details::details-content {
      block-size: 0; overflow: clip;
      transition: block-size .34s cubic-bezier(.16, 1, .3, 1), content-visibility .34s allow-discrete;
    }
    .faq details[open]::details-content { block-size: auto; }
  }
}

/* ══ ПЕРШИЙ ВЕЧІР — та сама нитка, тільки горизонтальна ═══════════

   Це не «три кроки» з каталогу лендінгів, а той самий чек-лист, який
   кабінет справді веде й рахує з того, що збережено. Тому колія тут не
   декор: заповнення — і є зміст, і саме воно рухається при появі.

   Вузол пробиває колію власною тінню кольору тла — це дешевше й точніше,
   ніж різати лінію на чотири шматки. */
/* Сегмент належить КРОКУ, а не списку. Колія на контейнері тягнеться від
   краю до краю й вилітає далеко за останню галочку — тобто каже «і далі
   ще», рівно протилежне до «кроків чотири». Крок малює нитку до наступного
   кроку, останній не малює нічого: та сама будова, що у «двох дверей». */
.setup {
  --setup-gap: clamp(20px, 2.6vw, 34px);
  position: relative; list-style: none; margin: clamp(38px, 4.6vw, 56px) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr);
  /* Проміжок лише МІЖ КОЛОНКАМИ. Рядковий мусить лишитись нулем: рядки тепер
     спільні (нижче), і `gap` розсунув би вузол, назву й опис на ті самі 34
     пікселі, якими розведені кроки. Відстані всередині кроку задають власні
     відступи назви й опису — 18 і 6, як і до сітки. */
  column-gap: var(--setup-gap); row-gap: 0;
  /* Три рядки на всі чотири кроки: вузол, назва, опис. Без них кожен крок мав
     власну висоту назви, і «Заводите послуги й пакети» — єдина з чотирьох, що
     лягає у два рядки, — штовхала свій опис на рядок нижче за сусідні три.
     Чотири підписи, які починаються на різній висоті, читаються як збій
     верстки, а не як чотири кроки. Тримається це `subgrid`: висоту рядка
     задає найвища назва, і кожен крок стає в ті самі три смуги. */
  grid-template-rows: auto auto auto;
}

.step { position: relative; }
/* Лише поки кроки стоять у рядок: нижче 860 колія повертається вертикально й
   крок отримує власну двоколонкову сітку (див. свій запит нижче). */
@media (min-width: 861px) {
  @supports (grid-template-rows: subgrid) {
    .step { display: grid; grid-row: span 3; grid-template-rows: subgrid; align-content: start; }
  }
}
.step::before, .step::after {
  content: ""; position: absolute; border-radius: 2px;
  left: 18px; right: calc(-1 * var(--setup-gap) - 18px); top: 17px; height: 2px;
}
.step::before { background: var(--hairline); }
.step::after { background: var(--lime); transform-origin: left center; }
.step:last-child::before, .step:last-child::after { display: none; }
.step__no {
  /* Вузол мусить стояти НАД своєю ниткою: інакше вольтова лінія проходить
     просто крізь галочку й вирізає з неї смужку у два пікселі — на трьох
     вузлах із чотирьох, і галочка виглядає тоншою за останню. */
  position: relative; z-index: 1;
  width: 36px; height: 36px; border-radius: 50%; font-size: 23px;
  background: var(--lime); color: var(--on-volt);
  box-shadow: 0 0 0 6px var(--ground);
  font-variation-settings: 'FILL' 0, 'wght' 700, 'GRAD' 0, 'opsz' 24;
}
.step b { display: block; margin-top: 18px; font-size: 16px; font-weight: 800; letter-spacing: -.025em; }
.step p { margin-top: 6px; font-size: 14.5px; color: var(--t3); line-height: 1.55; max-width: 30ch; }

.setup__note {
  margin-top: clamp(26px, 3vw, 36px); padding-top: 20px;
  border-top: 1px solid var(--hairline);
  font-size: 14.5px; color: var(--t3); line-height: 1.6; max-width: 74ch;
}

/* На телефоні нитка стає вертикальною — той самий механізм, повернутий. */
@media (max-width: 860px) {
  .setup { grid-template-columns: 1fr; gap: 0; }
  .step { display: grid; grid-template-columns: 36px 1fr; gap: 2px 16px; padding-bottom: 26px; }
  .step:last-child { padding-bottom: 0; }
  .step::before, .step::after {
    left: 17px; top: 38px; bottom: 0; right: auto; width: 2px; height: auto;
  }
  .step::after { transform-origin: center top; }
  .step__no { grid-row: 1 / span 2; align-self: start; }
  .step b { margin-top: 6px; }
  .step p { max-width: 46ch; }
}

/* Заповнення колії. Початковий стан оголошений лише під `.js`: клас ставить
   інлайновий скрипт у <head>, тож без JS перша ж фарба показує завершений
   список, а не порожній, який хтось потім домалює. */
@media (prefers-reduced-motion: no-preference) {
  /* Вузол спалахує, за ним тягнеться його нитка — і так чотири рази.
     Порядок тут не прикраса: він і є той список, який кабінет веде. */
  .js .step::after { scale: 0 1; }
  .js .setup.is-on .step::after { scale: 1 1; transition: scale .32s cubic-bezier(.16, 1, .3, 1); }
  @media (max-width: 860px) {
    .js .step::after { scale: 1 0; }
    .js .setup.is-on .step::after { scale: 1 1; }
  }
  .js .step__no { background: var(--hairline); color: var(--t4); transform: scale(.86); }
  .js .setup.is-on .step__no {
    background: var(--lime); color: var(--on-volt); transform: none;
    transition: background .28s ease, color .28s ease, transform .4s cubic-bezier(.16, 1, .3, 1);
  }
  .js .setup.is-on .step:nth-child(1) .step__no { transition-delay: .08s; }
  .js .setup.is-on .step:nth-child(1)::after { transition-delay: .16s; }
  .js .setup.is-on .step:nth-child(2) .step__no { transition-delay: .34s; }
  .js .setup.is-on .step:nth-child(2)::after { transition-delay: .42s; }
  .js .setup.is-on .step:nth-child(3) .step__no { transition-delay: .60s; }
  .js .setup.is-on .step:nth-child(3)::after { transition-delay: .68s; }
  .js .setup.is-on .step:nth-child(4) .step__no { transition-delay: .86s; }
}

/* ══ ФІНАЛЬНИЙ ЗАКЛИК — знову фотографія ═════════════════════════ */
.final {
  position: relative; isolation: isolate; overflow: hidden;
  border-radius: clamp(22px, 2.6vw, 34px);
  background: var(--photo-ground); color: var(--photo-fg);
  padding: clamp(64px, 9vw, 112px) 0; text-align: center;
}
/* Сторінка відкривається фотографією й закривається нею — це та сама пара
   винятків, про яку каже шапка файла. Якщо `cta.webp` немає, скрипт кладе
   сюди кадр героя: інший фрагмент того самого знімка під щільним скримом
   читається як фактура, а не як повтор, і закриття не падає в порожню коробку.

   `38% 45%` ходить за `cta.webp`, а не навпаки. Тут вирішує телефон: смуга
   там портретна (0,68:1), тобто `cover` показує лише 45% ширини кадру й ріже
   решту з боків. При 64% — числі, підібраному колись під кадр ГЕРОЯ, що стояв
   тут замість власного, — у цю щілину потрапляла порожня підлога праворуч
   від центру, і лава, заради якої знімок і зроблено, на телефоні зникала
   цілком. На десктопі горизонтальне число не вирішує нічого: смуга там
   ширша за кадр (1,83:1 проти 1,5:1), тож `cover` збігається по ширині й
   ріже зверху й знизу — за це відповідає друге число. */
.final__photo {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: var(--final-photo, none); background-size: cover; background-position: 38% 45%;
}
.final__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(14, 17, 19, .7), rgba(14, 17, 19, .86)),
    radial-gradient(58% 60% at 50% 108%, rgba(168, 207, 27, .2), rgba(168, 207, 27, 0) 66%);
}
.final > .shell { position: relative; z-index: 2; }
/* Той самий голос, що й у героя: сторінка відкривається фотографією з
   капітельним написом і закривається нею. Кегль менший — заклик стоїть
   по центру у двох рядках, і при героєвому він упирався б у поля. */
.final h2 {
  font-family: var(--display); font-weight: 700;
  text-transform: uppercase;
  /* Міжрядковий такий самий, як у героя, і з тієї самої причини — тільки тут
     її ставить ще й українська: у «ДОКИ ВИ ЙОГО НЕ» бревис над Й стоїть рівно
     під комою рядка вище, і на телефоні, де кегль падає до 31, їм двом місця
     вже не лишалося. Діакритика над великими літерами є в усіх чотирьох
     мовах — гачек, чарка, кружок, бревис, — тож заголовок один. */
  font-size: clamp(31px, 5.6vw, 64px);
  line-height: 1.08; letter-spacing: .006em;
}
.final p { margin: 20px auto 0; max-width: 46ch; color: var(--photo-fg-2); font-size: 17px; line-height: 1.6; }
.final .btn { margin-top: 32px; }
/* Той самий рядок, що під героєм: людина, яка дочитала до кінця, ставить те
   саме питання, що й та, яка щойно прийшла — «а що це мені коштує зараз». */
.final__note { margin: 18px auto 0; max-width: 46ch; font-size: 13.5px; font-weight: 600; color: var(--photo-fg-3); }

/* ══ ПІДВАЛ ══════════════════════════════════════════════════════ */
.footer { padding: 54px 0 60px; border-top: 1px solid var(--hairline); margin-top: clamp(64px, 9vw, 108px); }
.footer__in { display: flex; flex-wrap: wrap; gap: 28px 48px; align-items: flex-start; }
.footer__brand { max-width: 268px; }
.footer__brand .brand { color: var(--t1); }
.footer__brand p { margin-top: 12px; font-size: 13.5px; color: var(--t3); line-height: 1.55; }
.footer__col { display: grid; gap: 9px; align-content: start; }
.footer__col b { font: 600 12px/1.2 var(--display); letter-spacing: .12em; text-transform: uppercase; color: var(--t3); }
.footer__col a { font-size: 14px; color: var(--t3); text-decoration: none; }
.footer__col a:hover { color: var(--t1); }
.footer .langs { background: rgba(255, 255, 255, .07); }
.footer .langs button { color: var(--t3); }
.footer .langs button[aria-pressed="true"] { background: var(--lime); color: var(--on-volt); }
.footer__legal { width: 100%; margin-top: 32px; padding-top: 22px; border-top: 1px solid var(--hairline); font-size: 13px; color: var(--t3); }


/* ══════════════════════════════════════════════════════════════════════
   САЙТ ІЗ КІЛЬКОХ СТОРІНОК

   Усе нижче з'явилося тоді, коли лендінг перестав бути однією сторінкою з
   якорями: чотири сторінки продукту, довідка й статті в ній. Правило те
   саме, що й вище, — та сама кімната, той самий вольт, той самий Manrope.
   Oswald не виходить за межі, які йому відведено: дві фотополоси й дрібний
   капітель (кнопки, колонки підвалу, перемикач мов). Заголовок сторінки —
   Manrope, бо сторінка лишається сторінкою, а не стає афішею.
   ══════════════════════════════════════════════════════════════════════ */

/* ── смуга оголошення ─────────────────────────────────────────────── */
/* Не липка, і це навмисно. Шапка вже липка, і друга смуга під нею з'їдала б
   ще тридцять чотири пікселі першого екрана на телефоні — там, де фотографія
   героя і є той екран. Оголошення читають один раз; далі воно просто їде
   вгору й не повертається. Закриття зберігається, бо повернути прочитане
   на кожній із п'яти сторінок — це не оголошення, а нав'язливість. */
.promo {
  position: relative; z-index: 70;
  background: #171d20; border-bottom: 1px solid var(--hairline);
  font-size: 13px; color: var(--t2);
}
.promo__in { display: flex; align-items: center; gap: 12px; min-height: 38px; padding-block: 7px; }
.promo p { margin-inline: auto; text-align: center; text-wrap: pretty; }
.promo b { font-weight: 800; color: var(--t1); }
.promo a { color: var(--lime-ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: rgba(191, 232, 85, .45); }
.promo a:hover { text-decoration-color: currentColor; }
/* Хрестик стоїть на своєму місці незалежно від довжини рядка: текст
   центрується по всій смузі, а не по залишку після кнопки. */
.promo__x {
  position: absolute; right: var(--gutter); top: 50%; transform: translateY(-50%);
  background: none; border: 0; padding: 6px; border-radius: 8px; cursor: pointer;
  color: var(--t4); transition: color .16s ease, background .16s ease;
}
.promo__x:hover { color: var(--t1); background: rgba(255, 255, 255, .07); }
.promo__x .ms { font-size: 18px; width: 18px; height: 18px; }
@media (max-width: 700px) { .promo { font-size: 12.5px; } .promo__in { padding-right: 30px; } .promo__x { right: 8px; } }

/* ── шапка з випадними панелями ───────────────────────────────────── */
/* `<details>`, а не кнопка з панеллю: розкриття, клавіатура й читалка
   приходять від браузера. Escape і клік повз — єдине, чого `<details>` не
   вміє, і рівно це дописано в скрипті. Popover API дав би обидва задарма,
   але його панель лежить у верхньому шарі, тобто позиціонується від вікна,
   а не від свого пункту меню, — і без anchor-positioning (якого ще немає у
   Firefox) довелося б рахувати координати руками. */
.nav__item { position: relative; }
.nav__item > summary {
  display: flex; align-items: center; gap: 5px;
  padding: 9px 13px; border-radius: 10px; cursor: pointer;
  font-size: 14px; font-weight: 600; color: var(--photo-fg-2);
  white-space: nowrap; list-style: none;
  transition: background .16s ease, color .16s ease;
}
.nav__item > summary::-webkit-details-marker { display: none; }
.nav__item > summary:hover,
.nav__item[open] > summary { background: rgba(255, 255, 255, .1); color: var(--photo-fg); }
.nav__item > summary .ms { font-size: 17px; width: 17px; height: 17px; margin-right: -3px; transition: transform .22s cubic-bezier(.2, .9, .3, 1); }
.nav__item[open] > summary .ms { transform: rotate(180deg); }

.nav__pop {
  position: absolute; top: calc(100% + 9px); left: 0;
  width: 332px; padding: 8px;
  background: #171d20; border-radius: 16px;
  box-shadow: var(--deep), 0 0 0 1px var(--hairline), var(--edge-lit);
}
/* Панель праворуч від середини шапки притискається правим краєм, інакше
   остання в ряду виїжджає за вікно. */
.nav__pop--right { left: auto; right: 0; }
.nav__pop a {
  display: grid; grid-template-columns: 22px 1fr; gap: 4px 13px;
  padding: 11px 12px; border-radius: 11px; text-decoration: none;
  transition: background .16s ease;
}
.nav__pop a:hover { background: rgba(255, 255, 255, .06); }
.nav__pop .ms { grid-row: span 2; align-self: start; margin-top: 1px; font-size: 21px; width: 21px; height: 21px; color: var(--t3); transition: color .16s ease; }
.nav__pop a:hover .ms { color: var(--lime-ink); }
.nav__pop b { font-size: 14.5px; font-weight: 800; letter-spacing: -.02em; color: var(--t1); }
.nav__pop span { font-size: 12.5px; line-height: 1.45; color: var(--t3); }
@media (prefers-reduced-motion: no-preference) {
  .nav__item[open] .nav__pop { animation: pop .22s cubic-bezier(.16, 1, .3, 1) backwards; }
  @keyframes pop { from { opacity: 0; transform: translateY(-6px); } }
}

/* ── навігація на телефоні ────────────────────────────────────────── */
/* Раніше під 900px посилання просто зникали — з однією сторінкою це було
   майже правдою, з п'ятьма це сайт без навігації. `<dialog>` бере на себе
   пастку фокуса, Escape і підкладку; лишається намалювати. */
.burger {
  display: none; background: rgba(255, 255, 255, .1); border: 0;
  width: 40px; height: 40px; border-radius: 12px; cursor: pointer;
  color: var(--photo-fg); align-items: center; justify-content: center;
}
.burger:hover { background: rgba(255, 255, 255, .16); }
@media (max-width: 900px) {
  .nav__links { display: none; }
  .burger { display: inline-flex; margin-left: auto; }
  .langs { margin-left: 0; }
}
@media (max-width: 560px) { .nav__cta { display: none; } }

.drawer {
  width: min(420px, 100vw); max-width: 100vw; height: 100dvh; max-height: 100dvh;
  margin: 0 0 0 auto; padding: 0; border: 0;
  background: var(--paper); color: var(--t1);
  box-shadow: -1px 0 0 var(--hairline);
}
.drawer::backdrop { background: rgba(8, 10, 11, .66); backdrop-filter: blur(3px); }
.drawer__in { display: flex; flex-direction: column; height: 100%; padding: 18px var(--gutter) 30px; overflow-y: auto; }
.drawer__top { display: flex; align-items: center; justify-content: space-between; padding-bottom: 20px; }
.drawer__top .brand { color: var(--t1); }
.drawer__x { background: rgba(255, 255, 255, .07); border: 0; width: 40px; height: 40px; border-radius: 12px; cursor: pointer; color: var(--t2); display: inline-flex; align-items: center; justify-content: center; }
.drawer__x:hover { background: rgba(255, 255, 255, .13); color: var(--t1); }
.drawer h3 { font: 600 11.5px/1.2 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--t4); margin-top: 24px; }
.drawer nav { display: grid; gap: 2px; margin-top: 10px; }
.drawer nav a {
  display: flex; align-items: center; gap: 13px;
  padding: 13px 12px; margin-inline: -12px; border-radius: 12px;
  font-size: 16px; font-weight: 700; letter-spacing: -.02em; text-decoration: none; color: var(--t1);
}
.drawer nav a:hover { background: rgba(255, 255, 255, .06); }
.drawer nav a .ms { font-size: 21px; width: 21px; height: 21px; color: var(--t3); }
.drawer .btn { margin-top: 26px; width: 100%; }
.drawer .langs { margin-top: 18px; align-self: flex-start; background: rgba(255, 255, 255, .07); }
.drawer .langs button { color: var(--t3); }
.drawer .langs button[aria-pressed="true"] { background: var(--lime); color: var(--on-volt); }
@media (prefers-reduced-motion: no-preference) {
  .drawer[open] { animation: slide .3s cubic-bezier(.16, 1, .3, 1); }
  @keyframes slide { from { transform: translateX(24px); opacity: 0; } }
}

/* ── шапка внутрішньої сторінки ───────────────────────────────────── */
/* Фотографії тут немає й не буде: фотополос на сайті рівно дві, і обидві на
   головній. Внутрішня сторінка відкривається текстом на тому самому тлі —
   рівно тому вона й читається як наступна кімната тієї самої квартири. */
.phead { padding: clamp(46px, 7vw, 84px) 0 clamp(34px, 4.6vw, 52px); }
.phead h1 { font-size: clamp(34px, 5.4vw, 62px); max-width: 17ch; }
.phead__lead { margin-top: 22px; max-width: 58ch; font-size: clamp(16px, 1.8vw, 19px); line-height: 1.62; color: var(--t2); }
.phead__cta { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 32px; }

/* Хлібні крихти — єдине місце, де на сайті є шлях. На головній їх немає:
   звідти нікуди підніматись. */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; font-size: 13px; color: var(--t4); padding-top: clamp(22px, 3vw, 34px); }
.crumbs a { color: var(--t3); text-decoration: none; }
.crumbs a:hover { color: var(--lime-ink); }
.crumbs .ms { font-size: 15px; width: 15px; height: 15px; color: var(--t4); }

/* ── фішки під блоком ─────────────────────────────────────────────── */
/* Дрібні підписи того, з чого складається великий пункт. Вони не картки й не
   список: рядок коротких фактів, який дає щільність там, де абзац уже все
   сказав, а місця на другий абзац немає. */
/* Селектор БЕЗ нащадків — і це не педантизм. Фішка складається з трьох
   елементів (`<span><span class="ms">…</span><span>текст</span></span>`), тож
   `.chips span` малював заливку, поля й радіус на всіх трьох: гліф отримував
   свою таблетку, текст — свою, і обидві сиділи всередині третьої. Пігулка в
   пігулці, на трьох сторінках, і на телефоні вона розпухала на пів екрана.
   Дитина верхнього рівня — рівно одна фішка. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 26px; }
.chips > span {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 13px; border-radius: 99px;
  background: rgba(255, 255, 255, .05); box-shadow: inset 0 0 0 1px var(--hairline);
  font-size: 13px; font-weight: 600; color: var(--t2);
}
.chips .ms { font-size: 16px; width: 16px; height: 16px; color: var(--lime-ink); }
.ink .chips > span { background: rgba(255, 255, 255, .07); color: var(--on-ink-2); }
.ink .chips .ms { color: var(--lime-on-ink); }

/* ── плита: великий блок внутрішньої сторінки ─────────────────────── */
/* Те саме, що `.showcase` на головній, але без виїзду знімка за поля: на
   внутрішній сторінці таких блоків шість поспіль, і шість виїздів поспіль
   перестають бути прийомом. */
.slab { display: grid; gap: clamp(28px, 4vw, 56px); align-items: center; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.slab + .slab { margin-top: clamp(56px, 8vw, 104px); }
.slab--flip > :first-child { order: 2; }
@media (max-width: 940px) { .slab { grid-template-columns: 1fr; } .slab--flip > :first-child { order: 0; } }
.slab h2 { font-size: clamp(25px, 3vw, 34px); max-width: 18ch; }
.slab h2 + p { margin-top: 18px; max-width: 52ch; font-size: 16px; line-height: 1.62; color: var(--t3); }

/* ── розділ «своє» на головній: смуга, а не сітка карток ──────────

   Тут була сітка 2×2 з аркушевими комірками — рівно той прийом, яким вище
   намальовані три обіцянки, а нижче двоє дверей. Три однакові сітки з
   іконками на одній сторінці читаються як одна довга сітка з девʼятьма
   комірками, і жодна з трьох не каже, що вона про інше.

   Обіцянки стали рядками, двері лишилися аркушами з ниткою (там рух і є
   змістом), а це стало смугою: чотири колонки, розділені волосяною лінією,
   і жодної заливки. Різниця не косметична. Тут чотири РІВНОПРАВНІ речі, які
   лишаються тренерові, і колонка однакової ширини каже це краще за картку,
   яку можна взяти окремо від інших. */
.own {
  margin-top: clamp(38px, 4.6vw, 56px);
  display: grid; grid-template-columns: 1fr;
  gap: clamp(26px, 3vw, 36px);
  border-top: 1px solid var(--hairline);
  padding-top: clamp(28px, 3.2vw, 40px);
}
@media (min-width: 720px) { .own { grid-template-columns: 1fr 1fr; column-gap: clamp(30px, 3.6vw, 52px); } }
/* Сітка, над якою немає заголовка, а є підвал `.phead` — так стоять двері на
   сторінці помилки. Власний відступ `.own` складався б із тим підвалом і давав
   сто тридцять пікселів порожнечі там, де за задумом одна волосяна лінія. */
.own--flush { margin-top: 0; }

@media (min-width: 1060px) { .own { grid-template-columns: repeat(4, 1fr); } }
/* Колонка — колонка, а посилання прибите до її низу. Абзаци в чотирьох мовах
   мають різну висоту (українське «Видалення акаунта» на рядок довше за решту),
   і без цього чотири однакові посилання стояли на чотирьох різних висотах —
   тобто смуга, зміст якої в рівноправності, малювала сходинку. Той самий
   прийом, що й `margin-top: auto` перед ціною в тарифах. */
.own__cell { position: relative; display: flex; flex-direction: column; }
/* Вертикальна лінія МІЖ колонками, а не рамка навколо кожної: чотири
   колонки ділять одну смугу, а не стоять чотирма окремими предметами.
   Перша в рядку своєї лінії не малює — інакше смуга починалася б лінією,
   що стоїть у порожнечі. Хто саме «перший у рядку», залежить від того,
   скільки колонок у сітці, тому правило повторюється на кожному кроці. */
@media (min-width: 720px) {
  .own__cell { padding-left: clamp(20px, 2.4vw, 28px); }
  .own__cell::before {
    content: ""; position: absolute; left: 0; top: 3px; bottom: 3px;
    width: 1px; background: var(--hairline);
  }
  .own__cell:nth-child(odd)::before { display: none; }
}
@media (min-width: 1060px) {
  .own__cell:nth-child(odd)::before { display: block; }
  .own__cell:first-child::before { display: none; }
}
.own__head { display: flex; align-items: center; gap: 11px; }
.own__head .ms {
  font-size: 21px; width: 21px; height: 21px; color: var(--lime-ink);
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
  transition: font-variation-settings .22s ease;
}
/* Заливка гліфа — ідіома кабінету, де залитий знак каже «ви тут». Без
   аркуша під курсором вона лишається єдиною відповіддю на наведення. */
.own__cell:hover .ms { font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24; }
.own__head b { font-size: 16px; font-weight: 800; letter-spacing: -.025em; }
.own__cell p { margin-top: 12px; font-size: 14.5px; line-height: 1.58; color: var(--t3); }
.own__cell a { display: inline-flex; align-self: start; align-items: center; gap: 6px; margin-top: auto; padding-top: 15px; font-size: 13.5px; font-weight: 700; color: var(--lime-ink); text-decoration: none; }
.own__cell a .ms { font-size: 17px; width: 17px; height: 17px; transition: transform .2s cubic-bezier(.2, .9, .3, 1); }
.own__cell a:hover .ms { transform: translateX(4px); }

/* ── посилання «далі» ─────────────────────────────────────────────── */
.onward { display: inline-flex; align-items: center; gap: 8px; margin-top: 26px; font-size: 14.5px; font-weight: 700; color: var(--lime-ink); text-decoration: none; }
.onward .ms { font-size: 19px; width: 19px; height: 19px; transition: transform .2s cubic-bezier(.2, .9, .3, 1); }
.onward:hover .ms { transform: translateX(4px); }
.ink .onward { color: var(--lime-on-ink); }


/* ══════════════════════════════════════════════════════════════════════
   ДОВІДКА

   Дві полиці й статті в них. Полиця «Інструкції» — це «зроби ось так»,
   полиця «Як це влаштовано» — «ось чому воно так». Розділені вони не за
   темами, а за тим, із яким питанням людина прийшла: одна шукає порядок
   дій, друга — пояснення. Змішані в один список, вони заважають обом.
   ══════════════════════════════════════════════════════════════════════ */

/* ── пошук ────────────────────────────────────────────────────────── */
/* Фільтр по тому, що вже на сторінці, а не запит кудись: статей два десятки,
   і показати «нічого не знайдено» швидше, ніж завантажити індекс. Поле —
   `type="search"`, тож хрестик очищення дає браузер. */
.seek { position: relative; margin-top: clamp(26px, 3.4vw, 36px); max-width: 520px; }
.seek input {
  width: 100%; padding: 15px 17px 15px 48px;
  background: var(--paper); color: var(--t1);
  border: 0; border-radius: 14px;
  box-shadow: inset 0 0 0 1px var(--hairline), var(--edge-lit);
  font: 500 15px/1.2 var(--font);
  transition: box-shadow .18s ease;
}
.seek input::placeholder { color: var(--t4); }
.seek input:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--lime-ink), 0 0 0 4px rgba(191, 232, 85, .12); }
.seek > .ms { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--t4); pointer-events: none; }
.seek input:focus + .ms { color: var(--lime-ink); }
.seek__none { margin-top: 20px; font-size: 15px; color: var(--t3); }

/* ── полиці ───────────────────────────────────────────────────────── */
.shelf { margin-top: clamp(44px, 6vw, 72px); }
.shelf > h2 { font-size: clamp(22px, 2.6vw, 28px); }
.shelf > h2 + p { margin-top: 11px; max-width: 56ch; font-size: 15px; color: var(--t3); line-height: 1.6; }
/* Лінії між рядками намальовані ВСЕРЕДИНІ комірок, а не проміжком у кольорі
   лінії. Проміжок був простіший, але полиця з пʼятьма статтями у двох колонках
   лишає одну комірку порожньою — і та порожнеча ставала суцільним прямокутником
   кольору лінії. Те саме робив пошук, щойно знаходив непарну кількість. */
.shelf__list { margin-top: 26px; display: grid; background: var(--paper); border-radius: 18px; overflow: hidden; box-shadow: 0 0 0 1px var(--hairline); }
@media (min-width: 860px) { .shelf__list { grid-template-columns: 1fr 1fr; } }

/* Рядок, а не картка. Довідка — це зміст, і зміст читають колонкою зверху
   вниз; однакові коробки з іконкою зверху перетворюють його на вітрину, у
   якій усі двадцять пунктів однаково важливі. */
.entry {
  position: relative; display: grid; grid-template-columns: 26px 1fr; gap: 5px 16px;
  background: var(--paper); padding: clamp(20px, 2.4vw, 26px); text-decoration: none;
  box-shadow: inset -1px -1px 0 var(--hairline);
  transition: background .18s ease;
}
.entry:hover,
.entry:focus-visible { background: #1a2023; }
.entry .ms { grid-row: span 2; align-self: start; margin-top: 2px; font-size: 24px; width: 24px; height: 24px; color: var(--t3); transition: color .18s ease; }
.entry:hover .ms,
.entry:focus-visible .ms { color: var(--lime-ink); }
.entry b { font-size: 16.5px; font-weight: 800; letter-spacing: -.025em; color: var(--t1); }
.entry p { font-size: 14px; line-height: 1.55; color: var(--t3); max-width: 44ch; }
/* Стрілка з'являється під курсором і нікуди не зсуває текст: вона
   абсолютна, а не в потоці. */
.entry::after {
  content: "arrow_forward"; font-family: 'Material Symbols Rounded'; font-size: 20px;
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 20;
  position: absolute; right: 22px; top: 50%; margin-top: -10px;
  color: var(--lime-ink); opacity: 0; transform: translateX(-6px);
  transition: opacity .18s ease, transform .2s cubic-bezier(.2, .9, .3, 1);
}
/* Те саме на фокусі, а не лише під курсором: рядок довідки — це посилання,
   і людина, яка ходить табуляцією, мусить бачити ту саму стрілку й той самий
   аркуш, а не тільки рамку обведення. */
.entry:hover::after,
.entry:focus-visible::after { opacity: 1; transform: none; }
@media (max-width: 620px) { .entry::after { display: none; } }

/* ── стаття ───────────────────────────────────────────────────────── */
/* Дві колонки: текст і зміст збоку. Зміст не липкий на телефоні — там він
   просто перший блок сторінки, як і має бути в довгому тексті. */
.art { display: grid; gap: clamp(30px, 4vw, 60px); align-items: start; padding-bottom: clamp(50px, 7vw, 90px); }
@media (min-width: 1000px) { .art { grid-template-columns: minmax(0, 1fr) 240px; } }

.art__head { padding: clamp(26px, 3.4vw, 40px) 0 clamp(24px, 3vw, 34px); border-bottom: 1px solid var(--hairline); }
.art__head h1 { font-size: clamp(30px, 4vw, 46px); max-width: 18ch; }
.art__head p { margin-top: 18px; max-width: 60ch; font-size: clamp(16px, 1.7vw, 18px); line-height: 1.62; color: var(--t2); }

/* Тіло статті. Міра рядка — 68ch: на довшому око губить початок наступного,
   а інструкцію читають, а не проглядають. */
.prose { max-width: 68ch; font-size: 16px; line-height: 1.68; color: var(--t2); }
.prose > * + * { margin-top: 22px; }
.prose h2 { font-size: clamp(21px, 2.3vw, 26px); margin-top: 46px; scroll-margin-top: 96px; }
.prose h2:first-child { margin-top: 34px; }
.prose h3 { font-size: 17.5px; margin-top: 34px; }
.prose strong { color: var(--t1); font-weight: 800; }
.prose a { color: var(--lime-ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: rgba(191, 232, 85, .4); }
.prose a:hover { text-decoration-color: currentColor; }
.prose code {
  font: 500 .88em/1 var(--mono); padding: .18em .42em; border-radius: 6px;
  background: rgba(255, 255, 255, .07); color: var(--t1);
}

/* Марковані пункти — не «зроби так», а «буває отак». Крапка вольтова, бо
   на темному сірий маркер просто зникає. */
/* Відступ згори свій, а не від `.prose > * + *`: правило для списку
   специфічніше, тож `margin: 0` у ньому виграло б і приліпило перший пункт
   до заголовка. */
.prose ul { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 11px; }
.prose ul li { position: relative; padding-left: 24px; }
.prose ul li::before { content: ""; position: absolute; left: 5px; top: .62em; width: 6px; height: 6px; border-radius: 50%; background: var(--lime); }

/* Нумерований порядок дій. Число — Oswald, бо це номер, а не слово; той
   самий регістр, що на стартових номерах у фотополосах. */
.prose ol { list-style: none; margin: 24px 0 0; padding: 0; counter-reset: s; display: grid; gap: 15px; }
.prose ol li { position: relative; counter-increment: s; padding-left: 46px; min-height: 30px; }
.prose ol li::before {
  content: counter(s); position: absolute; left: 0; top: -1px;
  width: 30px; height: 30px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--lime-soft); color: var(--lime-ink);
  box-shadow: inset 0 0 0 1px rgba(191, 232, 85, .22);
  font: 600 14px/1 var(--display); letter-spacing: .02em;
}

/* Застереження — те, що кусає, якщо його проґавити. Один такий блок на
   екран; два поспіль означають, що абзац між ними написаний погано. */
.note {
  display: grid; grid-template-columns: 22px 1fr; gap: 14px;
  padding: 18px 20px; border-radius: 14px;
  background: var(--lime-soft); box-shadow: inset 0 0 0 1px rgba(191, 232, 85, .2);
  font-size: 15px; line-height: 1.6; color: #d9ecab;
}
.note .ms { font-size: 21px; width: 21px; height: 21px; color: var(--lime-ink); margin-top: 1px; }
.note strong { color: #eaf7c9; }

/* ── зміст статті ─────────────────────────────────────────────────── */
.toc { font-size: 14px; }
@media (min-width: 1000px) { .toc { position: sticky; top: 96px; } }
.toc b { display: block; font: 600 11.5px/1.2 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--t4); }
.toc ol { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 3px; border-left: 1px solid var(--hairline); }
.toc a { display: block; padding: 7px 0 7px 15px; margin-left: -1px; border-left: 1px solid transparent; color: var(--t3); text-decoration: none; line-height: 1.42; transition: color .16s ease, border-color .16s ease; }
.toc a:hover { color: var(--t1); }
.toc a[aria-current="true"] { color: var(--lime-ink); border-left-color: var(--lime); }

/* ── сусідні статті ───────────────────────────────────────────────── */
/* Та сама причина, що й у полиці: у першої статті немає «попередньої», у
   останньої — «наступної», і одна з двох комірок порожня. */
.pager { display: grid; margin-top: clamp(44px, 6vw, 68px); background: var(--paper); border-radius: 18px; overflow: hidden; box-shadow: 0 0 0 1px var(--hairline); }
@media (min-width: 720px) {
  .pager { grid-template-columns: 1fr 1fr; }
  /* Перша стаття не має «попередньої». Без цього рядка «наступна» стояла б у
     лівій половині, притиснута до правого краю власної комірки, — тобто
     посеред сторінки. */
  .pager__next:only-child { grid-column: 2; }
}
.pager a { background: var(--paper); padding: 22px 24px; text-decoration: none; display: grid; gap: 7px; box-shadow: inset -1px -1px 0 var(--hairline); transition: background .18s ease; }
.pager a:hover { background: #1a2023; }
.pager span { display: inline-flex; align-items: center; gap: 6px; font: 600 11.5px/1.2 var(--display); letter-spacing: .12em; text-transform: uppercase; color: var(--t4); }
.pager .ms { font-size: 16px; width: 16px; height: 16px; }
.pager b { font-size: 16px; font-weight: 800; letter-spacing: -.025em; color: var(--t1); }
.pager__next { text-align: right; }
.pager__next span { justify-content: flex-end; }

/* ── заклик у кінці статті ────────────────────────────────────────── */
.after { margin-top: clamp(44px, 6vw, 68px); padding: clamp(26px, 3.4vw, 38px); border-radius: 20px; background: var(--ink); box-shadow: var(--card-shadow), 0 0 0 1px var(--hairline), var(--edge-lit); }
.after b { display: block; font-size: clamp(19px, 2.2vw, 24px); font-weight: 800; letter-spacing: -.03em; color: var(--on-ink); }
.after p { margin-top: 11px; max-width: 48ch; font-size: 15px; line-height: 1.6; color: var(--on-ink-2); }
.after .btn { margin-top: 22px; }

/* «Ви тут». Позначено і кольором, і крапкою: сам лише колір у панелі, де
   кожен другий рядок під курсором і так світлішає, читається як наведення. */
.nav__pop a[aria-current="page"] b,
.drawer nav a[aria-current="page"] { color: var(--lime-ink); }
.nav__pop a[aria-current="page"] .ms,
.drawer nav a[aria-current="page"] .ms { color: var(--lime-ink); }
.footer__col a[aria-current="page"] { color: var(--t1); font-weight: 700; }

/* ── дві колонки тексту ───────────────────────────────────────────── */
/* Там, де двом темам однакова вага і жодній не потрібен знімок. Не картки:
   між колонками нічого не намальовано, їх тримає сам простір. */
.duo { display: grid; gap: clamp(26px, 3.4vw, 44px); margin-top: clamp(30px, 4vw, 44px); }
@media (min-width: 820px) { .duo { grid-template-columns: 1fr 1fr; } }
.duo h3 { font-size: 18.5px; letter-spacing: -.03em; }
.duo h3 + p { margin-top: 12px; font-size: 15px; line-height: 1.62; color: var(--t3); max-width: 46ch; }
.ink .duo h3 + p { color: var(--on-ink-2); }
.duo .claims { margin-top: 18px; }
.ink .duo .claims li { color: var(--on-ink-2); }

/* Два зауваження підряд — це одне відступлення з двох абзаців, а не два
   відступлення: друга волосяна лінія розрізала б їх на дві репліки. */
.setup__note + .setup__note { margin-top: 12px; padding-top: 0; border-top: 0; }

/* Посилання всередині звичайного тексту. `.prose` має власне правило (у статті
   їх багато й вони частина читання); тут ті самі очі бачать ту саму лінію. */
.faq p a,
.setup__note a,
.doors__one a {
  color: var(--lime-ink); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 1px;
  text-decoration-color: rgba(191, 232, 85, .4);
}
.faq p a:hover,
.setup__note a:hover,
.doors__one a:hover { text-decoration-color: currentColor; }

/* ── один телефон поруч із текстом ────────────────────────────────── */
/* Той самий екран, що в смузі на головній, але на своєму місці й більший:
   там шість штук і їх гортають, тут один і на нього дивляться. */
.solo { display: flex; justify-content: center; }
/* `.showcase__shot` тягне знімок за поля до краю вікна — великому кадру це
   й потрібно. Телефон же стоїть по центру своєї половини, і той самий
   відʼємний відступ зсував би його вбік рівно на ту ж величину. */
.showcase__shot.solo,
.showcase--flip .showcase__shot.solo { margin-inline: 0; }
.solo img { width: min(272px, 74vw); border-radius: 26px; box-shadow: var(--deep), 0 0 0 1px var(--hairline); background: var(--sunken); }

/* ── три колонки провайдерів ──────────────────────────────────────── */
/* Порівняння, а не вітрина: три еквайринги відрізняються ринком і тим, що
   вміють, і читати це треба поруч, а не по черзі. */
.grid3 { margin-top: clamp(30px, 4vw, 44px); display: grid; gap: 1px; background: var(--hairline); border-radius: 20px; overflow: hidden; box-shadow: 0 0 0 1px var(--hairline); }
@media (min-width: 900px) { .grid3 { grid-template-columns: repeat(3, 1fr); } }
.grid3 > div { background: var(--paper); padding: clamp(22px, 2.8vw, 30px); }
.grid3 b { display: block; font-size: 17px; font-weight: 800; letter-spacing: -.03em; }
.grid3 > div > span {
  display: inline-block; margin-top: 10px; padding: 5px 10px; border-radius: 99px;
  background: var(--lime-soft); color: var(--lime-ink); box-shadow: inset 0 0 0 1px rgba(191, 232, 85, .2);
  font: 600 11px/1.3 var(--display); letter-spacing: .1em; text-transform: uppercase;
}
.grid3 p { margin-top: 15px; font-size: 14.5px; line-height: 1.6; color: var(--t3); }
.grid3 ul { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 9px; }
.grid3 ul li { position: relative; padding-left: 24px; font-size: 14px; line-height: 1.5; color: var(--t2); }
.grid3 ul li::before {
  content: "check"; font-family: 'Material Symbols Rounded'; font-size: 16px;
  font-variation-settings: 'FILL' 0, 'wght' 600, 'GRAD' 0, 'opsz' 20;
  position: absolute; left: 0; top: 0; color: var(--lime-ink);
}

/* ══════════════════════════════════════════════════════════════════════
   ЩО ВИ ЗАКРИВАЄТЕ

   Заголовок обіцяє «не шість вкладок», і до цього блоку сторінка тих шести
   не показувала жодної. Тут вони названі — і навпроти кожної стоїть розділ
   кабінету, який її замінює. Зліва тьмяне, справа вольтове: перехід видно
   раніше, ніж прочитано.

   Це не сітка карток, а список із двома колонками, тому `subgrid` — тільки
   він тримає вольтові плашки на одній вертикалі через усі шість рядків.
   Де його немає, працює запасний рядок вище: колонки рахуються в кожному
   рядку окремо, плашки стають нерівні — і це все, що втрачається.
   ══════════════════════════════════════════════════════════════════════ */
.swap {
  list-style: none; margin: clamp(32px, 4.2vw, 48px) 0 0; padding: 0;
  display: grid; grid-template-columns: 1fr auto 1fr;
  border-bottom: 1px solid var(--hairline);
}
.swap li {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: 1fr auto 1fr;
  grid-template-columns: subgrid;
  align-items: center; gap: 16px;
  padding: 16px 2px; border-top: 1px solid var(--hairline);
}
.swap__was { display: flex; align-items: center; gap: 13px; font-size: 15.5px; color: var(--t3); }
.swap__was .ms { font-size: 20px; width: 20px; height: 20px; color: var(--t4); flex: none; }
/* Стрілка вольтова, і це єдиний акцент у рядку: вона одна каже «стає».
   Раніше акцент носила пігулка праворуч, але в пігулку влазило тільки
   одне слово — назва розділу кабінету, тобто підпис на екрані, якого
   читач ще не бачив. Речення в пігулку не влазить, а продає саме воно. */
.swap__arrow { font-size: 18px; width: 18px; height: 18px; color: var(--lime-ink); }
.swap__now {
  font-size: 15.5px; font-weight: 700; letter-spacing: -.015em;
  color: var(--t1); line-height: 1.45;
}
/* На телефоні рядок складається навпіл: тьмяне зверху, світле знизу, а
   стрілка зникає — колонка під неї коштує вісімнадцять пікселів із
   трьохсот сімдесяти пʼяти, а те саме вже сказано кольором і місцем. */
@media (max-width: 620px) {
  .swap, .swap li { grid-template-columns: 1fr; }
  .swap__arrow { display: none; }
  .swap__was { font-size: 14.5px; }
  .swap li { gap: 7px; }
}

/* Рядок під списком — те, чого в старій роботі не було взагалі. Він і робить
   блок не «заміною», а «заміною плюс». */
.swap__more {
  display: flex; gap: 14px; margin-top: clamp(26px, 3vw, 34px);
  max-width: 68ch; font-size: 15.5px; line-height: 1.6; color: var(--t2);
}
.swap__more .ms { flex: none; margin-top: 1px; color: var(--lime-ink); }
