/* =============================================================================
   base — скидання, елементи за замовчуванням, примітиви розкладки
   Кожне значення — var() з tokens.css.
   ============================================================================= */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-body);
  letter-spacing: var(--tracking-normal);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  margin: 0;
  font-weight: var(--fw-bold);
  line-height: var(--lh-heading);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

h1 {
  font-size: var(--fs-h1);
  line-height: var(--lh-display);
  letter-spacing: var(--tracking-display);
}

h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-display);
}

h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); font-weight: var(--fw-semibold); }

p { margin: 0; max-width: var(--measure); }

ul, ol { margin: 0; padding: 0; list-style: none; }

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}

button { font: inherit; color: inherit; }

/* height: auto обов'язковий разом із max-width. Атрибути width і height на <img>
   потрібні, щоб браузер зарезервував місце й не смикнув розкладку (CLS) — але
   поки ширина стискається до колонки, а висота лишається з атрибута, картинка
   їде в неправильній пропорції. У сітці журналу обкладинка 1200×675 малювалася
   як 370×675: стиснута вдвічі по горизонталі. */
img, svg, video { display: block; max-width: 100%; height: auto; }

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: var(--radius-chip);
}

::selection {
  background: var(--accent);
  color: var(--accent-on);
}

/* ---- примітиви ------------------------------------------------------------ */

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

.grid {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  gap: var(--gutter);
}

.stack > * + * { margin-block-start: var(--space-md); }

.section {
  position: relative;
  padding-block: var(--section-pad);
}

/* Світла секція. Перевизначає семантичні токени всередині себе — компоненти
   не знають, на якому фоні стоять, і працюють в обох. */
.section--invert {
  background: var(--surface-invert);
  --surface-page: var(--surface-invert);
  --surface-raised: var(--surface-invert-raised);
  --surface-sunken: var(--surface-invert-sunken);
  --surface-hairline: var(--surface-invert-hairline);
  --text-primary: var(--text-invert-primary);
  --text-secondary: var(--text-invert-secondary);
  --text-muted: var(--text-invert-muted);
  --shadow-card: var(--shadow-invert-card);
  /* Бурштин лампи на циферблаті дає 1.57:1 — нижче за поріг 3:1. Фокусне кільце
     всередині світлої секції бере чорнильний амбер (5.2:1). */
  --focus-ring: var(--accent-ink);
  color: var(--text-invert-primary);
}

/* Амбер як ТЕКСТ і як тонка лінія на світлому — тільки --accent-ink.
   --accent лишається для заливок (кнопка, пілюля), де контраст дає --accent-on. */
/* На світлій секції лампа НЕ світиться.

   Раніше тут стояв --accent-ink, і бурштин тонував половину заголовка в
   кожній із дев'яти секцій. Показник, увімкнений завжди, перестає бути
   показником: на світлому фоні чорнильний амбер око читає не як приглушений
   бурштин, а як другий колір — болотяно-коричневий на два-три рядки по 60px.
   Це була перша названа причина «сайт виглядає важким».

   --accent-ink лишається там, де він і працює: підкреслення посилань,
   показники в картках вигід, гліфи. */
.section--invert .tint { color: inherit; }

.section--invert .eyebrow::before { background: var(--accent-ink); }

.section--sunken { background: var(--surface-raised); }

/* ---- ореол лампи на темних поверхнях (механізм M06) -------------------------
   Світло приладу падає на кожну темну секцію, не лише на першу й останню.
   Але однаковий ореол у тому самому місці чотирнадцять разів — це штамп, а не
   освітлення, тому положення задає модифікатор: зверху чи знизу, ліворуч,
   по центру чи праворуч. Дві сусідні темні секції не беруть однакову пару.

   Ореол не має власного кольору поза токеном: --glow-accent і
   --glow-accent-soft уже описують бурштинове світло, тут міняється лише те,
   де стоїть його джерело. */

.section--glow::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 40rem;
  background: var(--glow-accent);
  pointer-events: none;
  z-index: var(--z-base);
}

/* Джерело знизу: слабше, бо світло вже розсіялось. */
.section--glow-bottom::before {
  inset-block: auto 0;
  background: var(--glow-accent-soft);
}

/* Зсув джерела вбік: псевдоелемент займає половину секції, тому центр плями
   стає на чверті ширини, а не посередині. Він лишається В МЕЖАХ секції
   свідомо — виліт за край давав горизонтальну прокрутку, а глушити її
   overflow-ом не можна: у 06 живе закріплений блок. */
.section--glow-left::before { inset-inline: 0 50%; }
.section--glow-right::before { inset-inline: 50% 0; }

.section > .wrap { position: relative; z-index: var(--z-raised); }

/* ---- типографічні утиліти -------------------------------------------------- */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.eyebrow::before {
  content: "";
  inline-size: var(--space-md);
  block-size: var(--border-width-hair);
  background: var(--accent);
}

.lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-loose);
  color: var(--text-secondary);
  max-width: var(--measure);
}

/* Механізм M04 — половина заголовка акцентом */
.tint { color: var(--accent); }

.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--tracking-wide);
}

.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- гліфи ------------------------------------------------------------------
   Phosphor Icons, вага bold, MIT. Заповнені контури, а не штрих: тонкі лінійні
   іконки на світлому читалися дешево, і це було головним зауваженням до них.
   Розмір задає секція, колір успадковується від батька.

   Виняток — службова стрілка: вона намальована штрихом за нашим правилом
   (кути 0/45/90) і позначає дію, а не предмет, тому живе окремим класом. */

/* Спрайт не рендериться, він лише сховище <symbol>. Правило живе саме тут, у
   базі: спрайт стоїть на КОЖНІЙ сторінці, а стиль секції вантажиться лише на
   головній — на сторінці кейса невидимий контейнер займав 150px порожнечі під
   шапкою. */
.sprite {
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: hidden;
}

.glyph {
  fill: currentColor;
  stroke: none;
  color: var(--text-muted);
}

/* Текстове посилання зі стрілкою. Живе в base.css, бо стоїть у чотирьох
   секціях і на внутрішніх сторінках — правило теми: елемент більш ніж на
   одній сторінці описується один раз. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  /* 21px рядка — нижче за поріг WCAG 2.2 (24×24). Кегль лишається, площу
     добирає відступ; візуально посилання те саме. */
  padding-block: var(--space-3xs);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}

.arrow-link:hover,
.arrow-link:focus-visible { color: var(--accent); }

/* У світлій секції лампа на кремовому дає 1.57:1 — той самий закон, що для
   .tint у секції 04. */
.section--invert .arrow-link:hover,
.section--invert .arrow-link:focus-visible { color: var(--accent-ink); }

.arrow-link:hover .arrow-icon,
.arrow-link:focus-visible .arrow-icon { transform: translateX(var(--space-3xs)); }

.arrow-icon {
  transition: transform var(--dur-fast) var(--ease-out);
  inline-size: var(--icon-size-sm);
  block-size: var(--icon-size-sm);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: butt;
  stroke-linejoin: miter;
}

/* ---- кнопки ---------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-md);
  border: var(--border-hairline);
  border-radius: var(--radius-chip);
  /* У спокої кнопка — фізична клавіша на панелі, а не контур. Прозоре тло з
     волосяною рамкою читалося порожнім місцем, поки на нього не наведеш:
     кнопка не має існувати тільки в момент ховера. Поверхня на крок вище за
     секцію плюс кромка --edge-light усередині --shadow-card дають їй тіло. */
  background: var(--surface-raised);
  box-shadow: var(--shadow-card);
  color: var(--text-primary);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tracking-normal);
  cursor: pointer;
  transition:
    background-color var(--dur-fast) var(--ease-in),
    border-color var(--dur-fast) var(--ease-in),
    box-shadow var(--dur-fast) var(--ease-in),
    color var(--dur-fast) var(--ease-in);
}

/* Риска-поділка перед текстом контурної кнопки: у спокої довжина 0,
   на hover виїжджає від лівого краю (motion-spec §6). Кнопка-лампа
   (--primary) її не має — вона світиться сама. */
.btn::before {
  content: "";
  flex: none;
  inline-size: var(--space-sm);
  block-size: var(--border-width-hair);
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-fast) var(--ease-in);
}

.btn:hover,
.btn:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: var(--shadow-lamp-soft);
  transition:
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.btn:hover::before,
.btn:focus-visible::before {
  transform: scaleX(1);
  transition: transform var(--dur-fast) var(--ease-out);
}

/* Натиснуто: клавіша йде в панель — тінь зникає, колір гасне на крок. */
.btn:active {
  color: var(--accent-quiet);
  box-shadow: var(--shadow-none);
}

.btn:active::before { background: var(--accent-quiet); }

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
}

.btn--primary::before { content: none; }

/* Лампа яскравішає: колір + сяйво. Без підйому — прилад не підстрибує. */
.btn--primary:hover,
.btn--primary:focus-visible {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: var(--accent-on);
  box-shadow: var(--shadow-lamp);
}

/* Натиснуто — лампа наполовину. */
.btn--primary:active {
  background: var(--accent-quiet);
  border-color: var(--accent-quiet);
  color: var(--text-primary);
  box-shadow: var(--shadow-lamp-soft);
}

/* Вимкнено: лампи нема, ховера нема. Для <a class="btn"> — aria-disabled. */
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: var(--shadow-none);
}

.btn:disabled:hover,
.btn[aria-disabled="true"]:hover {
  border-color: var(--surface-hairline);
  color: var(--text-primary);
}

.btn--primary:disabled:hover,
.btn--primary[aria-disabled="true"]:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
}

.btn:disabled::before,
.btn[aria-disabled="true"]::before { transform: scaleX(0); }

/* Робота триває: поділка біжить по ширині кнопки (motion-spec §6). */
.btn[data-loading="true"] {
  position: relative;
  overflow: hidden;
  pointer-events: none;
}

.btn[data-loading="true"]::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: var(--border-width-rule);
  background: var(--accent);
  animation: btn-sweep var(--dur-settle) var(--ease-in-out) infinite;
}

.btn--primary[data-loading="true"]::after { background: var(--accent-on); }

@keyframes btn-sweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
  .btn[data-loading="true"]::after { animation: none; }

  .arrow-link,
  .arrow-icon { transition: none; }

  .arrow-link:hover .arrow-icon,
  .arrow-link:focus-visible .arrow-icon { transform: none; }
}

.btn--lg {
  padding: var(--space-sm) var(--space-lg);
  font-size: var(--fs-body);
}

/* ---- плейсхолдер зображення -------------------------------------------------
   Чорновий етап. Розміри зарезервовані через aspect-ratio, тому CLS = 0,
   коли на місце плейсхолдера стане справжній файл. */

.ph {
  position: relative;
  background: var(--surface-sunken);
  border: var(--border-hairline);
  border-radius: var(--radius-card);
  overflow: hidden;
}

.ph::after {
  content: attr(data-label);
  position: absolute;
  inset-block-end: var(--space-xs);
  inset-inline-start: var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

.ph--wide { aspect-ratio: 16 / 9; }
.ph--tall { aspect-ratio: 3 / 4; }
.ph--square { aspect-ratio: 1 / 1; }
.ph--portrait { aspect-ratio: 4 / 5; }
.ph--block { aspect-ratio: 21 / 9; border-radius: var(--radius-block); }

/* ---- поява на скролі --------------------------------------------------------
   Спільного reveal-стану більше немає: словник руху живе в data-motion
   (docs/motion-spec.md §4), а початковий стан ставить лише JS у reveal.js.
   Без JS і під reduce жоден вузол не має opacity: 0.

   Єдиний CSS-хук друку рядка: доки заголовок не надрукований, показник у ньому
   не світиться. data-lamp ставить і знімає JS, тому без JS лампа горить одразу. */

[data-motion="print"][data-lamp="off"] .tint {
  color: var(--text-primary);
}

[data-motion="print"] .tint {
  transition: color var(--dur-fast) var(--ease-in-out);
}

/* ---- зерно ------------------------------------------------------------------
   Один шар поверх сторінки. Дає матеріальність плоскій темній базі. */

.grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: var(--z-modal);
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* =============================================================================
   Спільне між секціями. Перенесено з home.css при розрізанні: ці правила
   описують примітиви (.section__head, .section--invert, поля форми), а не
   одну секцію, тож у файлі секції їм місця немає.
   ============================================================================= */

/* ---- спільні заголовки секцій ------------------------------------------------ */

/* ДИХАННЯ ПІД ЗАГОЛОВКОМ. Проміжок «заголовок → лід» задається тут ОДИН раз на
   всі секції, а не в кожному файлі окремо. Причина: шапка #problems була
   звичайним блоком, а `p` у базі має `margin: 0` — на 390 між низом h2 і верхом
   ліда стояло рівно 0px (виміряно: обидва краї на 208). Текст не ламався, але
   око не бачило, де закінчилась думка й почалось пояснення, і саме це читається
   як стіна, навіть коли тексту мало.

   Механізм один — проміжок сітки. Тому `display` і `gap` ЗНЯТО з
   .problems__head, .process__head, .faq__head, .about__text і .cta__text: вони
   описували те саме значення вп'ятеро, а одна з п'яти шапок його взагалі не
   мала. Міняти проміжок тепер треба в одному місці.

   На ≥64rem split-шапки ставлять лід у сусідню колонку — там правило не діє,
   бо в потоці між заголовком і лідом проміжку немає взагалі. */
.section__head,
.problems__head,
.process__head,
.faq__head,
.about__text,
.cta__text {
  display: grid;
  gap: var(--space-md);
  align-content: start;
}

.section__head {
  margin-block-end: var(--space-2xl);
  max-width: var(--measure);
}

.section__head--split { max-width: none; }

@media (min-width: 64rem) {
  .section__head--split {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-2xl);
    align-items: end;
  }
}

/* ---- щільність на телефоні ----------------------------------------------------
   Вертикальний ритм сторінки був успадкований від десктопа цілком: на 390×844
   секція мала ті самі 64px полів і ті самі 80px під шапкою, що на 1440×900, —
   а екран тут у два з половиною рази нижчий. Поле, яке на десктопі займає 7%
   висоти вікна, на телефоні займає 15%, і сторінка з тим самим вмістом стає
   довшою в екранах, ніж вона є насправді.

   Тому на телефоні секція бере --section-pad-tight (той самий токен, яким уже
   живе смуга метрик), а шапка — --space-xl. Ні кегль, ні міжрядковий інтервал,
   ні вміст не міняються: правка стосується виключно порожнього місця.

   Межа 48rem, а не 64rem: між 48 і 64rem розкладка вже одноколонкова, але вікно
   там високе, і десктопний ритм у ньому не заважає.

   ФОРМА ЗАПИТУ, 2026-09-14. Було `max-width: 47.999rem` проти `min-width: 48rem`
   — і між 767.984px і 768px не діяло жодне з двох правил. Смуга вузька, але не
   теоретична: на Windows зі 125% масштабом ширина вікна дробова, і потрапити в
   неї можна. `not all and (min-width: N)` — точне доповнення до `min-width: N`:
   щілини немає за побудовою, а межа лишається тим самим числом, що й у пари.
   Так записані всі три пари: 30rem, 48rem, 64rem. */
@media not all and (min-width: 48rem) {
  .section { padding-block: var(--section-pad-tight); }

  .section__head { margin-block-end: var(--space-xl); }
}

/* ---- амбер на циферблаті ------------------------------------------------------
   Світлі секції (03 problems, 05 why, 08 outcomes, 10 words, 12 faq): --accent
   на --surface-invert дає 1.57:1. Усе, що є текстом або значущою лінією,
   переходить на --accent-ink (5.2:1). Заливок акцентом у цих секціях немає. */

.section--invert .problem__num,
.section--invert .why__num,
.section--invert .outcome__num,
.section--invert .faq__sign,

.section--invert .faq__q:hover { color: var(--accent-ink); }

.section--invert .why__item { border-block-start-color: var(--accent-ink); }

.section--invert .outcome:hover,
.section--invert .step:hover,
.section--invert .case:hover { border-color: var(--accent-ink); }

/* ---- поле форми ----------------------------------------------------------------
   Поле — це вікно зчитування, у яке пише користувач: та сама заглиблена
   поверхня, та сама тонка рамка, той самий радіус, що в показників. Підпис
   стоїть НАД полем моноширинним дрібним — як ярлик каналу на панелі. */

.field {
  display: grid;
  gap: var(--space-3xs);
}

.field__label {
  font-family: var(--font-readout);
  font-size: var(--fs-micro);
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

.field input,
.field textarea {
  inline-size: 100%;
  padding: var(--space-xs) var(--space-sm);
  background: var(--surface-sunken);
  /* Рамка полів навмисно світліша за всі інші межі на сайті. Волосяна давала
     на зануреній поверхні 1.4:1, посилена — 2.46:1, а WCAG 1.4.11 вимагає 3:1
     саме для меж елементів керування: поле, якого не видно, — це людина, яка
     не зрозуміла, куди писати. Тут це останній крок перед «надіслати», тому
     ціна невидимості не естетична, а втрачена заявка.

     Єдиний наявний токен, що проходить поріг, — `--text-muted` (5.19:1).
     Так, це колір тексту в ролі рамки; заводити окремий токен заради одного
     місця гірше, ніж використати наявний і пояснити чому. */
  border: 1px solid var(--text-muted);
  border-radius: var(--radius-readout);
  color: var(--text-primary);
  font: inherit;
  /* Не менше 16px: Safari на iOS сам збільшує сторінку, коли фокус потрапляє
     в поле з меншим кеглем, і сторінка стрибає посеред заповнення форми. */
  font-size: var(--fs-body);
  transition:
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.field input::placeholder,
.field textarea::placeholder { color: var(--text-muted); }

.field textarea {
  min-block-size: 8rem;
  resize: vertical;
}

.field input:focus,
.field textarea:focus {
  border-color: var(--accent);
  outline: none;
}

/* ---- стани поля форми ---------------------------------------------------------
   Помилка на приладі теж бурштинова — другого кольору для помилок немає
   (motion-spec §6). Стан природний: :user-invalid ставить браузер після
   спроби відправки, тому повідомлення лишається нативним. */

.field input:disabled,
.field textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.field input:user-invalid,
.field textarea:user-invalid {
  border-color: var(--accent);
  box-shadow: var(--shadow-lamp-soft);
}

.field input:focus,
.field textarea:focus { box-shadow: var(--shadow-lamp-soft); }
